Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Common/CodeLocationTools.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -185,4 +185,5 @@
     macro(FunctionType, Type) \
     macro(StructInstType, Type) \
+    macro(AdtInstType, Type) \
     macro(UnionInstType, Type) \
     macro(EnumInstType, Type) \
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Common/PassVisitor.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -226,4 +226,6 @@
 	virtual void visit( StructInstType * aggregateUseType ) override final;
 	virtual void visit( const StructInstType * aggregateUseType ) override final;
+	virtual void visit( AdtInstType * aggregateUseType ) override final;
+	virtual void visit( const AdtInstType * aggregateUseType ) override final;
 	virtual void visit( UnionInstType * aggregateUseType ) override final;
 	virtual void visit( const UnionInstType * aggregateUseType ) override final;
@@ -351,4 +353,5 @@
 	virtual Type * mutate( FunctionType * functionType ) override final;
 	virtual Type * mutate( StructInstType * aggregateUseType ) override final;
+	virtual Type * mutate( AdtInstType * aggregateUseType ) override final;
 	virtual Type * mutate( UnionInstType * aggregateUseType ) override final;
 	virtual Type * mutate( EnumInstType * aggregateUseType ) override final;
@@ -442,4 +445,5 @@
 	void indexerAddStructFwd( const StructDecl          * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
 	void indexerAddEnum     ( const EnumDecl            * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
+	void indexerAddAdt		( const std::string			& id    ) { indexer_impl_addAdt      ( pass, 0, id   ); }
 	void indexerAddAdt		( const AdtDecl				* node  ) { indexer_impl_addAdt		 ( pass, 0, node ); }
 	void indexerAddAdtFwd	( const AdtDecl				* node  ) { indexer_impl_addAdtFwd   ( pass, 0, node  ); }
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Common/PassVisitor.impl.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -688,4 +688,61 @@
 
 //--------------------------------------------------------------------------
+// AdtDecl
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( AdtDecl * node ) {
+	VISIT_START( node );
+
+	indexerAddAdtFwd( node );
+
+	maybeAccept_impl( node->data_union, *this );
+	maybeAccept_impl( node->tag, *this );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
+	maybeAccept_impl( node->attributes, *this );
+
+	indexerAddAdt( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AdtDecl * node ) {
+	VISIT_START( node );
+
+	indexerAddAdtFwd( node );
+
+	maybeAccept_impl( node->data_union, *this );
+	maybeAccept_impl( node->tag, *this );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
+	maybeAccept_impl( node->attributes, *this );
+
+	indexerAddAdt( node );
+
+	VISIT_END( node );
+}  
+
+template< typename pass_type >
+Declaration * PassVisitor< pass_type >::mutate( AdtDecl * node ) {
+	MUTATE_START( node );
+	
+	indexerAddAdtFwd( node );
+
+	maybeMutate_impl( node->data_union, *this );
+	maybeMutate_impl( node->tag, *this );
+
+	maybeMutate_impl( node->parameters, *this );
+	maybeMutate_impl( node->members   , *this );
+	maybeMutate_impl( node->attributes, *this );
+
+	indexerAddAdt( node );
+
+	MUTATE_END( Declaration, node );
+}
+
+
+//--------------------------------------------------------------------------
 // UnionDecl
 template< typename pass_type >
@@ -789,56 +846,4 @@
 }
 
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( AdtDecl * node ) {
-	VISIT_START( node );
-
-	indexerAddAdtFwd( node );
-
-	// unlike structs, traits, and unions, enums inject their members into the global scope
-	maybeAccept_impl( node->data_constructors, *this );
-	maybeAccept_impl( node->data_union, *this );
-	maybeAccept_impl( node->tag, *this );
-
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
-	maybeAccept_impl( node->attributes, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const AdtDecl * node ) {
-	VISIT_START( node );
-
-	indexerAddAdtFwd( node );
-
-	maybeAccept_impl( node->data_constructors, *this );
-	maybeAccept_impl( node->data_union, *this );
-	maybeAccept_impl( node->tag, *this );
-
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
-	maybeAccept_impl( node->attributes, *this );
-
-
-	VISIT_END( node );
-}  
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( AdtDecl * node ) {
-	MUTATE_START( node );
-	
-	indexerAddAdtFwd( node );
-
-	maybeMutate_impl( node->data_constructors, *this );
-	maybeMutate_impl( node->data_union, *this );
-	maybeMutate_impl( node->tag, *this );
-
-	maybeMutate_impl( node->parameters, *this );
-	maybeMutate_impl( node->members   , *this );
-	maybeMutate_impl( node->attributes, *this );
-
-	MUTATE_END( Declaration, node );
-}
 
 //--------------------------------------------------------------------------
@@ -3540,4 +3545,51 @@
 
 	indexerAddStruct( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeMutate_impl( node->forall    , *this );
+		maybeMutate_impl( node->parameters, *this );
+	}
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// AdtInstType
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( AdtInstType * node ) {
+	VISIT_START( node );
+
+	indexerAddAdt( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AdtInstType * node ) {
+	VISIT_START( node );
+
+	indexerAddAdt( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( AdtInstType * node ) {
+	MUTATE_START( node );
+
+	indexerAddAdt( node->name );
 
 	{
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Common/PassVisitor.proto.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -256,9 +256,4 @@
 	cloneAll( decl->parameters, fwd->parameters );
 
-	// Experimental
-	for ( const StructDecl * ctor : fwd->data_constructors ) {
-		indexer_impl_addStructFwd( pass, 0, ctor );
-	}
-
 	pass.indexer.addAdt( fwd );
 } 
@@ -288,4 +283,17 @@
 
 template<typename pass_type>
+static inline auto indexer_impl_addAdt( pass_type & pass, int, const std::string & str ) -> decltype( pass.indexer.addAdt( str ), void() ) {
+	assert( false );
+	if ( ! pass.indexer.lookupAdt( str )) {
+		pass.indexer.addAdt( str );
+	}
+}
+
+template<typename pass_type>
+static inline auto indexer_impl_addAdt( pass_type &, long, const std::string & ) {
+	assert( false );
+}
+
+template<typename pass_type>
 static inline auto indexer_impl_addUnion( pass_type & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) {
 	if ( ! pass.indexer.lookupUnion( str ) ) {
