Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision aa685dbf8755811d4d60571851044f95501a572b)
+++ src/Common/PassVisitor.impl.h	(revision 8024bc8cf76c8f650df1a6445c978552ea39985e)
@@ -293,4 +293,22 @@
 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
+// A NOTE ON THE ORDER OF TRAVERSAL
+//
+// Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
+// no such thing as a recursive type or typedef.
+//
+//             typedef struct { T *x; } T; // never allowed
+//
+// for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
+// members are traversed, and then the complete type should be added (assuming the type is completed by this particular
+// declaration).
+//
+//             struct T { struct T *x; }; // allowed
+//
+// It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
+// traversal may modify the definition of the type and these modifications should be visible when the symbol table is
+// queried later in this pass.
+//
+// TODO: figure out whether recursive contexts are sensible/possible/reasonable.
 
 //--------------------------------------------------------------------------
@@ -450,5 +468,5 @@
 	indexerAddEnum( node );
 
-	// unlike structs, contexts, and unions, enums inject their members into the global scope
+	// unlike structs, traits, and unions, enums inject their members into the global scope
 	maybeAccept( node->parameters, *this );
 	maybeAccept( node->members   , *this );
@@ -514,4 +532,7 @@
 	}
 
+	// 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 );
 
@@ -533,4 +554,7 @@
 	}
 
+	// 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 );
 
@@ -659,9 +683,12 @@
 void PassVisitor< pass_type >::visit( IfStmt * node ) {
 	VISIT_START( node );
-
-	visitExpression( node->condition );
-	node->thenPart = visitStatement( node->thenPart );
-	node->elsePart = visitStatement( node->elsePart );
-
+	{
+		// if statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		acceptAll( node->get_initialization(), *this );
+		visitExpression( node->condition );
+		node->thenPart = visitStatement( node->thenPart );
+		node->elsePart = visitStatement( node->elsePart );
+	}
 	VISIT_END( node );
 }
@@ -671,5 +698,7 @@
 	MUTATE_START( node );
 	{
-		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		// if statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeMutateRef( node->get_initialization(), *this );
 		node->condition = mutateExpression( node->condition );
 		node->thenPart  = mutateStatement ( node->thenPart  );
@@ -707,4 +736,5 @@
 	VISIT_START( node );
 	{
+		// for statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
 		maybeAccept( node->initialization, *this );
@@ -720,4 +750,5 @@
 	MUTATE_START( node );
 	{
+		// for statements introduce a level of scope (for the initialization)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
 		maybeMutateRef( node->initialization, *this );
@@ -848,4 +879,5 @@
 	VISIT_START( node );
 	{
+		// catch statements introduce a level of scope (for the caught exception)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
 		maybeAccept( node->decl, *this );
@@ -860,4 +892,5 @@
 	MUTATE_START( node );
 	{
+		// catch statements introduce a level of scope (for the caught exception)
 		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
 		maybeMutateRef( node->decl, *this );
