Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision 847ab8f8121e19ac3b7f0aa27361926c67b12c62)
+++ src/AST/Util.cpp	(revision dbf5e1890699a4755af129c8750ab720f60fcc8c)
@@ -102,4 +102,15 @@
 }
 
+/// Check for Floating Nodes:
+/// Every node should be reachable from a root (the TranslationUnit) via a
+/// chain of structural references (tracked with ptr). This cannot check all
+/// of that, it just checks if a given node's field has a strong reference.
+template<typename node_t, typename field_t>
+void noFloatingNode( const node_t * node, field_t node_t::*field_ptr ) {
+	const field_t & field = node->*field_ptr;
+	if ( nullptr == field ) return;
+	assertf( field->isManaged(), "Floating node found." );
+}
+
 struct InvariantCore {
 	// To save on the number of visits: this is a kind of composed core.
@@ -127,7 +138,32 @@
 	}
 
+	void previsit( const VariableExpr * node ) {
+		previsit( (const ParseNode *)node );
+		noFloatingNode( node, &VariableExpr::var );
+	}
+
 	void previsit( const MemberExpr * node ) {
 		previsit( (const ParseNode *)node );
 		memberMatchesAggregate( node );
+	}
+
+	void previsit( const StructInstType * node ) {
+		previsit( (const Node *)node );
+		noFloatingNode( node, &StructInstType::base );
+	}
+
+	void previsit( const UnionInstType * node ) {
+		previsit( (const Node *)node );
+		noFloatingNode( node, &UnionInstType::base );
+	}
+
+	void previsit( const EnumInstType * node ) {
+		previsit( (const Node *)node );
+		noFloatingNode( node, &EnumInstType::base );
+	}
+
+	void previsit( const TypeInstType * node ) {
+		previsit( (const Node *)node );
+		noFloatingNode( node, &TypeInstType::base );
 	}
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 847ab8f8121e19ac3b7f0aa27361926c67b12c62)
+++ src/InitTweak/InitTweak.cc	(revision dbf5e1890699a4755af129c8750ab720f60fcc8c)
@@ -882,5 +882,5 @@
 		if (!assign) {
 			auto td = new ast::TypeDecl(CodeLocation(), "T", {}, nullptr, ast::TypeDecl::Dtype, true);
-			assign = new ast::FunctionDecl(CodeLocation(), "?=?", {},
+			assign = new ast::FunctionDecl(CodeLocation(), "?=?", {td},
 			{ new ast::ObjectDecl(CodeLocation(), "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))),
 			  new ast::ObjectDecl(CodeLocation(), "_src", new ast::TypeInstType("T", td))},
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 847ab8f8121e19ac3b7f0aa27361926c67b12c62)
+++ src/Parser/parser.yy	(revision dbf5e1890699a4755af129c8750ab720f60fcc8c)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 12 06:14:16 2023
-// Update Count     : 6382
+// Last Modified On : Wed Jul 12 23:06:44 2023
+// Update Count     : 6389
 //
 
@@ -1868,8 +1868,8 @@
 
 KR_parameter_list:
-	push c_declaration pop ';'
-		{ $$ = $2; }
-	| KR_parameter_list push c_declaration pop ';'
-		{ $$ = $1->appendList( $3 ); }
+	c_declaration ';'
+		{ $$ = $1; }
+	| KR_parameter_list c_declaration ';'
+		{ $$ = $1->appendList( $2 ); }
 	;
 
@@ -2033,8 +2033,8 @@
 			} else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
 		}
-	| typedef_declaration pop ',' push declarator
-		{
-			typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname, "typedef_declaration 2" );
-			$$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
+	| typedef_declaration ',' declarator
+		{
+			typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "typedef_declaration 2" );
+			$$ = $1->appendList( $1->cloneBaseType( $3 )->addTypedef() );
 		}
 	| type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
@@ -2052,5 +2052,5 @@
 			SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
 		}
-	| typedef_expression pop ',' push identifier '=' assignment_expression
+	| typedef_expression ',' identifier '=' assignment_expression
 		{
 			SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
Index: src/Validate/ForallPointerDecay.cpp
===================================================================
--- src/Validate/ForallPointerDecay.cpp	(revision 847ab8f8121e19ac3b7f0aa27361926c67b12c62)
+++ src/Validate/ForallPointerDecay.cpp	(revision dbf5e1890699a4755af129c8750ab720f60fcc8c)
@@ -23,7 +23,6 @@
 #include "Common/CodeLocation.h"
 #include "Common/ToString.hpp"
+#include "Common/utility.h"
 #include "SymTab/FixFunction.h"
-
-#include "AST/Print.hpp"
 
 namespace Validate {
@@ -51,11 +50,14 @@
 }
 
-template<typename T>
-void append( std::vector<T> & dst, std::vector<T> & src ) {
-	dst.reserve( dst.size() + src.size() );
-	for ( auto el : src ) {
-		dst.emplace_back( std::move( el ) );
-	}
-	src.clear();
+ast::FunctionDecl * updateAssertions( ast::FunctionDecl * decl ) {
+	auto type = ast::mutate( decl->type.get() );
+	type->assertions.clear();
+	type->assertions.reserve( decl->assertions.size() );
+	for ( auto & assertion : decl->assertions ) {
+		type->assertions.emplace_back(
+			new ast::VariableExpr( decl->location, assertion ) );
+	}
+	decl->type = type;
+	return decl;
 }
 
@@ -96,5 +98,5 @@
 					decl->get_type() ) ) {
 				auto moreAsserts = expandTrait( traitInst );
-				append( assertions, moreAsserts );
+				splice( assertions, moreAsserts );
 			} else {
 				assertions.push_back( decl );
@@ -108,4 +110,5 @@
 	static TypeDeclVec expandTypeDecls( const TypeDeclVec & old ) {
 		TypeDeclVec typeDecls;
+		typeDecls.reserve( old.size() );
 		for ( const ast::TypeDecl * typeDecl : old ) {
 			typeDecls.push_back( ast::mutate_field( typeDecl,
@@ -123,12 +126,5 @@
 		mut->assertions = expandAssertions( decl->assertions );
 		// Update the assertion list on the type as well.
-		auto mutType = ast::mutate( mut->type.get() );
-		mutType->assertions.clear();
-		for ( auto & assertion : mut->assertions ) {
-			mutType->assertions.emplace_back(
-				new ast::VariableExpr( mut->location, assertion ) );
-		}
-		mut->type = mutType;
-		return mut;
+		return updateAssertions( mut );
 	}
 
@@ -154,4 +150,5 @@
 		const std::vector<ast::ptr<ast::DeclWithType>> & assertions ) {
 	std::vector<ast::ptr<ast::DeclWithType>> ret;
+	ret.reserve( assertions.size() );
 	for ( const auto & assn : assertions ) {
 		bool isVoid = false;
@@ -187,4 +184,11 @@
 	}
 
+	const ast::FunctionDecl * postvisit( const ast::FunctionDecl * decl ) {
+		if ( decl->assertions.empty() ) {
+			return decl;
+		}
+		return updateAssertions( mutate( decl ) );
+	}
+
 	const ast::StructDecl * previsit( const ast::StructDecl * decl ) {
 		if ( decl->params.empty() ) {
@@ -204,14 +208,12 @@
 };
 
-struct OberatorChecker final {
+struct OperatorChecker final {
 	void previsit( const ast::ObjectDecl * obj ) {
-		if ( CodeGen::isOperator( obj->name ) ) {
-			auto type = obj->type->stripDeclarator();
-			if ( ! dynamic_cast< const ast::FunctionType * >( type ) ) {
-				SemanticError( obj->location,
-					toCString( "operator ", obj->name.c_str(), " is not "
-					"a function or function pointer." ) );
-			}
-		}
+		if ( !CodeGen::isOperator( obj->name ) ) return;
+		auto type = obj->type->stripDeclarator();
+		if ( dynamic_cast< const ast::FunctionType * >( type ) ) return;
+		SemanticError( obj->location,
+			toCString( "operator ", obj->name.c_str(), " is not "
+			"a function or function pointer." ) );
 	}
 };
@@ -234,5 +236,5 @@
 	ast::Pass<TraitExpander>::run( transUnit );
 	ast::Pass<AssertionFunctionFixer>::run( transUnit );
-	ast::Pass<OberatorChecker>::run( transUnit );
+	ast::Pass<OperatorChecker>::run( transUnit );
 	ast::Pass<UniqueFixCore>::run( transUnit );
 }
Index: src/Validate/LinkReferenceToTypes.cpp
===================================================================
--- src/Validate/LinkReferenceToTypes.cpp	(revision 847ab8f8121e19ac3b7f0aa27361926c67b12c62)
+++ src/Validate/LinkReferenceToTypes.cpp	(revision dbf5e1890699a4755af129c8750ab720f60fcc8c)
@@ -10,6 +10,6 @@
 // Created On       : Thr Apr 21 11:41:00 2022
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Sep 20 16:17:00 2022
-// Update Count     : 2
+// Last Modified On : Fri Jul 14  9:19:00 2023
+// Update Count     : 3
 //
 
@@ -27,4 +27,5 @@
 struct LinkTypesCore : public WithNoIdSymbolTable,
 		public ast::WithCodeLocation,
+		public ast::WithDeclsToAdd<>,
 		public ast::WithGuards,
 		public ast::WithShortCircuiting,
@@ -63,5 +64,32 @@
 	template<typename AggrDecl>
 	AggrDecl const * renameGenericParams( AggrDecl const * decl );
+
+	// This cluster is used to add declarations (before) but outside of
+	// any "namespaces" which would qualify the names.
+	bool inNamespace = false;
+	std::list<ast::ptr<ast::Decl>> declsToAddOutside;
+	/// The "leaveNamespace" is handled by guard.
+	void enterNamespace();
+	/// Puts the decl on the back of declsToAddAfter once traversal is
+	/// outside of any namespaces.
+	void addDeclAfterOutside( ast::Decl const * );
 };
+
+void LinkTypesCore::enterNamespace() {
+	if ( inNamespace ) return;
+	inNamespace = true;
+	GuardAction( [this](){
+		inNamespace = false;
+		declsToAddAfter.splice( declsToAddAfter.begin(), declsToAddOutside );
+	} );
+}
+
+void LinkTypesCore::addDeclAfterOutside( ast::Decl const * decl ) {
+	if ( inNamespace ) {
+		declsToAddOutside.emplace_back( decl );
+	} else {
+		declsToAddAfter.emplace_back( decl );
+	}
+}
 
 ast::TypeInstType const * LinkTypesCore::postvisit( ast::TypeInstType const * type ) {
@@ -80,11 +108,22 @@
 ast::EnumInstType const * LinkTypesCore::postvisit( ast::EnumInstType const * type ) {
 	ast::EnumDecl const * decl = symtab.lookupEnum( type->name );
+	// It's not a semantic error if the enum is not found, just an implicit forward declaration.
+	// The unset code location is used to detect imaginary declarations.
+	// (They may never be used for enumerations.)
+	if ( !decl || decl->location.isUnset() ) {
+		assert( location );
+		ast::EnumDecl * mut = new ast::EnumDecl( *location, type->name );
+		mut->linkage = ast::Linkage::Compiler;
+		decl = mut;
+		symtab.addEnum( decl );
+		addDeclAfterOutside( decl );
+	}
+
 	ast::EnumInstType * mut = ast::mutate( type );
-	// It's not a semantic error if the enum is not found, just an implicit forward declaration.
-	if ( decl ) {
-		// Just linking in the node.
-		mut->base = decl;
-	}
-	if ( !decl || !decl->body ) {
+
+	// Just linking in the node.
+	mut->base = decl;
+
+	if ( !decl->body ) {
 		forwardEnums[ mut->name ].push_back( mut );
 	}
@@ -94,11 +133,21 @@
 ast::StructInstType const * LinkTypesCore::postvisit( ast::StructInstType const * type ) {
 	ast::StructDecl const * decl = symtab.lookupStruct( type->name );
+	// It's not a semantic error if the struct is not found, just an implicit forward declaration.
+	// The unset code location is used to detect imaginary declarations.
+	if ( !decl || decl->location.isUnset() ) {
+		assert( location );
+		ast::StructDecl * mut = new ast::StructDecl( *location, type->name );
+		mut->linkage = ast::Linkage::Compiler;
+		decl = mut;
+		symtab.addStruct( decl );
+		addDeclAfterOutside( decl );
+	}
+
 	ast::StructInstType * mut = ast::mutate( type );
-	// It's not a semantic error if the struct is not found, just an implicit forward declaration.
-	if ( decl ) {
-		// Just linking in the node.
-		mut->base = decl;
-	}
-	if ( !decl || !decl->body ) {
+
+	// Just linking in the node.
+	mut->base = decl;
+
+	if ( !decl->body ) {
 		forwardStructs[ mut->name ].push_back( mut );
 	}
@@ -108,11 +157,21 @@
 ast::UnionInstType const * LinkTypesCore::postvisit( ast::UnionInstType const * type ) {
 	ast::UnionDecl const * decl = symtab.lookupUnion( type->name );
+	// It's not a semantic error if the union is not found, just an implicit forward declaration.
+	// The unset code location is used to detect imaginary declarations.
+	if ( !decl || decl->location.isUnset() ) {
+		assert( location );
+		ast::UnionDecl * mut = new ast::UnionDecl( *location, type->name );
+		mut->linkage = ast::Linkage::Compiler;
+		decl = mut;
+		symtab.addUnion( decl );
+		addDeclAfterOutside( decl );
+	}
+
 	ast::UnionInstType * mut = ast::mutate( type );
-	// It's not a semantic error if the union is not found, just an implicit forward declaration.
-	if ( decl ) {
-		// Just linking in the node.
-		mut->base = decl;
-	}
-	if ( !decl || !decl->body ) {
+
+	// Just linking in the node.
+	mut->base = decl;
+
+	if ( !decl->body ) {
 		forwardUnions[ mut->name ].push_back( mut );
 	}
@@ -219,4 +278,5 @@
 
 ast::StructDecl const * LinkTypesCore::previsit( ast::StructDecl const * decl ) {
+	enterNamespace();
 	return renameGenericParams( decl );
 }
@@ -237,4 +297,5 @@
 
 ast::UnionDecl const * LinkTypesCore::previsit( ast::UnionDecl const * decl ) {
+	enterNamespace();
 	return renameGenericParams( decl );
 }
Index: src/Validate/ReplaceTypedef.cpp
===================================================================
--- src/Validate/ReplaceTypedef.cpp	(revision 847ab8f8121e19ac3b7f0aa27361926c67b12c62)
+++ src/Validate/ReplaceTypedef.cpp	(revision dbf5e1890699a4755af129c8750ab720f60fcc8c)
@@ -20,5 +20,4 @@
 #include "Common/ScopedMap.h"
 #include "Common/UniqueName.h"
-#include "Common/utility.h"
 #include "ResolvExpr/Unify.h"
 
@@ -294,5 +293,5 @@
 		aggrDecl->name, ast::Storage::Classes(), type, aggrDecl->linkage );
 	// Add the implicit typedef to the AST.
-	declsToAddBefore.push_back( ast::deepCopy( typeDecl.get() ) );
+	declsToAddAfter.push_back( ast::deepCopy( typeDecl.get() ) );
 	// Shore the name in the map of names.
 	typedefNames[ aggrDecl->name ] =
@@ -316,8 +315,9 @@
 	auto mut = ast::mutate( decl );
 
-	std::vector<ast::ptr<ast::Decl>> members;
+	std::list<ast::ptr<ast::Decl>> members;
 	// Unroll accept_all for decl->members so that implicit typedefs for
 	// nested types are added to the aggregate body.
 	for ( ast::ptr<ast::Decl> const & member : mut->members ) {
+		assert( declsToAddBefore.empty() );
 		assert( declsToAddAfter.empty() );
 		ast::Decl const * newMember = nullptr;
@@ -328,11 +328,12 @@
 		}
 		if ( !declsToAddBefore.empty() ) {
-			for ( auto declToAdd : declsToAddBefore ) {
-				members.push_back( declToAdd );
-			}
-			declsToAddBefore.clear();
+			members.splice( members.end(), declsToAddBefore );
 		}
 		members.push_back( newMember );
-	}
+		if ( !declsToAddAfter.empty() ) {
+			members.splice( members.end(), declsToAddAfter );
+		}
+	}
+	assert( declsToAddBefore.empty() );
 	assert( declsToAddAfter.empty() );
 	if ( !errors.isEmpty() ) { throw errors; }
