Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 6f096d2341e25591a9d9435e4a28725954748a7a)
+++ src/Common/PassVisitor.h	(revision e3d7f9ff33f317b575231654cab3ce4e670f0a3d)
@@ -410,22 +410,25 @@
 	void indexerScopeEnter  ()                                    { indexer_impl_enterScope  ( pass, 0       ); }
 	void indexerScopeLeave  ()                                    { indexer_impl_leaveScope  ( pass, 0       ); }
-	void indexerAddId       ( DeclarationWithType       * node  ) { indexer_impl_addId       ( pass, 0, node ); }
-	void indexerAddType     ( NamedTypeDecl             * node  ) { indexer_impl_addType     ( pass, 0, node ); }
+	void indexerAddId       ( const DeclarationWithType * node  ) { indexer_impl_addId       ( pass, 0, node ); }
+	void indexerAddType     ( const NamedTypeDecl       * node  ) { indexer_impl_addType     ( pass, 0, node ); }
 	void indexerAddStruct   ( const std::string         & id    ) { indexer_impl_addStruct   ( pass, 0, id   ); }
-	void indexerAddStruct   ( StructDecl                * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
-	void indexerAddStructFwd( StructDecl                * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
-	void indexerAddEnum     ( EnumDecl                  * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
+	void indexerAddStruct   ( const StructDecl          * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
+	void indexerAddStructFwd( const StructDecl          * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
+	void indexerAddEnum     ( const EnumDecl            * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
 	void indexerAddUnion    ( const std::string         & id    ) { indexer_impl_addUnion    ( pass, 0, id   ); }
-	void indexerAddUnion    ( UnionDecl                 * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
-	void indexerAddUnionFwd ( UnionDecl                 * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
-	void indexerAddTrait    ( TraitDecl                 * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
-	void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
+	void indexerAddUnion    ( const UnionDecl           * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
+	void indexerAddUnionFwd ( const UnionDecl           * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
+	void indexerAddTrait    ( const TraitDecl           * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
+	void indexerAddWith     ( const std::list< Expression * > & exprs, const BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
 
 
 	template< typename TreeType, typename VisitorType >
-	friend inline void indexerScopedAccept( TreeType * tree, VisitorType &visitor );
+	friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );
 
 	template< typename TreeType, typename VisitorType >
-	friend inline void indexerScopedMutate( TreeType *& tree, VisitorType &visitor );
+	friend inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor );
+
+	template< typename TreeType, typename VisitorType >
+	friend inline void indexerScopedMutate( TreeType *& tree, VisitorType & visitor );
 };
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 6f096d2341e25591a9d9435e4a28725954748a7a)
+++ src/Common/PassVisitor.impl.h	(revision e3d7f9ff33f317b575231654cab3ce4e670f0a3d)
@@ -548,19 +548,30 @@
 	VISIT_START( node );
 
+	indexerAddId( node );
+
 	maybeAccept_impl( node->withExprs, *this );
 	{
-		// implicit add __func__ identifier as specified in the C manual 6.4.2.2
-		static ObjectDecl func(
-			"__func__", noStorageClasses, LinkageSpec::C, nullptr,
-			new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
-			nullptr
-		);
-		maybeAccept_impl( node->type, *this );
-		// function body needs to have the same scope as parameters - CompoundStmt will not enter
-		// a new scope if inFunction is true
-		ValueGuard< bool > oldInFunction( inFunction );
-		inFunction = true;
-		maybeAccept_impl( node->statements, *this );
-		maybeAccept_impl( node->attributes, *this );
+		// with clause introduces a level of scope (for the with expression members).
+		// with clause exprs are added to the indexer before parameters so that parameters
+		// shadow with exprs and not the other way around.
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		indexerAddWith( node->withExprs, node );
+		{
+			auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+			// implicit add __func__ identifier as specified in the C manual 6.4.2.2
+			static ObjectDecl func(
+				"__func__", noStorageClasses, LinkageSpec::C, nullptr,
+				new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
+				nullptr
+			);
+			indexerAddId( &func );
+			maybeAccept_impl( node->type, *this );
+			// function body needs to have the same scope as parameters - CompoundStmt will not enter
+			// a new scope if inFunction is true
+			ValueGuard< bool > oldInFunction( inFunction );
+			inFunction = true;
+			maybeAccept_impl( node->statements, *this );
+			maybeAccept_impl( node->attributes, *this );
+		}
 	}
 
@@ -628,14 +639,4 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
-	MUTATE_START( node );
-
 	// make up a forward declaration and add it before processing the members
 	// needs to be on the heap because addStruct saves the pointer
@@ -644,4 +645,24 @@
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
+	}
+
+	// this addition replaces the forward declaration
+	indexerAddStruct( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
+	MUTATE_START( node );
+
+	// make up a forward declaration and add it before processing the members
+	// needs to be on the heap because addStruct saves the pointer
+	indexerAddStructFwd( node );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
 		maybeMutate_impl( node->parameters, *this );
 		maybeMutate_impl( node->members   , *this );
@@ -677,6 +698,14 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
+	// make up a forward declaration and add it before processing the members
+	indexerAddUnionFwd( node );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
+	}
+
+	indexerAddUnion( node );
 
 	VISIT_END( node );
@@ -720,4 +749,6 @@
 	VISIT_START( node );
 
+	indexerAddEnum( node );
+
 	// unlike structs, traits, and unions, enums inject their members into the global scope
 	maybeAccept_impl( node->parameters, *this );
@@ -761,6 +792,11 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->members   , *this );
+	}
+
+	indexerAddTrait( node );
 
 	VISIT_END( node );
@@ -811,19 +847,8 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->base      , *this );
-	maybeAccept_impl( node->assertions, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
-	MUTATE_START( node );
-
 	{
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
-		maybeMutate_impl( node->parameters, *this );
-		maybeMutate_impl( node->base      , *this );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->base      , *this );
 	}
 
@@ -833,4 +858,26 @@
 	indexerAddType( node );
 
+	maybeAccept_impl( node->assertions, *this );
+
+	indexerScopedAccept( node->init, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
+	MUTATE_START( node );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeMutate_impl( node->parameters, *this );
+		maybeMutate_impl( node->base      , *this );
+	}
+
+	// see A NOTE ON THE ORDER OF TRAVERSAL, above
+	// note that assertions come after the type is added to the symtab, since they are not part of the type proper
+	// and may depend on the type itself
+	indexerAddType( node );
+
 	maybeMutate_impl( node->assertions, *this );
 
@@ -863,6 +910,12 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->base      , *this );
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->parameters, *this );
+		maybeAccept_impl( node->base      , *this );
+	}
+
+	indexerAddType( node );
+
 	maybeAccept_impl( node->assertions, *this );
 
@@ -1101,10 +1154,12 @@
 void PassVisitor< pass_type >::visit( const IfStmt * node ) {
 	VISIT_START( node );
-
-	maybeAccept_impl( node->initialization, *this );
-	visitExpression ( node->condition );
-	visitStatement( node->thenPart );
-	visitStatement( node->elsePart );
-
+	{
+		// if statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->initialization, *this );
+		visitExpression ( node->condition );
+		visitStatement  ( node->thenPart );
+		visitStatement  ( node->elsePart );
+	}
 	VISIT_END( node );
 }
@@ -1145,7 +1200,11 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->initialization, *this );
-	visitExpression ( node->condition );
-	visitStatement( node->body );
+	{
+		// while statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->initialization, *this );
+		visitExpression ( node->condition );
+		visitStatement  ( node->body );
+	}
 
 	VISIT_END( node );
@@ -1187,10 +1246,12 @@
 void PassVisitor< pass_type >::visit( const ForStmt * node ) {
 	VISIT_START( node );
-
-	maybeAccept_impl( node->initialization, *this );
-	visitExpression( node->condition );
-	visitExpression( node->increment );
-	visitStatement( node->body );
-
+	{
+		// for statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->initialization, *this );
+		visitExpression( node->condition );
+		visitExpression( node->increment );
+		visitStatement ( node->body );
+	}
 	VISIT_END( node );
 }
@@ -1408,9 +1469,11 @@
 void PassVisitor< pass_type >::visit( const CatchStmt * node ) {
 	VISIT_START( node );
-
-	maybeAccept_impl( node->decl, *this );
-	visitExpression( node->cond );
-	visitStatement ( node->body );
-
+	{
+		// catch statements introduce a level of scope (for the caught exception)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->decl, *this );
+		visitExpression ( node->cond );
+		visitStatement  ( node->body );
+	}
 	VISIT_END( node );
 }
@@ -1543,8 +1606,11 @@
 void PassVisitor< pass_type >::visit( const WithStmt * node ) {
 	VISIT_START( node );
-
 	maybeAccept_impl( node->exprs, *this );
-	maybeAccept_impl( node->stmt, *this );
-
+	{
+		// catch statements introduce a level of scope (for the caught exception)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		indexerAddWith( node->exprs, node );
+		maybeAccept_impl( node->stmt, *this );
+	}
 	VISIT_END( node );
 }
@@ -1648,6 +1714,6 @@
 
 	indexerScopedAccept( node->result  , *this );
-	maybeAccept_impl        ( node->function, *this );
-	maybeAccept_impl        ( node->args    , *this );
+	maybeAccept_impl   ( node->function, *this );
+	maybeAccept_impl   ( node->args    , *this );
 
 	VISIT_END( node );
@@ -1658,7 +1724,7 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result  , *this );
-	maybeAccept_impl( node->function, *this );
-	maybeAccept_impl( node->args    , *this );
+	indexerScopedAccept( node->result  , *this );
+	maybeAccept_impl   ( node->function, *this );
+	maybeAccept_impl   ( node->args    , *this );
 
 	VISIT_END( node );
@@ -1697,5 +1763,5 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
+	indexerScopedAccept( node->result, *this );
 
 	for ( auto expr : node->args ) {
@@ -1735,5 +1801,5 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
+	indexerScopedAccept( node->result, *this );
 
 	VISIT_END( node );
@@ -1757,5 +1823,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl        ( node->arg   , *this );
+	maybeAccept_impl   ( node->arg   , *this );
 
 	VISIT_END( node );
@@ -1766,6 +1832,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->arg   , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg   , *this );
 
 	VISIT_END( node );
@@ -1799,6 +1865,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->arg   , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg   , *this );
 
 	VISIT_END( node );
@@ -1823,5 +1889,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->arg, *this );
+	maybeAccept_impl   ( node->arg, *this );
 
 	VISIT_END( node );
@@ -1832,6 +1898,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->arg, *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg, *this );
 
 	VISIT_END( node );
@@ -1865,6 +1931,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->arg   , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg   , *this );
 
 	VISIT_END( node );
@@ -1897,5 +1963,5 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
+	indexerScopedAccept( node->result, *this );
 
 	VISIT_END( node );
@@ -1929,7 +1995,7 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result   , *this );
-	maybeAccept_impl( node->aggregate, *this );
-	maybeAccept_impl( node->member   , *this );
+	indexerScopedAccept( node->result   , *this );
+	maybeAccept_impl   ( node->aggregate, *this );
+	maybeAccept_impl   ( node->member   , *this );
 
 	VISIT_END( node );
@@ -1964,6 +2030,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result   , *this );
-	maybeAccept_impl( node->aggregate, *this );
+	indexerScopedAccept( node->result   , *this );
+	maybeAccept_impl   ( node->aggregate, *this );
 
 	VISIT_END( node );
@@ -1996,5 +2062,5 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
+	indexerScopedAccept( node->result, *this );
 
 	VISIT_END( node );
@@ -2027,6 +2093,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result   , *this );
-	maybeAccept_impl( &node->constant, *this );
+	indexerScopedAccept( node->result   , *this );
+	maybeAccept_impl   ( &node->constant, *this );
 
 	VISIT_END( node );
@@ -2066,5 +2132,5 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
+	indexerScopedAccept( node->result, *this );
 	if ( node->get_isType() ) {
 		maybeAccept_impl( node->type, *this );
@@ -2111,5 +2177,5 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
+	indexerScopedAccept( node->result, *this );
 	if ( node->get_isType() ) {
 		maybeAccept_impl( node->type, *this );
@@ -2152,6 +2218,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->type  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->type  , *this );
 
 	VISIT_END( node );
@@ -2185,6 +2251,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->type  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->type  , *this );
 
 	VISIT_END( node );
@@ -2218,6 +2284,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->type  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->type  , *this );
 
 	VISIT_END( node );
@@ -2255,5 +2321,5 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
+	indexerScopedAccept( node->result, *this );
 	if ( node->get_isType() ) {
 		maybeAccept_impl( node->type, *this );
@@ -2297,7 +2363,7 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->arg1  , *this );
-	maybeAccept_impl( node->arg2  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg1  , *this );
+	maybeAccept_impl   ( node->arg2  , *this );
 
 	VISIT_END( node );
@@ -2334,8 +2400,8 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->arg1  , *this );
-	maybeAccept_impl( node->arg2  , *this );
-	maybeAccept_impl( node->arg3  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg1  , *this );
+	maybeAccept_impl   ( node->arg2  , *this );
+	maybeAccept_impl   ( node->arg3  , *this );
 
 	VISIT_END( node );
@@ -2372,7 +2438,7 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->arg1  , *this );
-	maybeAccept_impl( node->arg2  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->arg1  , *this );
+	maybeAccept_impl   ( node->arg2  , *this );
 
 	VISIT_END( node );
@@ -2407,6 +2473,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->type, *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->type, *this );
 
 	VISIT_END( node );
@@ -2442,8 +2508,8 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result    , *this );
-	maybeAccept_impl( node->inout     , *this );
-	maybeAccept_impl( node->constraint, *this );
-	maybeAccept_impl( node->operand   , *this );
+	indexerScopedAccept( node->result    , *this );
+	maybeAccept_impl   ( node->inout     , *this );
+	maybeAccept_impl   ( node->constraint, *this );
+	maybeAccept_impl   ( node->operand   , *this );
 
 	VISIT_END( node );
@@ -2479,6 +2545,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result    , *this );
-	maybeAccept_impl( node->callExpr  , *this );
+	indexerScopedAccept( node->result    , *this );
+	maybeAccept_impl   ( node->callExpr  , *this );
 
 	VISIT_END( node );
@@ -2512,6 +2578,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result  , *this );
-	maybeAccept_impl( node->callExpr, *this );
+	indexerScopedAccept( node->result  , *this );
+	maybeAccept_impl   ( node->callExpr, *this );
 
 	VISIT_END( node );
@@ -2545,6 +2611,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result     , *this );
-	maybeAccept_impl( node->initializer, *this );
+	indexerScopedAccept( node->result     , *this );
+	maybeAccept_impl   ( node->initializer, *this );
 
 	VISIT_END( node );
@@ -2579,7 +2645,7 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->low   , *this );
-	maybeAccept_impl( node->high  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->low   , *this );
+	maybeAccept_impl   ( node->high  , *this );
 
 	VISIT_END( node );
@@ -2614,6 +2680,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->exprs , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->exprs , *this );
 
 	VISIT_END( node );
@@ -2647,6 +2713,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->exprs , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->exprs , *this );
 
 	VISIT_END( node );
@@ -2680,6 +2746,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->tuple , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->tuple , *this );
 
 	VISIT_END( node );
@@ -2713,5 +2779,5 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result  , *this );
+	indexerScopedAccept( node->result  , *this );
 	maybeAccept_impl( node->stmtExpr, *this );
 
@@ -2753,16 +2819,4 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result     , *this );
-	maybeAccept_impl( node->statements , *this );
-	maybeAccept_impl( node->returnDecls, *this );
-	maybeAccept_impl( node->dtors      , *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
-	MUTATE_START( node );
-
 	// don't want statements from outer CompoundStmts to be added to this StmtExpr
 	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
@@ -2770,4 +2824,21 @@
 	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
 
+	indexerScopedAccept( node->result     , *this );
+	maybeAccept_impl   ( node->statements , *this );
+	maybeAccept_impl   ( node->returnDecls, *this );
+	maybeAccept_impl   ( node->dtors      , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
+	MUTATE_START( node );
+
+	// don't want statements from outer CompoundStmts to be added to this StmtExpr
+	ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
+	ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
+	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
+
 	indexerScopedMutate( node->result     , *this );
 	maybeMutate_impl   ( node->statements , *this );
@@ -2794,6 +2865,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->expr  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr  , *this );
 
 	VISIT_END( node );
@@ -2828,6 +2899,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->expr  , *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr  , *this );
 	// not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
 
@@ -2864,7 +2935,7 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->expr  , *this );
-	maybeAccept_impl( node->designation, *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr  , *this );
+	maybeAccept_impl   ( node->designation, *this );
 
 	VISIT_END( node );
@@ -2890,5 +2961,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->expr, *this );
+	maybeAccept_impl   ( node->expr, *this );
 	// don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
 
@@ -2900,6 +2971,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->expr, *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr, *this );
 	// don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
 
@@ -2925,5 +2996,5 @@
 
 	indexerScopedAccept( node->result, *this );
-	maybeAccept_impl( node->expr, *this );
+	maybeAccept_impl   ( node->expr, *this );
 
 	VISIT_END( node );
@@ -2934,6 +3005,6 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
-	maybeAccept_impl( node->expr, *this );
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl   ( node->expr, *this );
 
 	VISIT_END( node );
@@ -2971,8 +3042,8 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->result, *this );
+	indexerScopedAccept( node->result, *this );
 	maybeAccept_impl( node->control, *this );
 	for ( const GenericExpr::Association & assoc : node->associations ) {
-		maybeAccept_impl( assoc.type, *this );
+		indexerScopedAccept( assoc.type, *this );
 		maybeAccept_impl( assoc.expr, *this );
 	}
@@ -3247,6 +3318,11 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->forall    , *this );
-	maybeAccept_impl( node->parameters, *this );
+	indexerAddStruct( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
+	}
 
 	VISIT_END( node );
@@ -3289,6 +3365,11 @@
 	VISIT_START( node );
 
-	maybeAccept_impl( node->forall    , *this );
-	maybeAccept_impl( node->parameters, *this );
+	indexerAddStruct( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
+	}
 
 	VISIT_END( node );
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision 6f096d2341e25591a9d9435e4a28725954748a7a)
+++ src/Common/PassVisitor.proto.h	(revision e3d7f9ff33f317b575231654cab3ce4e670f0a3d)
@@ -229,11 +229,11 @@
 
 
-INDEXER_FUNC1( addId     , DeclarationWithType *       );
-INDEXER_FUNC1( addType   , NamedTypeDecl *             );
-INDEXER_FUNC1( addStruct , StructDecl *                );
-INDEXER_FUNC1( addEnum   , EnumDecl *                  );
-INDEXER_FUNC1( addUnion  , UnionDecl *                 );
-INDEXER_FUNC1( addTrait  , TraitDecl *                 );
-INDEXER_FUNC2( addWith   , std::list< Expression * > &, BaseSyntaxNode * );
+INDEXER_FUNC1( addId     , const DeclarationWithType *       );
+INDEXER_FUNC1( addType   , const NamedTypeDecl *             );
+INDEXER_FUNC1( addStruct , const StructDecl *                );
+INDEXER_FUNC1( addEnum   , const EnumDecl *                  );
+INDEXER_FUNC1( addUnion  , const UnionDecl *                 );
+INDEXER_FUNC1( addTrait  , const TraitDecl *                 );
+INDEXER_FUNC2( addWith   , const std::list< Expression * > &, const BaseSyntaxNode * );
 
 #undef INDEXER_FUNC1
@@ -241,5 +241,5 @@
 
 template<typename pass_type>
-static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
+static inline auto indexer_impl_addStructFwd( pass_type & pass, int, const StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
 	StructDecl * fwd = new StructDecl( decl->name );
 	cloneAll( decl->parameters, fwd->parameters );
@@ -251,5 +251,5 @@
 
 template<typename pass_type>
-static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
+static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
 	UnionDecl * fwd = new UnionDecl( decl->name );
 	cloneAll( decl->parameters, fwd->parameters );
