Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 175ad32b7130d539df6d505fb8ce4d6ad39a9097)
+++ src/InitTweak/FixInit.cc	(revision 46183193bf46bc3535bd1ab2f2760e3a0361433f)
@@ -239,5 +239,4 @@
 			SemanticError errors;
 		  private:
-			void handleFirstParam( Expression * firstParam );
 			template< typename... Params >
 			void emit( CodeLocation, const Params &... params );
@@ -1032,5 +1031,5 @@
 
 			if ( ! unhandled.empty() ) {
-				// need to explicitly re-add function parameters in order to resolve copy constructors
+				// need to explicitly re-add function parameters to the indexer in order to resolve copy constructors
 				enterScope();
 				maybeAccept( function->get_functionType(), *this );
@@ -1055,5 +1054,8 @@
 					}
 					InitExpander srcParam( arg2 );
-					SymTab::genImplicitCall( srcParam, new MemberExpr( field, new VariableExpr( thisParam ) ), function->get_name(), back_inserter( stmt ), field, isCtor );
+					// cast away reference type and construct field.
+					Expression * thisExpr = new CastExpr( new VariableExpr( thisParam ), thisParam->get_type()->stripReferences()->clone() );
+					Expression * memberDest = new MemberExpr( field, thisExpr );
+					SymTab::genImplicitCall( srcParam, memberDest, function->get_name(), back_inserter( stmt ), field, isCtor );
 
 					assert( stmt.size() <= 1 );
@@ -1082,4 +1084,27 @@
 		}
 
+		/// true if expr is effectively just the 'this' parameter
+		bool isThisExpression( Expression * expr, DeclarationWithType * thisParam ) {
+			// TODO: there are more complicated ways to pass 'this' to a constructor, e.g. &*, *&, etc.
+			if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
+				return varExpr->get_var() == thisParam;
+			} else if ( CastExpr * castExpr = dynamic_cast< CastExpr * > ( expr ) ) {
+				return isThisExpression( castExpr->get_arg(), thisParam );
+			}
+			return false;
+		}
+
+		/// returns a MemberExpr if expr is effectively just member access on the 'this' parameter, else nullptr
+		MemberExpr * isThisMemberExpr( Expression * expr, DeclarationWithType * thisParam ) {
+			if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( expr ) ) {
+				if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
+					return memberExpr;
+				}
+			} else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
+				return isThisMemberExpr( castExpr->get_arg(), thisParam );
+			}
+			return nullptr;
+		}
+
 		void GenStructMemberCalls::visit( ApplicationExpr * appExpr ) {
 			if ( ! checkWarnings( function ) ) return;
@@ -1090,35 +1115,17 @@
 				Expression * firstParam = appExpr->get_args().front();
 
-				if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( firstParam ) ) {
+				if ( isThisExpression( firstParam, thisParam ) ) {
 					// if calling another constructor on thisParam, assume that function handles
 					// all members - if it doesn't a warning will appear in that function.
-					if ( varExpr->get_var() == thisParam ) {
-						unhandled.clear();
-					}
-				} else {
-					// if first parameter is a member expression then
-					// remove the member from unhandled set.
-					handleFirstParam( firstParam );
-				}
-			}
-
-			Parent::visit( appExpr );
-		}
-
-		void GenStructMemberCalls::handleFirstParam( Expression * firstParam ) {
-			using namespace std;
-			if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( firstParam ) ) {
-				if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( addrExpr->get_arg() ) ) {
-					if ( ApplicationExpr * deref = dynamic_cast< ApplicationExpr * >( memberExpr->get_aggregate() ) ) {
-						if ( getFunctionName( deref ) == "*?" && deref->get_args().size() == 1 ) {
-							if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( deref->get_args().front() ) ) {
-								if ( varExpr->get_var() == thisParam ) {
-									unhandled.erase( memberExpr->get_member() );
-								}
-							}
-						}
+					unhandled.clear();
+				} else if ( MemberExpr * memberExpr = isThisMemberExpr( firstParam, thisParam ) ) {
+					// if first parameter is a member expression on the this parameter,
+					// then remove the member from unhandled set.
+					if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
+						unhandled.erase( memberExpr->get_member() );
 					}
 				}
 			}
+			Parent::visit( appExpr );
 		}
 
@@ -1127,14 +1134,8 @@
 			if ( ! isCtor ) return;
 
-			if ( ApplicationExpr * deref = dynamic_cast< ApplicationExpr * >( memberExpr->get_aggregate() ) ) {
-				if ( getFunctionName( deref ) == "*?" && deref->get_args().size() == 1 ) {
-					if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( deref->get_args().front() ) ) {
-						if ( varExpr->get_var() == thisParam ) {
-							if ( unhandled.count( memberExpr->get_member() ) ) {
-								// emit a warning because a member was used before it was constructed
-								usedUninit.insert( { memberExpr->get_member(), memberExpr->location } );
-							}
-						}
-					}
+			if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
+				if ( unhandled.count( memberExpr->get_member() ) ) {
+					// emit a warning because a member was used before it was constructed
+					usedUninit.insert( { memberExpr->get_member(), memberExpr->location } );
 				}
 			}
