Index: src/Validate/Autogen.cpp
===================================================================
--- src/Validate/Autogen.cpp	(revision 0d7fc00c6e8b1ba082c03b271ec5f42acc5134f7)
+++ src/Validate/Autogen.cpp	(revision d32679d538afe4b499d20b11c9407b3fc906cd84)
@@ -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 0d7fc00c6e8b1ba082c03b271ec5f42acc5134f7)
+++ src/Validate/FixQualifiedTypes.cpp	(revision d32679d538afe4b499d20b11c9407b3fc906cd84)
@@ -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 0d7fc00c6e8b1ba082c03b271ec5f42acc5134f7)
+++ src/Validate/ForallPointerDecay.cpp	(revision d32679d538afe4b499d20b11c9407b3fc906cd84)
@@ -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 0d7fc00c6e8b1ba082c03b271ec5f42acc5134f7)
+++ src/Validate/ForallPointerDecay.hpp	(revision d32679d538afe4b499d20b11c9407b3fc906cd84)
@@ -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.
