Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 44547b021e0a0a8176807a187bc5c1c80a63e39b)
+++ src/GenPoly/Box.cc	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -58,5 +58,5 @@
 namespace GenPoly {
 	namespace {
-		FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
+		FunctionType *makeAdapterType( FunctionType const *adaptee, const TyVarMap &tyVars );
 
 		class BoxPass {
@@ -124,5 +124,5 @@
 			/// `mangleName` as the base name for the adapter. `tyVars` is the map of
 			/// type variables for the function type of the adapted expression.
-			FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
+			FunctionDecl *makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
 			/// Replaces intrinsic operator functions with their arithmetic desugaring
 			Expression *handleIntrinsics( ApplicationExpr *appExpr );
@@ -190,5 +190,5 @@
 			ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 );
 			/// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns
-			bool findGeneric( Type *ty );
+			bool findGeneric( Type const *ty );
 			/// adds type parameters to the layout call; will generate the appropriate parameters if needed
 			void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );
@@ -426,5 +426,5 @@
 
 	namespace {
-		std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {
+		std::string makePolyMonoSuffix( FunctionType const * function, const TyVarMap &tyVars ) {
 			std::stringstream name;
 
@@ -435,5 +435,5 @@
 			// to take those polymorphic types as pointers. Therefore, there can be two different functions
 			// with the same mangled name, so we need to further mangle the names.
-			for ( DeclarationWithType * const ret : function->get_returnVals() ) {
+			for ( DeclarationWithType const * const ret : function->returnVals ) {
 				if ( isPolyType( ret->get_type(), tyVars ) ) {
 					name << "P";
@@ -443,5 +443,5 @@
 			}
 			name << "_";
-			for ( DeclarationWithType * const arg : function->get_parameters() ) {
+			for ( DeclarationWithType const * const arg : function->parameters ) {
 				if ( isPolyType( arg->get_type(), tyVars ) ) {
 					name << "P";
@@ -453,5 +453,5 @@
 		}
 
-		std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {
+		std::string mangleAdapterName( FunctionType const * function, const TyVarMap &tyVars ) {
 			return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars );
 		}
@@ -489,5 +489,5 @@
 
 				std::list< DeclarationWithType *> &paramList = functionType->parameters;
-				std::list< FunctionType *> functions;
+				std::list< FunctionType const *> functions;
 				for ( TypeDecl * const tyVar : functionType->forall ) {
 					for ( DeclarationWithType * const assert : tyVar->assertions ) {
@@ -499,5 +499,5 @@
 				} // for
 
-				for ( FunctionType * const funType : functions ) {
+				for ( FunctionType const * const funType : functions ) {
 					std::string mangleName = mangleAdapterName( funType, scopeTyVars );
 					if ( adapters.find( mangleName ) == adapters.end() ) {
@@ -794,5 +794,5 @@
 		}
 
-		FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {
+		FunctionType *makeAdapterType( FunctionType const *adaptee, const TyVarMap &tyVars ) {
 			// actually make the adapter type
 			FunctionType *adapter = adaptee->clone();
@@ -804,5 +804,9 @@
 		}
 
-		Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) {
+		Expression *makeAdapterArg(
+				DeclarationWithType *param,
+				DeclarationWithType const *arg,
+				DeclarationWithType const *realParam,
+				const TyVarMap &tyVars ) {
 			assert( param );
 			assert( arg );
@@ -817,5 +821,11 @@
 		}
 
-		void addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType *>::iterator arg, std::list< DeclarationWithType *>::iterator param, std::list< DeclarationWithType *>::iterator paramEnd, std::list< DeclarationWithType *>::iterator realParam, const TyVarMap &tyVars ) {
+		void addAdapterParams(
+				ApplicationExpr *adapteeApp,
+				std::list< DeclarationWithType *>::const_iterator arg,
+				std::list< DeclarationWithType *>::const_iterator param,
+				std::list< DeclarationWithType *>::const_iterator paramEnd,
+				std::list< DeclarationWithType *>::const_iterator realParam,
+				const TyVarMap &tyVars ) {
 			UniqueName paramNamer( "_p" );
 			for ( ; param != paramEnd; ++param, ++arg, ++realParam ) {
@@ -828,5 +838,5 @@
 		}
 
-		FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
+		FunctionDecl *Pass1::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {
 			FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
 			adapterType = ScrubTyVars::scrub( adapterType, tyVars );
@@ -845,12 +855,12 @@
 			Statement *bodyStmt;
 
-			Type::ForallList::iterator tyArg = realType->get_forall().begin();
-			Type::ForallList::iterator tyParam = adapterType->get_forall().begin();
-			Type::ForallList::iterator realTyParam = adaptee->get_forall().begin();
+			Type::ForallList::const_iterator tyArg = realType->forall.begin();
+			Type::ForallList::const_iterator tyParam = adapterType->forall.begin();
+			Type::ForallList::const_iterator realTyParam = adaptee->forall.begin();
 			for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) {
 				assert( tyArg != realType->get_forall().end() );
-				std::list< DeclarationWithType *>::iterator assertArg = (*tyArg)->get_assertions().begin();
-				std::list< DeclarationWithType *>::iterator assertParam = (*tyParam)->get_assertions().begin();
-				std::list< DeclarationWithType *>::iterator realAssertParam = (*realTyParam)->get_assertions().begin();
+				std::list< DeclarationWithType *>::const_iterator assertArg = (*tyArg)->get_assertions().begin();
+				std::list< DeclarationWithType *>::const_iterator assertParam = (*tyParam)->get_assertions().begin();
+				std::list< DeclarationWithType *>::const_iterator realAssertParam = (*realTyParam)->get_assertions().begin();
 				for ( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) {
 					assert( assertArg != (*tyArg)->get_assertions().end() );
@@ -859,7 +869,7 @@
 			} // for
 
-			std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin();
-			std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
-			std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin();
+			std::list< DeclarationWithType *>::const_iterator arg = realType->parameters.begin();
+			std::list< DeclarationWithType *>::const_iterator param = adapterType->parameters.begin();
+			std::list< DeclarationWithType *>::const_iterator realParam = adaptee->parameters.begin();
 			param++;		// skip adaptee parameter in the adapter type
 			if ( realType->get_returnVals().empty() ) {
@@ -867,5 +877,5 @@
 				addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
 				bodyStmt = new ExprStmt( adapteeApp );
-			} else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
+			} else if ( isDynType( adaptee->returnVals.front()->get_type(), tyVars ) ) {
 				// return type T
 				if ( (*param)->get_name() == "" ) {
@@ -892,5 +902,5 @@
 		void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) {
 			// collect a list of function types passed as parameters or implicit parameters (assertions)
-			std::list< FunctionType*> functions;
+			std::list<FunctionType const *> functions;
 			for ( TypeDecl * const tyVar : functionType->get_forall() ) {
 				for ( DeclarationWithType * const assert : tyVar->get_assertions() ) {
@@ -906,5 +916,5 @@
 			std::set< std::string > adaptersDone;
 
-			for ( FunctionType * const funType : functions ) {
+			for ( FunctionType const * const funType : functions ) {
 				FunctionType *originalFunction = funType->clone();
 				FunctionType *realFunction = funType->clone();
@@ -940,10 +950,5 @@
 
 		Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
-			NameExpr *opExpr;
-			if ( isIncr ) {
-				opExpr = new NameExpr( "?+=?" );
-			} else {
-				opExpr = new NameExpr( "?-=?" );
-			} // if
+			NameExpr *opExpr = new NameExpr( ( isIncr ) ? "?+=?" : "?-=?" );
 			UntypedExpr *addAssign = new UntypedExpr( opExpr );
 			if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) {
@@ -1146,7 +1151,7 @@
 		}
 
-		bool isPolyDeref( UntypedExpr * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) {
+		bool isPolyDeref( UntypedExpr const * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) {
 			if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
-				if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
+				if ( auto name = dynamic_cast<NameExpr const *>( expr->function ) ) {
 					if ( name->name == "*?" ) {
 						return true;
@@ -1229,5 +1234,5 @@
 		void Pass2::addAdapters( FunctionType *functionType ) {
 			std::list< DeclarationWithType *> &paramList = functionType->parameters;
-			std::list< FunctionType *> functions;
+			std::list< FunctionType const *> functions;
 			for ( DeclarationWithType * const arg : functionType->parameters ) {
 				Type *orig = arg->get_type();
@@ -1236,5 +1241,5 @@
 			}
 			std::set< std::string > adaptersDone;
-			for ( FunctionType * const funType : functions ) {
+			for ( FunctionType const * const funType : functions ) {
 				std::string mangleName = mangleAdapterName( funType, scopeTyVars );
 				if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
@@ -1471,5 +1476,5 @@
 
 		/// converts polymorphic type T into a suitable monomorphic representation, currently: __attribute__((aligned(8)) char[size_T]
-		Type * polyToMonoType( Type * declType ) {
+		Type * polyToMonoType( Type const * declType ) {
 			Type * charType = new BasicType( Type::Qualifiers(), BasicType::Kind::Char);
 			Expression * size = new NameExpr( sizeofName( mangleType(declType) ) );
@@ -1568,5 +1573,5 @@
 
 		/// Returns an index expression into the offset array for a type
-		Expression *makeOffsetIndex( Type *objectType, long i ) {
+		Expression *makeOffsetIndex( Type const *objectType, long i ) {
 			ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) );
 			UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
@@ -1675,5 +1680,5 @@
 
 		/// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list
-		bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) {
+		bool findGenericParams( std::list< TypeDecl* > const &baseParams, std::list< Expression* > const &typeParams, std::list< Type* > &out ) {
 			bool hasDynamicLayout = false;
 
@@ -1695,8 +1700,8 @@
 		}
 
-		bool PolyGenericCalculator::findGeneric( Type *ty ) {
+		bool PolyGenericCalculator::findGeneric( Type const *ty ) {
 			ty = replaceTypeInst( ty, env );
 
-			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
+			if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) {
 				if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
 					// NOTE assumes here that getting put in the scopeTyVars included having the layout variables set
@@ -1704,5 +1709,5 @@
 				}
 				return false;
-			} else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {
+			} else if ( auto structTy = dynamic_cast< StructInstType const * >( ty ) ) {
 				// check if this type already has a layout generated for it
 				std::string typeName = mangleType( ty );
@@ -1711,5 +1716,5 @@
 				// check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
 				std::list< Type* > otypeParams;
-				if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false;
+				if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->parameters, otypeParams ) ) return false;
 
 				// insert local variables for layout and generate call to layout function
@@ -1741,5 +1746,5 @@
 
 				return true;
-			} else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
+			} else if ( auto unionTy = dynamic_cast< UnionInstType const * >( ty ) ) {
 				// check if this type already has a layout generated for it
 				std::string typeName = mangleType( ty );
@@ -1748,5 +1753,5 @@
 				// check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
 				std::list< Type* > otypeParams;
-				if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false;
+				if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->parameters, otypeParams ) ) return false;
 
 				// insert local variables for layout and generate call to layout function
Index: src/GenPoly/FindFunction.cc
===================================================================
--- src/GenPoly/FindFunction.cc	(revision 44547b021e0a0a8176807a187bc5c1c80a63e39b)
+++ src/GenPoly/FindFunction.cc	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -29,5 +29,5 @@
 	class FindFunction : public WithGuards, public WithVisitorRef<FindFunction>, public WithShortCircuiting {
 	  public:
-		FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate );
+		FindFunction( std::list< FunctionType const* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate );
 
 		void premutate( FunctionType * functionType );
@@ -37,5 +37,5 @@
 		void handleForall( const Type::ForallList &forall );
 
-		std::list< FunctionType* > &functions;
+		std::list< FunctionType const * > & functions;
 		TyVarMap tyVars;
 		bool replaceMode;
@@ -43,15 +43,15 @@
 	};
 
-	void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) {
+	void findFunction( Type *type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) {
 		PassVisitor<FindFunction> finder( functions, tyVars, false, predicate );
 		type->acceptMutator( finder );
 	}
 
-	void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) {
+	void findAndReplaceFunction( Type *&type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) {
 		PassVisitor<FindFunction> finder( functions, tyVars, true, predicate );
 		type = type->acceptMutator( finder );
 	}
 
-	FindFunction::FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate )
+	FindFunction::FindFunction( std::list< FunctionType const * > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate )
 		: functions( functions ), tyVars( tyVars ), replaceMode( replaceMode ), predicate( predicate ) {
 	}
Index: src/GenPoly/FindFunction.h
===================================================================
--- src/GenPoly/FindFunction.h	(revision 44547b021e0a0a8176807a187bc5c1c80a63e39b)
+++ src/GenPoly/FindFunction.h	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -27,7 +27,7 @@
 
 	/// recursively walk `type`, placing all functions that match `predicate` under `tyVars` into `functions`
-	void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
+	void findFunction( Type *type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
 	/// like `findFunction`, but also replaces the function type with void ()(void)
-	void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
+	void findAndReplaceFunction( Type *&type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
 } // namespace GenPoly
 
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 44547b021e0a0a8176807a187bc5c1c80a63e39b)
+++ src/GenPoly/GenPoly.cc	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -112,4 +112,13 @@
 		if ( ! env ) return type;
 		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
+			Type *newType = env->lookup( typeInst->get_name() );
+			if ( newType ) return newType;
+		}
+		return type;
+	}
+
+	const Type* replaceTypeInst( const Type* type, const TypeSubstitution* env ) {
+		if ( ! env ) return type;
+		if ( auto typeInst = dynamic_cast< const TypeInstType* >( type ) ) {
 			Type *newType = env->lookup( typeInst->get_name() );
 			if ( newType ) return newType;
Index: src/GenPoly/GenPoly.h
===================================================================
--- src/GenPoly/GenPoly.h	(revision 44547b021e0a0a8176807a187bc5c1c80a63e39b)
+++ src/GenPoly/GenPoly.h	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -34,4 +34,5 @@
 	/// Replaces a TypeInstType by its referrent in the environment, if applicable
 	Type* replaceTypeInst( Type* type, const TypeSubstitution* env );
+	const Type* replaceTypeInst( const Type* type, const TypeSubstitution* env );
 	const ast::Type * replaceTypeInst( const ast::Type *, const ast::TypeSubstitution * );
 
@@ -116,5 +117,5 @@
 
 	/// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType().
-	inline std::string mangleType( Type *ty ) { return SymTab::Mangler::mangleType( ty ); }
+	inline std::string mangleType( const Type *ty ) { return SymTab::Mangler::mangleType( ty ); }
 
 	/// Gets the name of the sizeof parameter for the type, given its mangled name
