Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 5fe35d604ff44afc2ac1fbd0310797d09fa78823)
+++ src/InitTweak/FixInit.cc	(revision 178e4ec86cc344917f0d9781c8bf4e520b7b2a53)
@@ -393,7 +393,7 @@
 			if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types
 
-			// type may involve type variables, so apply type substitution to get temporary variable's actual type.
+			// type may involve type variables, so apply type substitution to get temporary variable's actual type,
+			// since result type may not be substituted (e.g., if the type does not appear in the parameter list)
 			// Use applyFree so that types bound in function pointers are not substituted, e.g. in forall(dtype T) void (*)(T).
-			result = result->clone();
 			env->applyFree( result );
 			ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr );
@@ -570,11 +570,5 @@
 
 			if ( returnDecl ) {
-				UntypedExpr * assign = new UntypedExpr( new NameExpr( "?=?" ) );
-				assign->get_args().push_back( new VariableExpr( returnDecl ) );
-				assign->get_args().push_back( callExpr );
-				// know the result type of the assignment is the type of the LHS (minus the pointer), so
-				// add that onto the assignment expression so that later steps have the necessary information
-				assign->set_result( returnDecl->get_type()->clone() );
-
+				ApplicationExpr * assign = createBitwiseAssignment( new VariableExpr( returnDecl ), callExpr );
 				Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
 				// move env from callExpr to retExpr
@@ -1146,8 +1140,4 @@
 			assert( ctorExpr->result && ctorExpr->get_result()->size() == 1 );
 
-			// xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary.
-			ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), ctorExpr->get_result()->clone(), nullptr );
-			declsToAddBefore.push_back( tmp );
-
 			// xxx - this can be TupleAssignExpr now. Need to properly handle this case.
 			ApplicationExpr * callExpr = strict_dynamic_cast< ApplicationExpr * > ( ctorExpr->get_callExpr() );
@@ -1155,4 +1145,8 @@
 			ctorExpr->set_callExpr( nullptr );
 			ctorExpr->set_env( nullptr );
+
+			// xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary.
+			ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), callExpr->args.front()->result->clone(), nullptr );
+			declsToAddBefore.push_back( tmp );
 			delete ctorExpr;
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 5fe35d604ff44afc2ac1fbd0310797d09fa78823)
+++ src/InitTweak/InitTweak.cc	(revision 178e4ec86cc344917f0d9781c8bf4e520b7b2a53)
@@ -12,4 +12,5 @@
 #include "Parser/LinkageSpec.h"    // for Spec, isBuiltin, Intrinsic
 #include "ResolvExpr/typeops.h"    // for typesCompatibleIgnoreQualifiers
+#include "SymTab/Autogen.h"
 #include "SymTab/Indexer.h"        // for Indexer
 #include "SynTree/Attribute.h"     // for Attribute
@@ -524,4 +525,23 @@
 	}
 
+	ApplicationExpr * createBitwiseAssignment( Expression * dst, Expression * src ) {
+		static FunctionDecl * assign = nullptr;
+		if ( ! assign ) {
+			// temporary? Generate a fake assignment operator to represent bitwise assignments.
+			// This operator could easily exist as a real function, but it's tricky because nothing should resolve to this function.
+			TypeDecl * td = new TypeDecl( "T", noStorageClasses, nullptr, TypeDecl::Dtype, true );
+			assign = new FunctionDecl( "?=?", noStorageClasses, LinkageSpec::Intrinsic, SymTab::genAssignType( new TypeInstType( noQualifiers, td->name, td ) ), nullptr );
+		}
+		if ( dynamic_cast< ReferenceType * >( dst->result ) ) {
+			dst = new AddressExpr( dst );
+		} else {
+			dst = new CastExpr( dst, new ReferenceType( noQualifiers, dst->result->clone() ) );
+		}
+		if ( dynamic_cast< ReferenceType * >( src->result ) ) {
+			src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) );
+		}
+		return new ApplicationExpr( VariableExpr::functionPointer( assign ), { dst, src } );
+	}
+
 	class ConstExprChecker : public Visitor {
 	public:
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 5fe35d604ff44afc2ac1fbd0310797d09fa78823)
+++ src/InitTweak/InitTweak.h	(revision 178e4ec86cc344917f0d9781c8bf4e520b7b2a53)
@@ -35,4 +35,7 @@
 	/// returns the first parameter of a constructor/destructor/assignment function
 	ObjectDecl * getParamThis( FunctionType * ftype );
+
+	/// generate a bitwise assignment operation.
+	ApplicationExpr * createBitwiseAssignment( Expression * dst, Expression * src );
 
 	/// transform Initializer into an argument list that can be passed to a call expression
