Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision ac633d0974fbb4e8ab841c7fa9c8a858292ba9da)
+++ src/GenPoly/Box.cc	(revision d1caa6c7aa23cd5f9211381edb88cec622650e22)
@@ -62,14 +62,15 @@
 		FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
 
-		/// Key for a unique concrete type; generic base type paired with type parameter list
-		struct ConcreteType {
-			ConcreteType() : base(NULL), params() {}
-
-			ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); }
-
-			ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
+		/// Abstracts type equality for a list of parameter types
+		struct TypeList {
+			TypeList() : params() {}
+			TypeList( const std::list< Type* > &_params ) : params() { cloneAll(_params, params); }
+			TypeList( std::list< Type* > &&_params ) : params( _params ) {}
+
+			TypeList( const TypeList &that ) : params() { cloneAll(that.params, params); }
+			TypeList( TypeList &&that ) : params( std::move( that.params ) ) {}
 
 			/// Extracts types from a list of TypeExpr*
-			ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
+			TypeList( const std::list< TypeExpr* >& _params ) : params() {
 				for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
 					params.push_back( (*param)->get_type()->clone() );
@@ -77,9 +78,8 @@
 			}
 
-			ConcreteType& operator= (const ConcreteType& that) {
+			TypeList& operator= ( const TypeList &that ) {
 				deleteAll( params );
+
 				params.clear();
-
-				base = that.base;
 				cloneAll( that.params, params );
 
@@ -87,11 +87,18 @@
 			}
 
-			~ConcreteType() { deleteAll( params ); }
-
-			bool operator== (const ConcreteType& that) const {
-				if ( base != that.base ) return false;
+			TypeList& operator= ( TypeList &&that ) {
+				deleteAll( params );
+
+				params = std::move( that.params );
+
+				return *this;
+			}
+
+			~TypeList() { deleteAll( params ); }
+
+			bool operator== ( const TypeList& that ) const {
+				if ( params.size() != that.params.size() ) return false;
 
 				SymTab::Indexer dummy;
-				if ( params.size() != that.params.size() ) return false;
 				for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
 					if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
@@ -100,21 +107,14 @@
 			}
 
-			AggregateDecl *base;        ///< Base generic type
 			std::list< Type* > params;  ///< Instantiation parameters
 		};
 
-		/// Maps a concrete type to the some value, accounting for scope
-		template< typename Value >
+		/// Maps a key and a TypeList to the some value, accounting for scope
+		template< typename Key, typename Value >
 		class InstantiationMap {
-			/// Information about a specific instantiation of a generic type
-			struct Instantiation {
-				ConcreteType key;  ///< Instantiation parameters for this type
-				Value *value;      ///< Value for this instantiation
-
-				Instantiation() : key(), value(0) {}
-				Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {}
-			};
-			/// Map of generic types to instantiations of them
-			typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
+			/// Wraps value for a specific (Key, TypeList) combination
+			typedef std::pair< TypeList, Value* > Instantiation;
+			/// Map of keys to instantiations of them
+			typedef std::map< Key*, std::vector< Instantiation > > Scope;
 
 			std::vector< Scope > scopes;  ///< list of scopes, from outermost to innermost
@@ -135,16 +135,16 @@
 			InstantiationMap() { beginScope(); }
 
-			/// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
-			/// Returns NULL on none such.
-			Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
-				ConcreteType key(generic, params);
+			/// Gets the value for the (key, typeList) pair, returns NULL on none such.
+			Value *lookup( Key *key, const std::list< TypeExpr* >& params ) {
+				TypeList typeList( params );
+				
 				// scan scopes from innermost out
 				for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {
-					// skip scope if no instantiations of this generic type
-					typename Scope::const_iterator insts = scope->find( generic );
+					// skip scope if nothing for this key
+					typename Scope::const_iterator insts = scope->find( key );
 					if ( insts == scope->end() ) continue;
-					// look through instantiations for matches to concrete type
+					// look through instantiations for matches to typeList
 					for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
-						if ( inst->key == key ) return inst->value;
+						if ( inst->first == typeList ) return inst->second;
 					}
 				}
@@ -153,8 +153,7 @@
 			}
 
-			/// Adds a value for a concrete type to the current scope
-			void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, Value *value ) {
-				ConcreteType key(generic, params);
-				scopes.back()[generic].push_back( Instantiation( key, value ) );
+			/// Adds a value for a (key, typeList) pair to the current scope
+			void insert( Key *key, const std::list< TypeExpr* > &params, Value *value ) {
+				scopes.back()[key].push_back( Instantiation( TypeList( params ), value ) );
 			}
 		};
@@ -245,5 +244,5 @@
 		class GenericInstantiator : public DeclMutator {
 			/// Map of (generic type, parameter list) pairs to concrete type instantiations
-			InstantiationMap< AggregateDecl > instantiations;
+			InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
 			/// Namer for concrete types
 			UniqueName typeNamer;
