Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision c6976ba09dbc5ab56dc1e9bf723a722048efdd57)
+++ src/CodeGen/CodeGenerator.cc	(revision 0a81c3fa5fe8fdf6e54bc612620b22c7c9342e8d)
@@ -338,35 +338,4 @@
 			if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
 				std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
-				switch ( opInfo.type ) {
-				  case OT_PREFIXASSIGN:
-				  case OT_POSTFIXASSIGN:
-				  case OT_INFIXASSIGN:
-				  case OT_CTOR:
-				  case OT_DTOR:
-					{
-						assert( arg != applicationExpr->get_args().end() );
-						if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
-							// remove & from first assignment/ctor argument
-							*arg = addrExpr->get_arg();
-						} else {
-							// no address-of operator, so must be a pointer - add dereference
-							// NOTE: if the assertion starts to trigger, check that the application expr isn't being shared.
-							// Since its arguments are modified here, this assertion most commonly triggers when the application
-							// is visited multiple times.
-							UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) );
-							newExpr->get_args().push_back( *arg );
-							Type * type = InitTweak::getPointerBase( (*arg)->get_result() );
-							assertf( type, "First argument to a derefence must be a pointer. Ensure that expressions are not being shared." );
-							newExpr->set_result( type->clone() );
-							*arg = newExpr;
-						} // if
-						break;
-					}
-
-				  default:
-					// do nothing
-					;
-				} // switch
-
 				switch ( opInfo.type ) {
 				  case OT_INDEX:
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision c6976ba09dbc5ab56dc1e9bf723a722048efdd57)
+++ src/GenPoly/Box.cc	(revision 0a81c3fa5fe8fdf6e54bc612620b22c7c9342e8d)
@@ -758,5 +758,6 @@
 					// if the argument's type is polymorphic, we don't need to box again!
 					return;
-				} else if ( arg->get_result()->get_lvalue() ) {
+				} else if ( arg->get_result()->get_lvalue() ) {  // xxx - is this still right??
+				// xxx - dynamic_cast<ReferenceType *>( arg->get_result() )??
 					// VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
 					// xxx - need to test that this code is still reachable
@@ -1036,5 +1037,6 @@
 						assert( appExpr->has_result() );
 						assert( ! appExpr->get_args().empty() );
-						if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
+						if ( isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { // dereference returns a reference type
+							// remove dereference from polymorphic types since they are boxed.
 							Expression *ret = appExpr->get_args().front();
 							delete ret->get_result();
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision c6976ba09dbc5ab56dc1e9bf723a722048efdd57)
+++ src/InitTweak/FixInit.cc	(revision 0a81c3fa5fe8fdf6e54bc612620b22c7c9342e8d)
@@ -364,9 +364,9 @@
 					assert( ftype );
 					if ( isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) {
-						Type * t1 = ftype->get_parameters().front()->get_type();
+						Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
 						Type * t2 = ftype->get_parameters().back()->get_type();
-						PointerType * ptrType = safe_dynamic_cast< PointerType * > ( t1 );
-
-						if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) {
+						assert( t1 );
+
+						if ( ResolvExpr::typesCompatible( t1, t2, SymTab::Indexer() ) ) {
 							// optimization: don't need to copy construct in order to call a copy constructor
 							return appExpr;
@@ -489,5 +489,5 @@
 				impCpCtorExpr->get_returnDecls().push_back( ret );
 				CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
-				if ( ! result->get_lvalue() ) {
+				if ( ! dynamic_cast< ReferenceType * >( result ) ) {
 					// destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
 					destructRet( ret, impCpCtorExpr );
@@ -997,6 +997,6 @@
 				assert( ! type->get_parameters().empty() );
 				thisParam = safe_dynamic_cast< ObjectDecl * >( type->get_parameters().front() );
-				PointerType * ptrType = safe_dynamic_cast< PointerType * > ( thisParam->get_type() );
-				StructInstType * structType = dynamic_cast< StructInstType * >( ptrType->get_base() );
+				Type * thisType = getPointerBase( thisParam->get_type() );
+				StructInstType * structType = dynamic_cast< StructInstType * >( thisType );
 				if ( structType ) {
 					structDecl = structType->get_baseStruct();
@@ -1046,6 +1046,4 @@
 					// insert and resolve default/copy constructor call for each field that's unhandled
 					std::list< Statement * > stmt;
-					UntypedExpr * deref = UntypedExpr::createDeref( new VariableExpr( thisParam ) );
-
 					Expression * arg2 = 0;
 					if ( isCopyConstructor( function ) ) {
@@ -1056,5 +1054,5 @@
 					}
 					InitExpander srcParam( arg2 );
-					SymTab::genImplicitCall( srcParam, new MemberExpr( field, deref ), function->get_name(), back_inserter( stmt ), field, isCtor );
+					SymTab::genImplicitCall( srcParam, new MemberExpr( field, new VariableExpr( thisParam ) ), function->get_name(), back_inserter( stmt ), field, isCtor );
 
 					assert( stmt.size() <= 1 );
