Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision c10ee66d0c4a079e4da1a33ec95eab1c8d49d061)
+++ src/GenPoly/Box.cc	(revision a0ad7dc9c1fb88ba2a6f635f0b103f2eb1380169)
@@ -765,8 +765,4 @@
 						arg = new AddressExpr( arg );
 					}
-					if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
-						// silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
-						arg = new CastExpr( arg, param->clone() );
-					}
 				} else {
 					// use type computed in unification to declare boxed variables
@@ -906,5 +902,6 @@
 				} // if
 				UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
-				UntypedExpr *deref = UntypedExpr::createDeref( new CastExpr( new VariableExpr( *param++ ), new PointerType( Type::Qualifiers(), realType->get_returnVals().front()->get_type()->clone() ) ) );
+				UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
+				deref->get_args().push_back( new CastExpr( new VariableExpr( *param++ ), new PointerType( Type::Qualifiers(), realType->get_returnVals().front()->get_type()->clone() ) ) );
 				assign->get_args().push_back( deref );
 				addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
@@ -1220,4 +1217,11 @@
 
 		Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
+			// maybe need access to the env when mutating the expr
+			if ( Expression * expr = returnStmt->get_expr() ) {
+				if ( expr->get_env() ) {
+					env = expr->get_env();
+				}
+			}
+
 			if ( retval && returnStmt->get_expr() ) {
 				assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );
@@ -1535,6 +1539,6 @@
 					Type *declType = objectDecl->get_type();
 					std::string bufName = bufNamer.newName();
-					ObjectDecl *newBuf = new ObjectDecl( bufName, Type::StorageClasses(), LinkageSpec::C, 0,
-						new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ),
+					ObjectDecl *newBuf = new ObjectDecl( bufName, Type::StorageClasses(), LinkageSpec::C, 0, 
+						new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ), 
 						true, false, std::list<Attribute*>{ new Attribute( std::string{"aligned"}, std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
 					stmtsToAdd.push_back( new DeclStmt( noLabels, newBuf ) );
@@ -1574,4 +1578,15 @@
 		}
 
+		/// Returns an expression dereferenced n times
+		Expression *makeDerefdVar( Expression *derefdVar, long n ) {
+			for ( int i = 1; i < n; ++i ) {
+				UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+				derefExpr->get_args().push_back( derefdVar );
+				// xxx - should set results on derefExpr
+				derefdVar = derefExpr;
+			}
+			return derefdVar;
+		}
+
 		Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
 			// mutate, exiting early if no longer MemberExpr
@@ -1580,7 +1595,14 @@
 			if ( ! memberExpr ) return expr;
 
+			// get declaration for base struct, exiting early if not found
+			int varDepth;
+			VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );
+			if ( ! varExpr ) return memberExpr;
+			ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
+			if ( ! objectDecl ) return memberExpr;
+
 			// only mutate member expressions for polymorphic types
 			int tyDepth;
-			Type *objectType = hasPolyBase( memberExpr->get_aggregate()->get_result(), scopeTyVars, &tyDepth );
+			Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
 			if ( ! objectType ) return memberExpr;
 			findGeneric( objectType ); // ensure layout for this type is available
@@ -1600,13 +1622,8 @@
 				fieldLoc->get_args().push_back( aggr );
 				fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
-				fieldLoc->set_result( memberExpr->get_result()->clone() );
 				newMemberExpr = fieldLoc;
 			} else if ( dynamic_cast< UnionInstType* >( objectType ) ) {
-				// union members are all at offset zero, so just use the aggregate expr
-				Expression * aggr = memberExpr->get_aggregate()->clone();
-				delete aggr->get_env(); // xxx - there's a problem with keeping the env for some reason, so for now just get rid of it
-				aggr->set_env( nullptr );
-				newMemberExpr = aggr;
-				newMemberExpr->set_result( memberExpr->get_result()->clone() );
+				// union members are all at offset zero, so build appropriately-dereferenced variable
+				newMemberExpr = makeDerefdVar( varExpr->clone(), varDepth );
 			} else return memberExpr;
 			assert( newMemberExpr );
@@ -1616,5 +1633,6 @@
 				// Not all members of a polymorphic type are themselves of polymorphic type; in this case the member expression should be wrapped and dereferenced to form an lvalue
 				CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), memberType->clone() ) );
-				UntypedExpr *derefExpr = UntypedExpr::createDeref( ptrCastExpr );
+				UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+				derefExpr->get_args().push_back( ptrCastExpr );
 				newMemberExpr = derefExpr;
 			}
