Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 6d160d71b3de65956bb910618eeea262ad595278)
+++ src/GenPoly/Box.cc	(revision 8488c7158d4a96b08115d10483367b9b57836905)
@@ -1290,5 +1290,6 @@
 
 			// get declaration for base struct, exiting early if not found
-			VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate() );
+			int varDepth;
+			VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );
 			if ( ! varExpr ) return memberExpr;
 			ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
@@ -1296,5 +1297,6 @@
 
 			// only mutate member expressions for polymorphic types
-			Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars );
+			int tyDepth;
+			Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
 			if ( ! objectType ) return memberExpr;
 
@@ -1323,5 +1325,5 @@
 
 			// replace member expression with pointer to base plus offset
-			// this is in a polymorphic context, so maybe keeping it as a void* is fine?
+			// get offset for field
 			std::stringstream offset_namer;
 			offset_namer << i;
@@ -1330,9 +1332,16 @@
 			fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
 			fieldOffset->get_args().push_back( fieldIndex );
+			// build appropriately-dereferenced variable
+			Expression *derefdVar = varExpr->clone();
+			for ( int i = 1; i < varDepth; ++i ) {
+				UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+				derefExpr->get_args().push_back( derefdVar );
+				derefdVar = derefExpr;
+			}
+			// add offset to deref'd variable
 			UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
-			fieldLoc->get_args().push_back( memberExpr->get_aggregate() );
+			fieldLoc->get_args().push_back( derefdVar );
 			fieldLoc->get_args().push_back( fieldOffset );
 
-			memberExpr->set_aggregate( 0 );
 			delete memberExpr;
 			return fieldLoc;
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 6d160d71b3de65956bb910618eeea262ad595278)
+++ src/GenPoly/GenPoly.cc	(revision 8488c7158d4a96b08115d10483367b9b57836905)
@@ -127,13 +127,20 @@
 	}
 
-	Type *hasPolyBase( Type *type, const TypeSubstitution *env ) {
-		if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
-			return hasPolyBase( ptr->get_base(), env );
-		} else if ( env ) {
-			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
-				if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
-					return hasPolyBase( newType, env );
-				} // if
-			} // if
+	Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) {
+		int dummy;
+		if ( ! levels ) { levels = &dummy; }
+		*levels = 0;
+
+		while ( true ) {
+			if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
+				type = ptr->get_base();
+				++(*levels);
+			} else if ( env ) {
+				if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
+					if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
+						type = newType;
+					} else break;
+				} else break;
+			} else break;
 		}
 
@@ -141,13 +148,20 @@
 	}
 	
-	Type *hasPolyBase( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
-		if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
-			return hasPolyBase( ptr->get_base(), tyVars, env );
-		} else if ( env ) {
-			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
-				if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
-					return hasPolyBase( newType, tyVars, env );
-				} // if
-			} // if
+	Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {
+		int dummy;
+		if ( ! levels ) { levels = &dummy; }
+		*levels = 0;
+
+		while ( true ) {
+			if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
+				type = ptr->get_base();
+				++(*levels);
+			} else if ( env ) {
+				if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
+					if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
+						type = newType;
+					} else break;
+				} else break;
+			} else break;
 		}
 
@@ -164,16 +178,25 @@
 	}
 
-	VariableExpr *getBaseVar( Expression *expr ) {
-		if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
-			// found the variable directly
-			return varExpr;
-		} else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) {
-			return getBaseVar( addressExpr->get_arg() );
-		} else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
-			// look for compiler-inserted dereference operator
-			NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
-			if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
-			return getBaseVar( *untypedExpr->begin_args() );
-		} else return 0;
+	VariableExpr * getBaseVar( Expression *expr, int *levels ) {
+		int dummy;
+		if ( ! levels ) { levels = &dummy; }
+		*levels = 0;
+
+		while ( true ) {
+			if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
+				return varExpr;
+			} else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) {
+				expr = addressExpr->get_arg();
+			} else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
+				// look for compiler-inserted dereference operator
+				NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
+				if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
+				expr = *untypedExpr->begin_args();
+			} else break;
+
+			++(*levels);
+		}
+
+		return 0;
 	}
 
Index: src/GenPoly/GenPoly.h
===================================================================
--- src/GenPoly/GenPoly.h	(revision 6d160d71b3de65956bb910618eeea262ad595278)
+++ src/GenPoly/GenPoly.h	(revision 8488c7158d4a96b08115d10483367b9b57836905)
@@ -20,4 +20,5 @@
 #include <string>
 #include <iostream>
+#include <utility>
 
 #include "SynTree/Declaration.h"
@@ -47,17 +48,18 @@
 	Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
 
-	/// returns polymorphic base type if the base type (after dereferencing any number of pointers) is a polymorphic type, NULL otherwise;
-	/// will look up substitution in env if provided
-	Type *hasPolyBase( Type *type, const TypeSubstitution *env = 0 );
+	/// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise;
+	/// N will be stored in levels, if provided, will look up substitution in env if provided
+	Type *hasPolyBase( Type *type, int *levels = 0, const TypeSubstitution *env = 0 );
 
-	/// returns polymorphic base type if the base type (after dereferencing any number of pointers) is a polymorphic type in tyVars, NULL otherwise;
-	/// will look up substitution in env if provided
-	Type *hasPolyBase( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
+	/// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type in tyVars, returns the base type, NULL otherwise;
+	/// N will be stored in levels, if provided, will look up substitution in env if provided
+	Type *hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels = 0, const TypeSubstitution *env = 0 );
 
 	/// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
 	FunctionType *getFunctionType( Type *ty );
 
-	/// Returns the base variable (possibly repeatedly dereferenced) for an expression, NULL if none found
-	VariableExpr *getBaseVar( Expression *expr );
+	/// If expr (after dereferencing N >= 0 pointers) is a variable expression, returns the variable expression, NULL otherwise;
+	/// N will be stored in levels, if provided
+	VariableExpr *getBaseVar( Expression *expr, int *levels = 0 );
 
 	/// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
