Index: src/AST/Create.cpp
===================================================================
--- src/AST/Create.cpp	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/AST/Create.cpp	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -42,17 +42,11 @@
 		return nullptr;
 	}
-	return new ast::FunctionDecl( decl->location,
-		decl->name,
-		vectorCopy( decl->type_params ),
-		vectorCopy( decl->assertions ),
-		vectorCopy( decl->params ),
-		vectorCopy( decl->returns ),
-		nullptr,
-		decl->storage,
-		decl->linkage,
-		vectorCopy( decl->attributes ),
-		decl->funcSpec,
-		decl->type->isVarArgs
-	);
+	// The cast and changing the original should be safe as long as the
+	// change is reverted before anything else sees it. It's also faster.
+	FunctionDecl * mutDecl = const_cast<FunctionDecl *>( decl );
+	CompoundStmt const * stmts = mutDecl->stmts.release();
+	FunctionDecl * copy = deepCopy( mutDecl );
+	mutDecl->stmts = stmts;
+	return copy;
 }
 
Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/AST/Util.cpp	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -20,6 +20,10 @@
 #include "Pass.hpp"
 #include "TranslationUnit.hpp"
+#include "Common/utility.h"
+#include "GenPoly/ScopedSet.h"
 
 #include <vector>
+
+using GenPoly::ScopedSet;
 
 namespace ast {
@@ -173,8 +177,195 @@
 };
 
+/// Checks that referred to nodes are in scope.
+/// This checks many readonly pointers to see if the declaration they are
+/// referring to is in scope by the structural rules of code.
+// Any escapes marked with a bug should be removed once the bug is fixed.
+struct InScopeCore : public ast::WithShortCircuiting {
+	ScopedSet<DeclWithType const *> typedDecls;
+	ScopedSet<TypeDecl const *> typeDecls;
+	// These 3 are really hard to check, because uses that originally ref. at
+	// a forward declaration can be rewired to point a later full definition.
+	ScopedSet<StructDecl const *> structDecls;
+	ScopedSet<UnionDecl const *> unionDecls;
+	ScopedSet<EnumDecl const *> enumDecls;
+	ScopedSet<TraitDecl const *> traitDecls;
+
+	bool isInGlobal = false;
+
+	void beginScope() {
+		typedDecls.beginScope();
+		typeDecls.beginScope();
+		structDecls.beginScope();
+		unionDecls.beginScope();
+		enumDecls.beginScope();
+		traitDecls.beginScope();
+	}
+
+	void endScope() {
+		typedDecls.endScope();
+		typeDecls.endScope();
+		structDecls.endScope();
+		unionDecls.endScope();
+		enumDecls.endScope();
+		traitDecls.endScope();
+	}
+
+	void previsit( ApplicationExpr const * expr ) {
+		// All isInGlobal manipulation is just to isolate this check.
+		// The invalid compound literals lead to bad ctor/dtors. [#280]
+		VariableExpr const * func = nullptr;
+		CastExpr const * cast = nullptr;
+		VariableExpr const * arg = nullptr;
+		if ( isInGlobal
+				&& 1 == expr->args.size()
+				&& ( func = expr->func.as<VariableExpr>() )
+				&& ( "?{}" == func->var->name || "^?{}" == func->var->name )
+				&& ( cast = expr->args[0].as<CastExpr>() )
+				&& ( arg = cast->arg.as<VariableExpr>() )
+				&& isPrefix( arg->var->name, "_compLit" ) ) {
+			visit_children = false;
+		}
+	}
+
+	void previsit( VariableExpr const * expr ) {
+		if ( !expr->var ) return;
+		// bitwise assignment escape [#281]
+		if ( expr->var->location.isUnset() ) return;
+		assert( typedDecls.contains( expr->var ) );
+	}
+
+	void previsit( FunctionType const * type ) {
+		// This is to avoid checking the assertions, which can point at the
+		// function's declaration and not the enclosing function.
+		for ( auto type_param : type->forall ) {
+			if ( type_param->formal_usage ) {
+				visit_children = false;
+				// We could check non-assertion fields here.
+			}
+		}
+	}
+
+	void previsit( TypeInstType const * type ) {
+		if ( !type->base ) return;
+		assertf( type->base->isManaged(), "Floating Node" );
+
+		// bitwise assignment escape [#281]
+		if ( type->base->location.isUnset() ) return;
+		// Formal types can actually look at out of scope variables.
+		if ( type->formal_usage ) return;
+		assert( typeDecls.contains( type->base ) );
+	}
+
+	void previsit( TraitInstType const * type ) {
+		if ( !type->base ) return;
+		assert( traitDecls.contains( type->base ) );
+	}
+
+	void previsit( ObjectDecl const * decl ) {
+		typedDecls.insert( decl );
+		// There are some ill-formed compound literals. [#280]
+		// The only known problem cases are at the top level.
+		if ( isPrefix( decl->name, "_compLit" ) ) {
+			visit_children = false;
+		}
+	}
+
+	void previsit( FunctionDecl const * decl ) {
+		typedDecls.insert( decl );
+		beginScope();
+		for ( auto & type_param : decl->type_params ) {
+			typeDecls.insert( type_param );
+		}
+		for ( auto & assertion : decl->assertions ) {
+			typedDecls.insert( assertion );
+		}
+		for ( auto & param : decl->params ) {
+			typedDecls.insert( param );
+		}
+		for ( auto & ret : decl->returns ) {
+			typedDecls.insert( ret );
+		}
+		// No special handling of withExprs.
+
+		// Part of the compound literal escape. [#280]
+		if ( "__global_init__" == decl->name
+				|| "__global_destroy__" == decl->name ) {
+			assert( !isInGlobal );
+			isInGlobal = true;
+		}
+	}
+
+	void postvisit( FunctionDecl const * decl ) {
+		endScope();
+		// Part of the compound literal escape. [#280]
+		if ( isInGlobal && ( "__global_init__" == decl->name
+				|| "__global_destroy__" == decl->name ) ) {
+			isInGlobal = false;
+		}
+	}
+
+	void previsit( StructDecl const * decl ) {
+		structDecls.insert( decl );
+		beginScope();
+		for ( auto & type_param : decl->params ) {
+			typeDecls.insert( type_param );
+		}
+	}
+
+	void postvisit( StructDecl const * ) {
+		endScope();
+	}
+
+	void previsit( UnionDecl const * decl ) {
+		unionDecls.insert( decl );
+		beginScope();
+		for ( auto & type_param : decl->params ) {
+			typeDecls.insert( type_param );
+		}
+	}
+
+	void postvisit( UnionDecl const * ) {
+		endScope();
+	}
+
+	void previsit( EnumDecl const * decl ) {
+		enumDecls.insert( decl );
+		if ( ast::EnumDecl::EnumHiding::Visible == decl->hide ) {
+			for ( auto & member : decl->members ) {
+				typedDecls.insert( member.strict_as<ast::DeclWithType>() );
+			}
+		}
+		beginScope();
+		for ( auto & type_param : decl->params ) {
+			typeDecls.insert( type_param );
+		}
+	}
+
+	void postvisit( EnumDecl const * ) {
+		endScope();
+	}
+
+	void previsit( TraitDecl const * decl ) {
+		traitDecls.insert( decl );
+		beginScope();
+		for ( auto & type_param : decl->params ) {
+			typeDecls.insert( type_param );
+		}
+	}
+
+	void postvisit( TraitDecl const * ) {
+		endScope();
+	}
+
+	void previsit( Designation const * ) {
+		visit_children = false;
+	}
+};
+
 } // namespace
 
 void checkInvariants( TranslationUnit & transUnit ) {
-	ast::Pass<InvariantCore>::run( transUnit );
+	Pass<InvariantCore>::run( transUnit );
+	Pass<InScopeCore>::run( transUnit );
 }
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/InitTweak/InitTweak.cc	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -891,6 +891,5 @@
 				dst = new ast::AddressExpr(dst);
 			}
-		}
-		else {
+		} else {
 			dst = new ast::CastExpr(dst, new ast::ReferenceType(dst->result, {}));
 		}
@@ -900,5 +899,9 @@
 			}
 		}
-		return new ast::ApplicationExpr(dst->location, ast::VariableExpr::functionPointer(dst->location, assign), {dst, src});
+		auto var = ast::VariableExpr::functionPointer(dst->location, assign);
+		auto app = new ast::ApplicationExpr(dst->location, var, {dst, src});
+		// Skip the resolver, just set the result to the correct type.
+		app->result = ast::deepCopy( src->result );
+		return app;
 	}
 
Index: src/SymTab/GenImplicitCall.cpp
===================================================================
--- src/SymTab/GenImplicitCall.cpp	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/SymTab/GenImplicitCall.cpp	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -16,4 +16,5 @@
 #include "GenImplicitCall.hpp"
 
+#include "AST/Copy.hpp"                  // for deepCopy
 #include "AST/Decl.hpp"                  // for ObjectDecl
 #include "AST/Expr.hpp"                  // for ConstantExpr, UntypedExpr,...
@@ -115,8 +116,9 @@
 	std::string cmp, update;
 
+	const ast::Expr * dimension = deepCopy( array->dimension );
 	if ( forward ) {
 		// generate: for ( int i = 0; i < N; ++i )
 		begin = ast::ConstantExpr::from_int( loc, 0 );
-		end = array->dimension;
+		end = dimension;
 		cmp = "?<?";
 		update = "++?";
@@ -124,5 +126,5 @@
 		// generate: for ( int i = N-1; i >= 0; --i )
 		begin = ast::UntypedExpr::createCall( loc, "?-?",
-			{ array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } );
+			{ dimension, ast::ConstantExpr::from_int( loc, 1 ) } );
 		end = ast::ConstantExpr::from_int( loc, 0 );
 		cmp = "?>=?";
Index: src/Validate/Autogen.cpp
===================================================================
--- src/Validate/Autogen.cpp	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/Validate/Autogen.cpp	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -532,8 +532,20 @@
 		)
 	);
-	return genImplicitCall(
+	auto stmt = genImplicitCall(
 		srcParam, dstSelect, location, func->name,
 		field, direction
 	);
+	// This could return the above directly, except the generated code is
+	// built using the structure's members and that means all the scoped
+	// names (the forall parameters) are incorrect. This corrects them.
+	if ( stmt && !decl->params.empty() ) {
+		ast::DeclReplacer::TypeMap oldToNew;
+		for ( auto pair : group_iterate( decl->params, func->type_params ) ) {
+			oldToNew.emplace( std::get<0>(pair), std::get<1>(pair) );
+		}
+		auto node = ast::DeclReplacer::replace( stmt, oldToNew );
+		stmt = strict_dynamic_cast<const ast::Stmt *>( node );
+	}
+	return stmt;
 }
 
Index: src/Validate/FixQualifiedTypes.cpp
===================================================================
--- src/Validate/FixQualifiedTypes.cpp	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/Validate/FixQualifiedTypes.cpp	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -89,26 +89,25 @@
 	}
 
-	ast::Expr const * postvisit( ast::QualifiedNameExpr const * t) {
+	ast::Expr const * postvisit( ast::QualifiedNameExpr const * t ) {
 		assert( location );
-		if ( t->type_decl ) {
-        	auto enumName = t->type_decl->name;
-        	const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName );
-			for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) {
-				if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) {
-					if ( memberAsObj->name == t->name ) {
-						return new ast::VariableExpr( t->location, memberAsObj );
-					}
-				} else {
-					assertf( false, "unhandled qualified child type");
+		if ( !t->type_decl ) return t;
+
+		auto enumName = t->type_decl->name;
+		const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName );
+		for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) {
+			if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) {
+				if ( memberAsObj->name == t->name ) {
+					return new ast::VariableExpr( t->location, memberAsObj );
 				}
+			} else {
+				assertf( false, "unhandled qualified child type" );
 			}
+		}
 
-        	auto var = new ast::ObjectDecl( t->location, t->name,
-			new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall );
-			var->mangleName = Mangle::mangle( var );
-			return new ast::VariableExpr( t->location, var );
-        }
-
-		return t;
+		auto var = new ast::ObjectDecl( t->location, t->name,
+			new ast::EnumInstType( enumDecl, ast::CV::Const ),
+			nullptr, {}, ast::Linkage::Cforall );
+		var->mangleName = Mangle::mangle( var );
+		return new ast::VariableExpr( t->location, var );
 	}
 
Index: src/Validate/ForallPointerDecay.cpp
===================================================================
--- src/Validate/ForallPointerDecay.cpp	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/Validate/ForallPointerDecay.cpp	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -214,6 +214,6 @@
 		if ( dynamic_cast< const ast::FunctionType * >( type ) ) return;
 		SemanticError( obj->location,
-			toCString( "operator ", obj->name.c_str(), " is not "
-			"a function or function pointer." ) );
+			toCString( "operator ", obj->name.c_str(),
+			" is not a function or function pointer." ) );
 	}
 };
@@ -237,4 +237,7 @@
 	ast::Pass<AssertionFunctionFixer>::run( transUnit );
 	ast::Pass<OperatorChecker>::run( transUnit );
+}
+
+void fixUniqueIds( ast::TranslationUnit & transUnit ) {
 	ast::Pass<UniqueFixCore>::run( transUnit );
 }
Index: src/Validate/ForallPointerDecay.hpp
===================================================================
--- src/Validate/ForallPointerDecay.hpp	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/Validate/ForallPointerDecay.hpp	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -27,10 +27,13 @@
 
 /// Cleans up assertion lists and expands traits.
-/// Also checks that operator names are used properly on functions and
-/// assigns unique IDs. This is a "legacy" pass.
+/// Also checks that operator names are used properly on functions.
+/// This is a "legacy" pass.
+/// Must happen before auto-gen routines are added.
+void decayForallPointers( ast::TranslationUnit & transUnit );
+
+/// Sets uniqueIds on any declarations that do not have one set.
 /// Must be after implement concurrent keywords; because uniqueIds must be
 /// set on declaration before resolution.
-/// Must happen before auto-gen routines are added.
-void decayForallPointers( ast::TranslationUnit & transUnit );
+void fixUniqueIds( ast::TranslationUnit & transUnit );
 
 /// Expand all traits in an assertion list.
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 6a4dae6e0323dcc1f2905f70abe7bd4bcdabb1c4)
+++ src/main.cc	(revision f496046ba2faf27a2bbae7028f7005b58ac592ee)
@@ -334,4 +334,5 @@
 		PASS( "Link Reference To Types", Validate::linkReferenceToTypes, transUnit );
 
+		PASS( "Forall Pointer Decay", Validate::decayForallPointers, transUnit );
 		PASS( "Fix Qualified Types", Validate::fixQualifiedTypes, transUnit );
 		PASS( "Eliminate Typedef", Validate::eliminateTypedef, transUnit );
@@ -342,5 +343,5 @@
 		PASS( "Fix Return Statements", InitTweak::fixReturnStatements, transUnit );
 		PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords, transUnit );
-		PASS( "Forall Pointer Decay", Validate::decayForallPointers, transUnit );
+		PASS( "Fix Unique Ids", Validate::fixUniqueIds, transUnit );
 		PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls, transUnit );
 
@@ -369,5 +370,5 @@
 		PASS( "Translate Throws", ControlStruct::translateThrows, transUnit );
 		PASS( "Fix Labels", ControlStruct::fixLabels, transUnit );
-        PASS( "Implement Waituntil", Concurrency::generateWaitUntil, transUnit  );
+		PASS( "Implement Waituntil", Concurrency::generateWaitUntil, transUnit  );
 		PASS( "Fix Names", CodeGen::fixNames, transUnit );
 		PASS( "Gen Init", InitTweak::genInit, transUnit );
