diff --git a/libcfa/prelude/prelude-gen.cc b/libcfa/prelude/prelude-gen.cc
index 2fe54ca11..90ffeb8a2 100644
--- a/libcfa/prelude/prelude-gen.cc
+++ b/libcfa/prelude/prelude-gen.cc
@@ -205,30 +205,32 @@ int main() {
 	cout << "/////////////////////////////" << endl;
 	cout << endl;
 
-	auto otype = [](const std::string & type, bool do_volatile = false) {
+	// The general pattern for arithmetic types.
+	auto arithmetic = [](const std::string & type,
+			bool do_zero_one = true, bool do_volatile = false) {
 		cout << "void ?{} (" << type << " &);" << endl;
-		cout << "void ?{} (" << type << " &, " << type << ");" << endl;
-		cout << type << " ?=? (" << type << " &, " << type << ")";
+		cout << "void ?{} (" << type << " &, " << type << " const &);" << endl;
+		cout << type << " & ?=? (" << type << " &, " << type << " const &)";
 		if ( do_volatile ) {
-			cout << ", ?=?(volatile " << type << " &, " << type << ")";
+			cout << ", ?=?(volatile " << type << " &, " << type << " const &)";
 		}
 		cout << ";" << endl;
-		cout << "void ^?{}( " << type << " & );" << endl;
+		if ( do_zero_one ) {
+			cout << "void ?{}(" << type << " &, zero_t);" << endl;
+			cout << "void ?{}(" << type << " &, one_t);" << endl;
+		}
+		cout << "void ^?{}(" << type << " &);" << endl;
 	};
 
-	otype("zero_t");
+	arithmetic("zero_t", false);
 	cout << endl;
-	otype("one_t");
+	arithmetic("one_t", false);
 	cout << endl;
-	otype("_Bool", true);
+	arithmetic("_Bool", false, true);
 	cout << endl;
 
 	for (auto type : basicTypes) {
-		cout << "void ?{}(" << type.name << " &);" << endl;
-		cout << "void ?{}(" << type.name << " &, " << type.name << ");" << endl;
-		cout << "void ?{}(" << type.name << " &, zero_t);" << endl;
-		cout << "void ?{}(" << type.name << " &, one_t);" << endl;
-		cout << "void ^?{}(" << type.name << " &);" << endl;
+		arithmetic(type.name);
 		cout << endl;
 	}
 	cout << endl;
@@ -238,8 +240,8 @@ int main() {
 	cout << "//////////////////////////" << endl;
 	cout << endl;
 
-	cout << "forall(ftype FT) void ?{}( FT *&, FT * );" << endl;
-	cout << "forall(ftype FT) void ?{}( FT * volatile &, FT * );" << endl;
+	cout << "forall(ftype FT) void ?{}( FT *&, FT * const & );" << endl;
+	cout << "forall(ftype FT) void ?{}( FT * volatile &, FT * const & );" << endl;
 
 	// generate qualifiers
 	vector<string> qualifiersSingle;
@@ -263,7 +265,7 @@ int main() {
 	for (auto type : { "  DT", "void" }) {
 		for (auto cvq : qualifiersPair) {
 			for (auto is_vol : { "        ", "volatile" }) {
-				cout << "forall(DT &) void  ?{}(" << cvq.first << type << " * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
+				cout << "forall(DT &) void  ?{}(" << cvq.first << type << " * " << is_vol << " &, " << cvq.second << "DT * const &);" << endl;
 			}
 		}
 	}
@@ -297,8 +299,8 @@ int main() {
 	cout << endl;
 
 	cout << "forall(ftype FT) void	?{}( FT *	   &, zero_t );" << endl;
-	cout << "forall(ftype FT) FT *			?=?( FT *	   &, zero_t );" << endl;
-	cout << "forall(ftype FT) FT *			?=?( FT * volatile &, zero_t );" << endl;
+	cout << "forall(ftype FT) FT *&			?=?( FT *	   &, zero_t const & );" << endl;
+	cout << "forall(ftype FT) FT *&			?=?( FT * volatile &, zero_t const & );" << endl;
 	cout << "forall(ftype FT) void	?{}( FT *	   & );" << endl;
 	cout << "forall(ftype FT) void	^?{}( FT *	   & );" << endl;
 	cout << endl;
@@ -307,8 +309,8 @@ int main() {
 	cout << "// Pointer Operators //" << endl;
 	cout << "///////////////////////" << endl;
 
-	cout << "forall(ftype FT) FT *			?=?( FT *&, FT * );" << endl;
-	cout << "forall(ftype FT) FT *			?=?( FT * volatile &, FT * );" << endl;
+	cout << "forall(ftype FT) FT *&			?=?( FT *&, FT * const &);" << endl;
+	cout << "forall(ftype FT) FT *&			?=?( FT * volatile &, FT * const &);" << endl;
 	cout << "forall(ftype FT) int !?( FT * );" << endl;
 	cout << "forall(ftype FT) signed int ?==?( FT *, FT * );" << endl;
 	cout << "forall(ftype FT) signed int ?!=?( FT *, FT * );" << endl;
@@ -328,7 +330,7 @@ int main() {
 							for (auto q : qualifiersSingle){
 								for (auto q2 : { "        ", "volatile" }) {
 									forall();
-									cout << q << type << " * " << op.name << "(";
+									cout << q << type << " * &" << op.name << "(";
 									cout << q << type << " * " << q2 << " &";
 									cout << ");" << endl;
 								}
@@ -337,11 +339,11 @@ int main() {
 							for (auto q : qualifiersPair){
 								for (auto q2 : { "        ", "volatile" }) {
 									forall();
-									cout << q.first << type << " * " << op.name << "(";
+									cout << q.first << type << " * &" << op.name << "(";
 									cout << q.first << type << " * " << q2 << " &";
 
 									for (int i = 1; i < operands; ++i) {
-										cout << ", " << q.second << type << " *";
+										cout << ", " << q.second << type << " * " << q2 << " const &";
 									}
 									cout << ");" << endl;
 								}
@@ -407,10 +409,10 @@ int main() {
 
 	for (auto is_vol : { "        ", "volatile" }) {
 		for (auto cvq : qualifiersPair) {
-				cout << "forall(DT &) " << cvq.first << "void * ?=?( " << cvq.first << "void * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
+				cout << "forall(DT &) " << cvq.first << "void *& ?=?( " << cvq.first << "void * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
 		}
 		for (auto cvq : qualifiersSingle) {
-			cout << "forall(DT &) " << cvq <<   "  DT * ?=?( " << cvq << "  DT * " << is_vol << " &, zero_t);" << endl;
+			cout << "forall(DT &) " << cvq <<   "  DT *& ?=?( " << cvq << "  DT * " << is_vol << " &, zero_t);" << endl;
 		}
 	}
 	cout << endl;
diff --git a/src/GenPoly/Lvalue.cpp b/src/GenPoly/Lvalue.cpp
index a2e83f512..f2c09b326 100644
--- a/src/GenPoly/Lvalue.cpp
+++ b/src/GenPoly/Lvalue.cpp
@@ -103,6 +103,10 @@ struct CollapseAddressDeref final {
 	ast::Expr const * postvisit( ast::ApplicationExpr const * expr );
 };
 
+struct RValueCastAdjustment final {
+	ast::Expr const * postvisit( ast::AddressExpr const * expr );
+};
+
 /// GCC-like Generalized Lvalues (which have since been removed from GCC).
 /// https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Lvalues.html#Lvalues
 /// Replaces &(a,b) with (a, &b), &(a ? b : c) with (a ? &b : &c)
@@ -533,8 +537,6 @@ ast::Expr const * CollapseAddressDeref::postvisit(
 			ret->env = expr->env;
 			return ret;
 		}
-	} else {
-		return moveAddressUnderCast( expr );
 	}
 	return expr;
 }
@@ -560,6 +562,11 @@ ast::Expr const * CollapseAddressDeref::postvisit(
 	return expr;
 }
 
+ast::Expr const * RValueCastAdjustment::postvisit(
+		ast::AddressExpr const * expr ) {
+	return moveAddressUnderCast( expr );
+}
+
 ast::Expr const * GeneralizedLvalue::postvisit(
 		ast::AddressExpr const * expr ) {
 	return applyTransformation( expr, &ast::AddressExpr::arg,
@@ -639,6 +646,7 @@ void convertLvalue( ast::TranslationUnit & translationUnit ) {
 	ast::Pass<ReferenceConversions>::run( translationUnit );
 	ast::Pass<FixIntrinsicArgs>::run( translationUnit );
 	ast::Pass<CollapseAddressDeref>::run( translationUnit );
+	ast::Pass<RValueCastAdjustment>::run( translationUnit );
 	ast::Pass<GeneralizedLvalue>::run( translationUnit );
 	// Last because other passes need reference types to work.
 	ast::Pass<ReferenceTypeElimination>::run( translationUnit );
diff --git a/src/InitTweak/FixInit.cpp b/src/InitTweak/FixInit.cpp
index 5304dcda6..6657b3668 100644
--- a/src/InitTweak/FixInit.cpp
+++ b/src/InitTweak/FixInit.cpp
@@ -912,6 +912,13 @@ const ast::DeclWithType * FixInit::postvisit( const ast::ObjectDecl *_objDecl )
 				// ctorCall should be gone afterwards
 				auto mutArg = mutate(ctorArg);
 				mutArg->env = ctorCall->env;
+				// TODO: Get rid of layer of reference.
+				if ( auto cast = dynamic_cast<ast::CastExpr *>( mutArg ) ) {
+					if ( auto refType = cast->result.as<ast::ReferenceType>() ) {
+						cast->result = refType->base;
+						mutArg = cast;
+					}
+				}
 				objDecl->init = new ast::SingleInit(loc, mutArg );
 			} else {
 				stmtsToAddAfter.push_back( ctor );
diff --git a/src/InitTweak/InitTweak.cpp b/src/InitTweak/InitTweak.cpp
index b0c932ecd..a1ae61dab 100644
--- a/src/InitTweak/InitTweak.cpp
+++ b/src/InitTweak/InitTweak.cpp
@@ -319,7 +319,8 @@ bool isCopyFunction( const ast::FunctionDecl * decl ) {
 
 	const ast::Type * t1 = ast::getPointerBase( ftype->params.front() );
 	if ( ! t1 ) return false;
-	const ast::Type * t2 = ftype->params.back();
+	const ast::Type * t2 = ast::getPointerBase( ftype->params.back() );
+	if ( ! t2 ) return false;
 
 	return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2 );
 }
diff --git a/src/Parser/TypeData.cpp b/src/Parser/TypeData.cpp
index 135a0331d..5d7d3077c 100644
--- a/src/Parser/TypeData.cpp
+++ b/src/Parser/TypeData.cpp
@@ -731,8 +731,13 @@ void buildForall(
 		const CodeLocation & location = mutTypeDecl->location;
 		*i = mutTypeDecl;
 
-		// add assertion parameters to `type' tyvars in reverse order
-		// add assignment operator:  T * ?=?(T *, T)
+		// TODO: Helper functions!
+
+		ast::TypeInstType * mut0 = ast::shallowCopy( i->get() );
+		mut0->set_const( true );
+
+		// Add assertion parameters to `type' tyvars in reverse order:
+		// Add assignment operator:  T & ?=?(T &, T const &)
 		newAssertions.push_back( new ast::FunctionDecl(
 			location,
 			"?=?",
@@ -749,7 +754,7 @@ void buildForall(
 				new ast::ObjectDecl(
 					location,
 					"",
-					i->get(),
+					new ast::ReferenceType( mut0 ),
 					(ast::Init *)nullptr,
 					ast::Storage::Classes(),
 					ast::Linkage::Cforall,
@@ -760,7 +765,7 @@ void buildForall(
 				new ast::ObjectDecl(
 					location,
 					"",
-					i->get(),
+					new ast::ReferenceType( i->get() ),
 					(ast::Init *)nullptr,
 					ast::Storage::Classes(),
 					ast::Linkage::Cforall,
@@ -772,7 +777,7 @@ void buildForall(
 			ast::Linkage::Cforall
 		) );
 
-		// add default ctor:  void ?{}(T *)
+		// Add default ctor:  void ?{}(T &)
 		newAssertions.push_back( new ast::FunctionDecl(
 			location,
 			"?{}",
@@ -793,7 +798,7 @@ void buildForall(
 			ast::Linkage::Cforall
 		) );
 
-		// add copy ctor:  void ?{}(T *, T)
+		// Add copy ctor:  void ?{}(T &, T const &)
 		newAssertions.push_back( new ast::FunctionDecl(
 			location,
 			"?{}",
@@ -810,7 +815,7 @@ void buildForall(
 				new ast::ObjectDecl(
 					location,
 					"",
-					i->get(),
+					new ast::ReferenceType( mut0 ),
 					(ast::Init *)nullptr,
 					ast::Storage::Classes(),
 					ast::Linkage::Cforall,
@@ -823,7 +828,7 @@ void buildForall(
 			ast::Linkage::Cforall
 		) );
 
-		// add dtor:  void ^?{}(T *)
+		// Add dtor:  void ^?{}(T &)
 		newAssertions.push_back( new ast::FunctionDecl(
 			location,
 			"^?{}",
@@ -868,8 +873,10 @@ void buildForall(
 		const CodeLocation & location = mutTypeDecl->location;
 		*i = mutTypeDecl;
 
-		// add assertion parameters to `type' tyvars in reverse order
-		// add assignment operator:  T * ?=?(T *, T)
+		// TODO: Helper functions!
+
+		// Add assertion parameters to `type' tyvars in reverse order:
+		// Add assignment operator:  T & ?=?(T &, T const &)
 		newAssertions.push_back( new ast::FunctionDecl(
 			location,
 			"?=?",
@@ -886,7 +893,8 @@ void buildForall(
 				new ast::ObjectDecl(
 					location,
 					"",
-					new ast::TypeInstType( td->name, *i ),
+					new ast::ReferenceType(
+						new ast::TypeInstType( td->name, *i, ast::CV::Const ) ),
 					(ast::Init *)nullptr,
 					ast::Storage::Classes(),
 					ast::Linkage::Cforall,
@@ -897,7 +905,7 @@ void buildForall(
 				new ast::ObjectDecl(
 					location,
 					"",
-					new ast::TypeInstType( td->name, *i ),
+					new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
 					(ast::Init *)nullptr,
 					ast::Storage::Classes(),
 					ast::Linkage::Cforall,
@@ -909,7 +917,7 @@ void buildForall(
 			ast::Linkage::Cforall
 		) );
 
-		// add default ctor:  void ?{}(T *)
+		// add default ctor:  void ?{}(T &)
 		newAssertions.push_back( new ast::FunctionDecl(
 			location,
 			"?{}",
@@ -931,7 +939,7 @@ void buildForall(
 			ast::Linkage::Cforall
 		) );
 
-		// add copy ctor:  void ?{}(T *, T)
+		// Add copy ctor:  void ?{}(T &, T const &)
 		newAssertions.push_back( new ast::FunctionDecl(
 			location,
 			"?{}",
@@ -949,7 +957,8 @@ void buildForall(
 				new ast::ObjectDecl(
 					location,
 					"",
-					new ast::TypeInstType( td->name, *i ),
+					new ast::ReferenceType(
+						new ast::TypeInstType( td->name, *i, ast::CV::Const ) ),
 					(ast::Init *)nullptr,
 					ast::Storage::Classes(),
 					ast::Linkage::Cforall,
@@ -962,7 +971,7 @@ void buildForall(
 			ast::Linkage::Cforall
 		) );
 
-		// add dtor:  void ^?{}(T *)
+		// Add dtor:  void ^?{}(T &)
 		newAssertions.push_back( new ast::FunctionDecl(
 			location,
 			"^?{}",
diff --git a/src/Validate/Autogen.cpp b/src/Validate/Autogen.cpp
index 4f753fed5..ce0a5a701 100644
--- a/src/Validate/Autogen.cpp
+++ b/src/Validate/Autogen.cpp
@@ -378,9 +378,11 @@ ast::ObjectDecl * FuncGenerator::dstParam() const {
 }
 
 ast::ObjectDecl * FuncGenerator::srcParam() const {
+	ast::ptr<ast::Type> srcType = ast::deepCopy( type );
+	add_qualifiers( srcType, { ast::CV::Const } );
 	return addUnusedAttribute(
 		new ast::ObjectDecl( getLocation(), "_src",
-			ast::deepCopy( type ) ) );
+			new ast::ReferenceType( srcType.release() ) ) );
 }
 
 /// Use the current type T to create `void ?{}(T & _dst)`.
@@ -388,7 +390,7 @@ ast::FunctionDecl * FuncGenerator::genCtorProto() const {
 	return genProto( "?{}", { dstParam() }, {} );
 }
 
-/// Use the current type T to create `void ?{}(T & _dst, T _src)`.
+/// Use the current type T to create `void ?{}(T & _dst, T const & _src)`.
 ast::FunctionDecl * FuncGenerator::genCopyProto() const {
 	return genProto( "?{}", { dstParam(), srcParam() }, {} );
 }
@@ -403,10 +405,10 @@ ast::FunctionDecl * FuncGenerator::genDtorProto() const {
 	return genProto( "^?{}", { dst }, {} );
 }
 
-/// Use the current type T to create `T ?=?(T & _dst, T _src)`.
+/// Use the current type T to create `T & ?=?(T & _dst, T const & _src)`.
 ast::FunctionDecl * FuncGenerator::genAssignProto() const {
 	// Only the name is different, so just reuse the generation function.
-	auto retval = srcParam();
+	auto retval = dstParam();
 	retval->name = "_ret";
 	return genProto( "?=?", { dstParam(), srcParam() }, { retval } );
 }
@@ -549,6 +551,14 @@ void StructFuncGenerator::makeFunctionBody( Iterator current, Iterator end,
 
 	ast::CompoundStmt * stmts = new ast::CompoundStmt( location );
 
+	assert( !func->params.empty() );
+	const ast::ObjectDecl * dstParam =
+		func->params.front().strict_as<ast::ObjectDecl>();
+	const ast::ObjectDecl * srcParam = nullptr;
+	if ( 2 == func->params.size() ) {
+		srcParam = func->params.back().strict_as<ast::ObjectDecl>();
+	}
+
 	for ( ; current != end ; ++current ) {
 		const ast::ptr<ast::Decl> & member = *current;
 		auto field = member.as<ast::ObjectDecl>();
@@ -568,17 +578,17 @@ void StructFuncGenerator::makeFunctionBody( Iterator current, Iterator end,
 			}
 		}
 
-		assert( !func->params.empty() );
-		const ast::ObjectDecl * dstParam =
-			func->params.front().strict_as<ast::ObjectDecl>();
-		const ast::ObjectDecl * srcParam = nullptr;
-		if ( 2 == func->params.size() ) {
-			srcParam = func->params.back().strict_as<ast::ObjectDecl>();
-		}
+		ast::MemberExpr * srcSelect = (!srcParam) ? nullptr :
+			new ast::MemberExpr(
+				location,
+				field,
+				new ast::CastExpr(
+					location,
+					new ast::VariableExpr( location, srcParam ),
+					srcParam->type.strict_as<ast::ReferenceType>()->base
+				)
+			);
 
-		ast::MemberExpr * srcSelect = (srcParam) ? new ast::MemberExpr(
-			location, field, new ast::VariableExpr( location, srcParam )
-		) : nullptr;
 		const ast::Stmt * stmt =
 			makeMemberOp( location, dstParam, srcSelect, field, func, direction );
 
