Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 1d7609346873ee72ada94a9702d5eca9232cd625)
+++ src/ResolvExpr/CastCost.cc	(revision 7870799883ca946218c97fb6a189d1da90a16e8e)
@@ -37,15 +37,15 @@
 	struct CastCost_old : public ConversionCost {
 	  public:
-		CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
+		CastCost_old( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
 
 		using ConversionCost::previsit;
 		using ConversionCost::postvisit;
-		void postvisit( BasicType * basicType );
-		void postvisit( PointerType * pointerType );
+		void postvisit( const BasicType * basicType );
+		void postvisit( const PointerType * pointerType );
 	};
 
-	Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
-		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+	Cost castCost( const Type *src, const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+		if ( const TypeInstType *destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
+			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
 				if ( eqvClass->type ) {
 					return castCost( src, eqvClass->type, indexer, env );
@@ -53,7 +53,7 @@
 					return Cost::infinity;
 				}
-			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) {
+			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
 				// all typedefs should be gone by this point
-				TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );
+				const TypeDecl * type = strict_dynamic_cast< const TypeDecl* >( namedType );
 				if ( type->base ) {
 					return castCost( src, type->base, indexer, env ) + Cost::safe;
@@ -74,15 +74,15 @@
 			PRINT( std::cerr << "compatible!" << std::endl; )
 			return Cost::zero;
-		} else if ( dynamic_cast< VoidType* >( dest ) ) {
+		} else if ( dynamic_cast< const VoidType* >( dest ) ) {
 			return Cost::safe;
-		} else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
+		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
 			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
+			return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
 				return ptrsCastable( t1, t2, env, indexer );
 			});
 		} else {
-			PassVisitor<CastCost_old> converter( 
-				dest, indexer, env, 
-				(Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & ))
+			PassVisitor<CastCost_old> converter(
+				dest, indexer, env,
+				(Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & ))
 					castCost );
 			src->accept( converter );
@@ -96,10 +96,10 @@
 	}
 
-	CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
+	CastCost_old::CastCost_old( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
 		: ConversionCost( dest, indexer, env, costFunc ) {
 	}
 
-	void CastCost_old::postvisit( BasicType *basicType ) {
-		PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
+	void CastCost_old::postvisit( const BasicType *basicType ) {
+		const PointerType *destAsPointer = dynamic_cast< const PointerType* >( dest );
 		if ( destAsPointer && basicType->isInteger() ) {
 			// necessary for, e.g. unsigned long => void*
@@ -110,7 +110,7 @@
 	}
 
-	void CastCost_old::postvisit( PointerType *pointerType ) {
-		if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
-			if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
+	void CastCost_old::postvisit( const PointerType *pointerType ) {
+		if ( const PointerType *destAsPtr = dynamic_cast< const PointerType* >( dest ) ) {
+			if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
 				cost = Cost::safe;
 			} else {
@@ -125,5 +125,5 @@
 				} // if
 			} // if
-		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
+		} else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
 			if ( destAsBasic->isInteger() ) {
 				// necessary for, e.g. void* => unsigned long
@@ -138,6 +138,6 @@
 		using ConversionCost_new::postvisit;
 
-		CastCost_new( 
-			const ast::Type * dst, const ast::SymbolTable & symtab, 
+		CastCost_new(
+			const ast::Type * dst, const ast::SymbolTable & symtab,
 			const ast::TypeEnvironment & env, CostCalculation costFunc )
 		: ConversionCost_new( dst, symtab, env, costFunc ) {}
@@ -182,7 +182,7 @@
 } // anonymous namespace
 
-Cost castCost( 
-	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
-	const ast::TypeEnvironment & env 
+Cost castCost(
+	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
+	const ast::TypeEnvironment & env
 ) {
 	if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
@@ -220,8 +220,8 @@
 		PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
 		#warning cast on ptrsCastable artifact of having two functions, remove when port done
-		return convertToReferenceCost( 
-			src, refType, symtab, env, 
-			( int (*)( 
-				const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
+		return convertToReferenceCost(
+			src, refType, symtab, env,
+			( int (*)(
+				const ast::Type *, const ast::Type *, const ast::SymbolTable &,
 				const ast::TypeEnvironment & )
 			) ptrsCastable );
@@ -229,7 +229,7 @@
 		#warning cast on castCost artifact of having two functions, remove when port done
 		ast::Pass< CastCost_new > converter{
-			dst, symtab, env, 
-			( Cost (*)( 
-				const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
+			dst, symtab, env,
+			( Cost (*)(
+				const ast::Type *, const ast::Type *, const ast::SymbolTable &,
 				const ast::TypeEnvironment & )
 			) castCost };
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 1d7609346873ee72ada94a9702d5eca9232cd625)
+++ src/ResolvExpr/ConversionCost.cc	(revision 7870799883ca946218c97fb6a189d1da90a16e8e)
@@ -46,6 +46,6 @@
 #endif
 
-	Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
-		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
+	Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
 			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
@@ -55,7 +55,7 @@
 					return Cost::infinity;
 				}
-			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
+			} else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
 				PRINT( std::cerr << " found" << std::endl; )
-				TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
+				const TypeDecl *type = dynamic_cast< const TypeDecl* >( namedType );
 				// all typedefs should be gone by this point
 				assert( type );
@@ -77,15 +77,15 @@
 			PRINT( std::cerr << "compatible!" << std::endl; )
 			return Cost::zero;
-		} else if ( dynamic_cast< VoidType* >( dest ) ) {
+		} else if ( dynamic_cast< const VoidType * >( dest ) ) {
 			return Cost::safe;
-		} else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
+		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
 			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
+			return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
 				return ptrsAssignable( t1, t2, env );
 			});
 		} else {
-			PassVisitor<ConversionCost> converter( 
-				dest, indexer, env, 
-				(Cost (*)(Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))
+			PassVisitor<ConversionCost> converter(
+				dest, indexer, env,
+				(Cost (*)(const Type*, const Type*, const SymTab::Indexer&, const TypeEnvironment&))
 					conversionCost );
 			src->accept( converter );
@@ -98,23 +98,23 @@
 	}
 
-	Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
+	Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
 		PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
 		if ( diff > 0 ) {
 			// TODO: document this
-			Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
+			Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
 			cost.incReference();
 			return cost;
 		} else if ( diff < -1 ) {
 			// TODO: document this
-			Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
+			Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func );
 			cost.incReference();
 			return cost;
 		} else if ( diff == 0 ) {
-			ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
-			ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
+			const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src );
+			const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
 			if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
 				PRINT( std::cerr << "converting between references" << std::endl; )
-				Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
-				Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
+				Type::Qualifiers tq1 = srcAsRef->base->tq;
+				Type::Qualifiers tq2 = destAsRef->base->tq;
 				if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
 					PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
@@ -137,7 +137,7 @@
 			} else {
 				PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
-				PassVisitor<ConversionCost> converter( 
-					dest, indexer, env, 
-					(Cost (*)(Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))
+				PassVisitor<ConversionCost> converter(
+					dest, indexer, env,
+					(Cost (*)(const Type*, const Type*, const SymTab::Indexer&, const TypeEnvironment&))
 						conversionCost );
 				src->accept( converter );
@@ -145,5 +145,5 @@
 			} // if
 		} else {
-			ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
+			const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
 			assert( diff == -1 && destAsRef );
 			PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
@@ -156,7 +156,7 @@
 					)
 					// lvalue-to-reference conversion:  cv lvalue T => cv T &
-					if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
+					if ( src->tq == destAsRef->base->tq ) {
 						return Cost::reference; // cost needs to be non-zero to add cast
-					} if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
+					} if ( src->tq < destAsRef->base->tq ) {
 						return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
 					} else {
@@ -178,5 +178,5 @@
 	}
 
-	Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
+	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
 		int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
 		Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
@@ -185,5 +185,5 @@
 	}
 
-	ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
+	ConversionCost::ConversionCost( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
 		: dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
 	}
@@ -193,22 +193,22 @@
 	/* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
 	                         _Bool
-	char                signed char         unsigned char       
-	          signed short int         unsigned short int       
-	          signed int               unsigned int             
-	          signed long int          unsigned long int        
-	          signed long long int     unsigned long long int   
-	          __int128                 unsigned __int128        
-	          _Float16                 _Float16 _Complex        
-	          _Float32                 _Float32 _Complex        
-	          float                    float _Complex           
-	          _Float32x                _Float32x _Complex       
-	          _Float64                 _Float64 _Complex        
-	          double                   double _Complex          
-	          _Float64x                _Float64x _Complex       
+	char                signed char         unsigned char
+	          signed short int         unsigned short int
+	          signed int               unsigned int
+	          signed long int          unsigned long int
+	          signed long long int     unsigned long long int
+	          __int128                 unsigned __int128
+	          _Float16                 _Float16 _Complex
+	          _Float32                 _Float32 _Complex
+	          float                    float _Complex
+	          _Float32x                _Float32x _Complex
+	          _Float64                 _Float64 _Complex
+	          double                   double _Complex
+	          _Float64x                _Float64x _Complex
 	                     __float80
-	          _Float128                _Float128 _Complex       
+	          _Float128                _Float128 _Complex
 	                    __float128
-	          long double              long double _Complex     
-	          _Float128x               _Float128x _Complex      
+	          long double              long double _Complex
+	          _Float128x               _Float128x _Complex
 	*/
 	// GENERATED END
@@ -309,11 +309,11 @@
 	);
 
-	void ConversionCost::postvisit( VoidType * ) {
+	void ConversionCost::postvisit( const VoidType * ) {
 		cost = Cost::infinity;
 	}
 
-	void ConversionCost::postvisit(BasicType *basicType) {
-		if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
-			int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
+	void ConversionCost::postvisit(const BasicType *basicType) {
+		if ( const BasicType * destAsBasic = dynamic_cast< const BasicType* >( dest ) ) {
+			int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ];
 			if ( tableResult == -1 ) {
 				cost = Cost::unsafe;
@@ -321,7 +321,7 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult );
-				cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
-			} // if
-		} else if ( dynamic_cast< EnumInstType *>( dest ) ) {
+				cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] );
+			} // if
+		} else if ( dynamic_cast< const EnumInstType * >( dest ) ) {
 			// xxx - not positive this is correct, but appears to allow casting int => enum
 			cost = Cost::unsafe;
@@ -330,9 +330,9 @@
 	}
 
-	void ConversionCost::postvisit( PointerType * pointerType ) {
-		if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
+	void ConversionCost::postvisit( const PointerType * pointerType ) {
+		if ( const PointerType *destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
 			PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
-			Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
-			Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
+			Type::Qualifiers tq1 = pointerType->base->tq;
+			Type::Qualifiers tq2 = destAsPtr->base->tq;
 			if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
 				PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
@@ -363,16 +363,16 @@
 	}
 
-	void ConversionCost::postvisit( ArrayType * ) {}
-
-	void ConversionCost::postvisit( ReferenceType * refType ) {
+	void ConversionCost::postvisit( const ArrayType * ) {}
+
+	void ConversionCost::postvisit( const ReferenceType * refType ) {
 		// Note: dest can never be a reference, since it would have been caught in an earlier check
-		assert( ! dynamic_cast< ReferenceType * >( dest ) );
+		assert( ! dynamic_cast< const ReferenceType * >( dest ) );
 		// convert reference to rvalue: cv T1 & => T2
 		// recursively compute conversion cost from T1 to T2.
 		// cv can be safely dropped because of 'implicit dereference' behavior.
 		cost = costFunc( refType->base, dest, indexer, env );
-		if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
+		if ( refType->base->tq == dest->tq ) {
 			cost.incReference();  // prefer exact qualifiers
-		} else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
+		} else if ( refType->base->tq < dest->tq ) {
 			cost.incSafe(); // then gaining qualifiers
 		} else {
@@ -382,8 +382,8 @@
 	}
 
-	void ConversionCost::postvisit( FunctionType * ) {}
-
-	void ConversionCost::postvisit( StructInstType * inst ) {
-		if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
+	void ConversionCost::postvisit( const FunctionType * ) {}
+
+	void ConversionCost::postvisit( const StructInstType * inst ) {
+		if ( const StructInstType *destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
 				cost = Cost::zero;
@@ -392,6 +392,6 @@
 	}
 
-	void ConversionCost::postvisit( UnionInstType * inst ) {
-		if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
+	void ConversionCost::postvisit( const UnionInstType * inst ) {
+		if ( const UnionInstType *destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
 				cost = Cost::zero;
@@ -400,5 +400,5 @@
 	}
 
-	void ConversionCost::postvisit( EnumInstType * ) {
+	void ConversionCost::postvisit( const EnumInstType * ) {
 		static Type::Qualifiers q;
 		static BasicType integer( q, BasicType::SignedInt );
@@ -409,15 +409,15 @@
 	}
 
-	void ConversionCost::postvisit( TraitInstType * ) {}
-
-	void ConversionCost::postvisit( TypeInstType *inst ) {
+	void ConversionCost::postvisit( const TraitInstType * ) {}
+
+	void ConversionCost::postvisit( const TypeInstType *inst ) {
 		if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
 			cost = costFunc( eqvClass->type, dest, indexer, env );
-		} else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
+		} else if ( const TypeInstType *destAsInst = dynamic_cast< const TypeInstType* >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
 				cost = Cost::zero;
 			}
 		} else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
-			TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
+			const TypeDecl *type = dynamic_cast< const TypeDecl* >( namedType );
 			// all typedefs should be gone by this point
 			assert( type );
@@ -428,7 +428,7 @@
 	}
 
-	void ConversionCost::postvisit( TupleType * tupleType ) {
+	void ConversionCost::postvisit( const TupleType * tupleType ) {
 		Cost c = Cost::zero;
-		if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
+		if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) {
 			std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
 			std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
@@ -448,16 +448,16 @@
 	}
 
-	void ConversionCost::postvisit( VarArgsType * ) {
-		if ( dynamic_cast< VarArgsType* >( dest ) ) {
-			cost = Cost::zero;
-		}
-	}
-
-	void ConversionCost::postvisit( ZeroType * ) {
-		if ( dynamic_cast< ZeroType * >( dest ) ) {
-			cost = Cost::zero;
-		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
+	void ConversionCost::postvisit( const VarArgsType * ) {
+		if ( dynamic_cast< const VarArgsType* >( dest ) ) {
+			cost = Cost::zero;
+		}
+	}
+
+	void ConversionCost::postvisit( const ZeroType * ) {
+		if ( dynamic_cast< const ZeroType * >( dest ) ) {
+			cost = Cost::zero;
+		} else if ( const BasicType *destAsBasic = dynamic_cast< const BasicType* >( dest ) ) {
 			// copied from visit(BasicType*) for signed int, but +1 for safe conversions
-			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
+			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
 			if ( tableResult == -1 ) {
 				cost = Cost::unsafe;
@@ -465,7 +465,7 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult + 1 );
-				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
-			} // if
-		} else if ( dynamic_cast< PointerType* >( dest ) ) {
+				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
+			} // if
+		} else if ( dynamic_cast< const PointerType* >( dest ) ) {
 			cost = Cost::zero;
 			cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
@@ -473,10 +473,10 @@
 	}
 
-	void ConversionCost::postvisit( OneType * ) {
-		if ( dynamic_cast< OneType * >( dest ) ) {
-			cost = Cost::zero;
-		} else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
+	void ConversionCost::postvisit( const OneType * ) {
+		if ( dynamic_cast< const OneType * >( dest ) ) {
+			cost = Cost::zero;
+		} else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
 			// copied from visit(BasicType*) for signed int, but +1 for safe conversions
-			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
+			int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
 			if ( tableResult == -1 ) {
 				cost = Cost::unsafe;
@@ -484,5 +484,5 @@
 				cost = Cost::zero;
 				cost.incSafe( tableResult + 1 );
-				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
+				cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
 			} // if
 		} // if
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision 1d7609346873ee72ada94a9702d5eca9232cd625)
+++ src/ResolvExpr/ConversionCost.h	(revision 7870799883ca946218c97fb6a189d1da90a16e8e)
@@ -33,30 +33,30 @@
 	class TypeEnvironment;
 
-	typedef std::function<Cost(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
+	typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
 	struct ConversionCost : public WithShortCircuiting {
 	  public:
-		ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
+		ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
 
 		Cost get_cost() const { return cost; }
 
-		void previsit( BaseSyntaxNode * ) { visit_children = false; }
+		void previsit( const BaseSyntaxNode * ) { visit_children = false; }
 
-		void postvisit( VoidType * voidType );
-		void postvisit( BasicType * basicType );
-		void postvisit( PointerType * pointerType );
-		void postvisit( ArrayType * arrayType );
-		void postvisit( ReferenceType * refType );
-		void postvisit( FunctionType * functionType );
-		void postvisit( StructInstType * aggregateUseType );
-		void postvisit( UnionInstType * aggregateUseType );
-		void postvisit( EnumInstType * aggregateUseType );
-		void postvisit( TraitInstType * aggregateUseType );
-		void postvisit( TypeInstType * aggregateUseType );
-		void postvisit( TupleType * tupleType );
-		void postvisit( VarArgsType * varArgsType );
-		void postvisit( ZeroType * zeroType );
-		void postvisit( OneType * oneType );
+		void postvisit( const VoidType * voidType );
+		void postvisit( const BasicType * basicType );
+		void postvisit( const PointerType * pointerType );
+		void postvisit( const ArrayType * arrayType );
+		void postvisit( const ReferenceType * refType );
+		void postvisit( const FunctionType * functionType );
+		void postvisit( const StructInstType * aggregateUseType );
+		void postvisit( const UnionInstType * aggregateUseType );
+		void postvisit( const EnumInstType * aggregateUseType );
+		void postvisit( const TraitInstType * aggregateUseType );
+		void postvisit( const TypeInstType * aggregateUseType );
+		void postvisit( const TupleType * tupleType );
+		void postvisit( const VarArgsType * varArgsType );
+		void postvisit( const ZeroType * zeroType );
+		void postvisit( const OneType * oneType );
 	  protected:
-		Type *dest;
+		const Type * dest;
 		const SymTab::Indexer &indexer;
 		Cost cost;
@@ -65,6 +65,6 @@
 	};
 
-	typedef std::function<int(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
-	Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
+	typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
+	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
 
 // Some function pointer types, differ in return type.
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision 1d7609346873ee72ada94a9702d5eca9232cd625)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision 7870799883ca946218c97fb6a189d1da90a16e8e)
@@ -27,38 +27,38 @@
 namespace ResolvExpr {
 	struct PtrsAssignable : public WithShortCircuiting {
-		PtrsAssignable( Type *dest, const TypeEnvironment &env );
+		PtrsAssignable( const Type * dest, const TypeEnvironment &env );
 
 		int get_result() const { return result; }
 
-		void previsit( Type * ) { visit_children = false; }
-
-		void postvisit( VoidType * voidType );
-		void postvisit( BasicType * basicType );
-		void postvisit( PointerType * pointerType );
-		void postvisit( ArrayType * arrayType );
-		void postvisit( FunctionType * functionType );
-		void postvisit( StructInstType * inst );
-		void postvisit( UnionInstType * inst );
-		void postvisit( EnumInstType * inst );
-		void postvisit( TraitInstType * inst );
-		void postvisit( TypeInstType * inst );
-		void postvisit( TupleType * tupleType );
-		void postvisit( VarArgsType * varArgsType );
-		void postvisit( ZeroType * zeroType );
-		void postvisit( OneType * oneType );
+		void previsit( const Type * ) { visit_children = false; }
+
+		void postvisit( const VoidType * voidType );
+		void postvisit( const BasicType * basicType );
+		void postvisit( const PointerType * pointerType );
+		void postvisit( const ArrayType * arrayType );
+		void postvisit( const FunctionType * functionType );
+		void postvisit( const StructInstType * inst );
+		void postvisit( const UnionInstType * inst );
+		void postvisit( const EnumInstType * inst );
+		void postvisit( const TraitInstType * inst );
+		void postvisit( const TypeInstType * inst );
+		void postvisit( const TupleType * tupleType );
+		void postvisit( const VarArgsType * varArgsType );
+		void postvisit( const ZeroType * zeroType );
+		void postvisit( const OneType * oneType );
 	  private:
-		Type *dest;
+		const Type * dest;
 		int result;
 		const TypeEnvironment &env;
 	};
 
-	int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
+	int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) {
 		// std::cerr << "assignable: " << src << " | " << dest << std::endl;
-		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
+			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
 				return ptrsAssignable( src, eqvClass->type, env );
 			} // if
 		} // if
-		if ( dynamic_cast< VoidType* >( dest ) ) {
+		if ( dynamic_cast< const VoidType* >( dest ) ) {
 			// void * = T * for any T is unsafe
 			// xxx - this should be safe, but that currently breaks the build
@@ -71,21 +71,21 @@
 	}
 
-	PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
-
-	void PtrsAssignable::postvisit( VoidType * ) {
+	PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
+
+	void PtrsAssignable::postvisit( const VoidType * ) {
 		// T * = void * is disallowed - this is a change from C, where any
 		// void * can be assigned or passed to a non-void pointer without a cast.
 	}
 
-	void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {}
-	void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {}
-	void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {}
-	void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {}
-
-	void PtrsAssignable::postvisit(  __attribute__((unused)) StructInstType *inst ) {}
-	void PtrsAssignable::postvisit(  __attribute__((unused)) UnionInstType *inst ) {}
-
-	void PtrsAssignable::postvisit( EnumInstType * ) {
-		if ( dynamic_cast< BasicType* >( dest ) ) {
+	void PtrsAssignable::postvisit( const BasicType * ) {}
+	void PtrsAssignable::postvisit( const PointerType * ) {}
+	void PtrsAssignable::postvisit( const ArrayType * ) {}
+	void PtrsAssignable::postvisit( const FunctionType * ) {}
+
+	void PtrsAssignable::postvisit( const StructInstType * ) {}
+	void PtrsAssignable::postvisit( const UnionInstType * ) {}
+
+	void PtrsAssignable::postvisit( const EnumInstType * ) {
+		if ( dynamic_cast< const BasicType* >( dest ) ) {
 			// int * = E *, etc. is safe. This isn't technically correct, as each
 			// enum has one basic type that it is compatible with, an that type can
@@ -97,7 +97,7 @@
 	}
 
-	void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
-	void PtrsAssignable::postvisit( TypeInstType *inst ) {
-		if ( const EqvClass *eqvClass = env.lookup( inst->get_name() ) ) {
+	void PtrsAssignable::postvisit(  const TraitInstType * ) {}
+	void PtrsAssignable::postvisit( const TypeInstType * inst ) {
+		if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
 			if ( eqvClass->type ) {
 				// T * = S * for any S depends on the type bound to T
@@ -107,8 +107,8 @@
 	}
 
-	void PtrsAssignable::postvisit(  __attribute__((unused)) TupleType *tupleType ) {}
-	void PtrsAssignable::postvisit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
-	void PtrsAssignable::postvisit(  __attribute__((unused)) ZeroType *zeroType ) {}
-	void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
+	void PtrsAssignable::postvisit( const TupleType * ) {}
+	void PtrsAssignable::postvisit( const VarArgsType * ) {}
+	void PtrsAssignable::postvisit( const ZeroType * ) {}
+	void PtrsAssignable::postvisit( const OneType * ) {}
 
 // TODO: Get rid of the `_new` suffix when the old version is removed.
Index: src/ResolvExpr/PtrsCastable.cc
===================================================================
--- src/ResolvExpr/PtrsCastable.cc	(revision 1d7609346873ee72ada94a9702d5eca9232cd625)
+++ src/ResolvExpr/PtrsCastable.cc	(revision 7870799883ca946218c97fb6a189d1da90a16e8e)
@@ -29,26 +29,26 @@
 	struct PtrsCastable_old : public WithShortCircuiting  {
 	  public:
-		PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
+		PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
 
 		int get_result() const { return result; }
 
-		void previsit( Type * ) { visit_children = false; }
-
-		void postvisit( VoidType * voidType );
-		void postvisit( BasicType * basicType );
-		void postvisit( PointerType * pointerType );
-		void postvisit( ArrayType * arrayType );
-		void postvisit( FunctionType * functionType );
-		void postvisit( StructInstType * inst );
-		void postvisit( UnionInstType * inst );
-		void postvisit( EnumInstType * inst );
-		void postvisit( TraitInstType * inst );
-		void postvisit( TypeInstType * inst );
-		void postvisit( TupleType * tupleType );
-		void postvisit( VarArgsType * varArgsType );
-		void postvisit( ZeroType * zeroType );
-		void postvisit( OneType * oneType );
+		void previsit( const Type * ) { visit_children = false; }
+
+		void postvisit( const VoidType * voidType );
+		void postvisit( const BasicType * basicType );
+		void postvisit( const PointerType * pointerType );
+		void postvisit( const ArrayType * arrayType );
+		void postvisit( const FunctionType * functionType );
+		void postvisit( const StructInstType * inst );
+		void postvisit( const UnionInstType * inst );
+		void postvisit( const EnumInstType * inst );
+		void postvisit( const TraitInstType * inst );
+		void postvisit( const TypeInstType * inst );
+		void postvisit( const TupleType * tupleType );
+		void postvisit( const VarArgsType * varArgsType );
+		void postvisit( const ZeroType * zeroType );
+		void postvisit( const OneType * oneType );
 	  private:
-		Type *dest;
+		const Type * dest;
 		int result;
 		const TypeEnvironment &env;
@@ -57,15 +57,15 @@
 
 	namespace {
-		int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
-			if ( dynamic_cast< FunctionType* >( src ) ) {
+		int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+			if ( dynamic_cast< const FunctionType* >( src ) ) {
 				return -1;
-			} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
-				if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
-					if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
-						if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
+			} else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) {
+				if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) {
+					if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) {
+						if ( tyDecl->kind == TypeDecl::Ftype ) {
 							return -1;
 						} // if
 					} //if
-				} else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
+				} else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
 					if ( eqvClass->data.kind == TypeDecl::Ftype ) {
 						return -1;
@@ -75,17 +75,17 @@
 			return 1;
 		}
-		int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+		int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
 			return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
 		}
 	}
 
-	int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
-		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+	int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
+			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
 				// xxx - should this be ptrsCastable?
 				return ptrsAssignable( src, eqvClass->type, env );
 			} // if
 		} // if
-		if ( dynamic_cast< VoidType* >( dest ) ) {
+		if ( dynamic_cast< const VoidType* >( dest ) ) {
 			return objectCast( src, env, indexer );
 		} else {
@@ -96,42 +96,42 @@
 	}
 
-	PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
+	PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
 		: dest( dest ), result( 0 ), env( env ), indexer( indexer )	{
 	}
 
-	void PtrsCastable_old::postvisit( VoidType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( BasicType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( PointerType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( ArrayType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( FunctionType * ) {
+	void PtrsCastable_old::postvisit( const VoidType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const BasicType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const PointerType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const ArrayType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const FunctionType * ) {
 		// result = -1;
 		result = functionCast( dest, env, indexer );
 	}
 
-	void PtrsCastable_old::postvisit( StructInstType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( UnionInstType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( EnumInstType * ) {
-		if ( dynamic_cast< EnumInstType* >( dest ) ) {
+	void PtrsCastable_old::postvisit( const StructInstType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const UnionInstType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const EnumInstType * ) {
+		if ( dynamic_cast< const EnumInstType * >( dest ) ) {
 			result = 1;
-		} else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
-			if ( bt->get_kind() == BasicType::SignedInt ) {
+		} else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) {
+			if ( bt->kind == BasicType::SignedInt ) {
 				result = 0;
 			} else {
@@ -143,24 +143,24 @@
 	}
 
-	void PtrsCastable_old::postvisit( TraitInstType * ) {}
-
-	void PtrsCastable_old::postvisit(TypeInstType *inst ) {
+	void PtrsCastable_old::postvisit( const TraitInstType * ) {}
+
+	void PtrsCastable_old::postvisit( const TypeInstType *inst ) {
 		//result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
 		result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
 	}
 
-	void PtrsCastable_old::postvisit( TupleType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( VarArgsType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( ZeroType * ) {
-		result = objectCast( dest, env, indexer );
-	}
-
-	void PtrsCastable_old::postvisit( OneType * ) {
+	void PtrsCastable_old::postvisit( const TupleType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const VarArgsType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const ZeroType * ) {
+		result = objectCast( dest, env, indexer );
+	}
+
+	void PtrsCastable_old::postvisit( const OneType * ) {
 		result = objectCast( dest, env, indexer );
 	}
@@ -168,6 +168,6 @@
 namespace {
 	// can this type be cast to an object (1 for yes, -1 for no)
-	int objectCast( 
-		const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
+	int objectCast(
+		const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
 	) {
 		if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
@@ -191,6 +191,6 @@
 
 	// can this type be cast to a function (inverse of objectCast)
-	int functionCast( 
-		const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
+	int functionCast(
+		const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
 	) {
 		return -1 * objectCast( src, env, symtab );
@@ -204,5 +204,5 @@
 		int result;
 
-		PtrsCastable_new( 
+		PtrsCastable_new(
 			const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
 		: dst( d ), env( e ), symtab( syms ), result( 0 ) {}
@@ -278,7 +278,7 @@
 } // anonymous namespace
 
-int ptrsCastable( 
-	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
-	const ast::TypeEnvironment & env 
+int ptrsCastable(
+	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
+	const ast::TypeEnvironment & env
 ) {
 	if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 1d7609346873ee72ada94a9702d5eca9232cd625)
+++ src/ResolvExpr/Unify.cc	(revision 7870799883ca946218c97fb6a189d1da90a16e8e)
@@ -97,7 +97,7 @@
 	bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer );
 
-	bool unifyExact( 
-		const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
-		ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
+	bool unifyExact(
+		const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
+		ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
 		WidenMode widen, const ast::SymbolTable & symtab );
 
@@ -121,6 +121,6 @@
 	}
 
-	bool typesCompatible( 
-			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 
+	bool typesCompatible(
+			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
 			const ast::TypeEnvironment & env ) {
 		ast::TypeEnvironment newEnv;
@@ -135,9 +135,9 @@
 		findOpenVars( newSecond, open, closed, need, have, FirstOpen );
 
-		return unifyExact( 
+		return unifyExact(
 			newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
 	}
 
-	bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+	bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		TypeEnvironment newEnv;
 		OpenVarSet openVars;
@@ -163,11 +163,11 @@
 	}
 
-	bool typesCompatibleIgnoreQualifiers( 
-			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 
+	bool typesCompatibleIgnoreQualifiers(
+			const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
 			const ast::TypeEnvironment & env ) {
 		ast::TypeEnvironment newEnv;
 		ast::OpenVarSet open;
 		ast::AssertionSet need, have;
-		
+
 		ast::ptr<ast::Type> newFirst{ first }, newSecond{ second };
 		env.apply( newFirst );
@@ -176,5 +176,5 @@
 		reset_qualifiers( newSecond );
 
-		return unifyExact( 
+		return unifyExact(
 			newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
 	}
@@ -490,9 +490,9 @@
 
 			// sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
-			if ( 
-					(flatFunc->parameters.size() == flatOther->parameters.size() && 
-						flatFunc->returnVals.size() == flatOther->returnVals.size()) 
-					|| flatFunc->isTtype() 
-					|| flatOther->isTtype() 
+			if (
+					(flatFunc->parameters.size() == flatOther->parameters.size() &&
+						flatFunc->returnVals.size() == flatOther->returnVals.size())
+					|| flatFunc->isTtype()
+					|| flatOther->isTtype()
 			) {
 				if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
@@ -711,13 +711,13 @@
 		bool result;
 
-		Unify_new( 
-			const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 
-			ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 
+		Unify_new(
+			const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need,
+			ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen,
 			const ast::SymbolTable & symtab )
-		: type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 
+		: type2(type2), tenv(env), need(need), have(have), open(open), widen(widen),
 		  symtab(symtab), result(false) {}
 
 		void previsit( const ast::Node * ) { visit_children = false; }
-		
+
 		void postvisit( const ast::VoidType * ) {
 			result = dynamic_cast< const ast::VoidType * >( type2 );
@@ -732,6 +732,6 @@
 		void postvisit( const ast::PointerType * pointer ) {
 			if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
-				result = unifyExact( 
-					pointer->base, pointer2->base, tenv, need, have, open, 
+				result = unifyExact(
+					pointer->base, pointer2->base, tenv, need, have, open,
 					noWiden(), symtab );
 			}
@@ -742,8 +742,8 @@
 			if ( ! array2 ) return;
 
-			// to unify, array types must both be VLA or both not VLA and both must have a 
+			// to unify, array types must both be VLA or both not VLA and both must have a
 			// dimension expression or not have a dimension
 			if ( array->isVarLen != array2->isVarLen ) return;
-			if ( ! array->isVarLen && ! array2->isVarLen 
+			if ( ! array->isVarLen && ! array2->isVarLen
 					&& array->dimension && array2->dimension ) {
 				auto ce1 = array->dimension.as< ast::ConstantExpr >();
@@ -751,11 +751,11 @@
 
 				// see C11 Reference Manual 6.7.6.2.6
-				// two array types with size specifiers that are integer constant expressions are 
+				// two array types with size specifiers that are integer constant expressions are
 				// compatible if both size specifiers have the same constant value
 				if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return;
 			}
 
-			result = unifyExact( 
-				array->base, array2->base, tenv, need, have, open, noWiden(), 
+			result = unifyExact(
+				array->base, array2->base, tenv, need, have, open, noWiden(),
 				symtab );
 		}
@@ -763,6 +763,6 @@
 		void postvisit( const ast::ReferenceType * ref ) {
 			if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
-				result = unifyExact( 
-					ref->base, ref2->base, tenv, need, have, open, noWiden(), 
+				result = unifyExact(
+					ref->base, ref2->base, tenv, need, have, open, noWiden(),
 					symtab );
 			}
@@ -771,5 +771,5 @@
 	private:
 		/// Replaces ttype variables with their bound types.
-		/// If this isn't done when satifying ttype assertions, then argument lists can have 
+		/// If this isn't done when satifying ttype assertions, then argument lists can have
 		/// different size and structure when they should be compatible.
 		struct TtypeExpander_new : public ast::WithShortCircuiting {
@@ -800,9 +800,9 @@
 				auto types = flatten( d->get_type() );
 				for ( ast::ptr< ast::Type > & t : types ) {
-					// outermost const, volatile, _Atomic qualifiers in parameters should not play 
-					// a role in the unification of function types, since they do not determine 
+					// outermost const, volatile, _Atomic qualifiers in parameters should not play
+					// a role in the unification of function types, since they do not determine
 					// whether a function is callable.
-					// NOTE: **must** consider at least mutex qualifier, since functions can be 
-					// overloaded on outermost mutex and a mutex function has different 
+					// NOTE: **must** consider at least mutex qualifier, since functions can be
+					// overloaded on outermost mutex and a mutex function has different
 					// requirements than a non-mutex function
 					remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
@@ -818,5 +818,5 @@
 			std::vector< ast::ptr< ast::Type > > types;
 			while ( crnt != end ) {
-				// it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 
+				// it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
 				// that this results in a flat tuple
 				flatten( (*crnt)->get_type(), types );
@@ -829,7 +829,7 @@
 
 		template< typename Iter >
-		static bool unifyDeclList( 
-			Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 
-			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
+		static bool unifyDeclList(
+			Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
+			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
 			const ast::SymbolTable & symtab
 		) {
@@ -843,16 +843,16 @@
 				if ( isTuple1 && ! isTuple2 ) {
 					// combine remainder of list2, then unify
-					return unifyExact( 
-						t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 
+					return unifyExact(
+						t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
 						noWiden(), symtab );
 				} else if ( ! isTuple1 && isTuple2 ) {
 					// combine remainder of list1, then unify
-					return unifyExact( 
-						tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 
+					return unifyExact(
+						tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
 						noWiden(), symtab );
 				}
 
-				if ( ! unifyExact( 
-					t1, t2, env, need, have, open, noWiden(), symtab ) 
+				if ( ! unifyExact(
+					t1, t2, env, need, have, open, noWiden(), symtab )
 				) return false;
 
@@ -860,5 +860,5 @@
 			}
 
-			// May get to the end of one argument list before the other. This is only okay if the 
+			// May get to the end of one argument list before the other. This is only okay if the
 			// other is a ttype
 			if ( crnt1 != end1 ) {
@@ -866,6 +866,6 @@
 				const ast::Type * t1 = (*crnt1)->get_type();
 				if ( ! Tuples::isTtype( t1 ) ) return false;
-				return unifyExact( 
-					t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 
+				return unifyExact(
+					t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
 					noWiden(), symtab );
 			} else if ( crnt2 != end2 ) {
@@ -873,6 +873,6 @@
 				const ast::Type * t2 = (*crnt2)->get_type();
 				if ( ! Tuples::isTtype( t2 ) ) return false;
-				return unifyExact( 
-					tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 
+				return unifyExact(
+					tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
 					noWiden(), symtab );
 			}
@@ -881,12 +881,12 @@
 		}
 
-		static bool unifyDeclList( 
-			const std::vector< ast::ptr< ast::DeclWithType > > & list1, 
-			const std::vector< ast::ptr< ast::DeclWithType > > & list2, 
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
+		static bool unifyDeclList(
+			const std::vector< ast::ptr< ast::DeclWithType > > & list1,
+			const std::vector< ast::ptr< ast::DeclWithType > > & list2,
+			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
 			const ast::OpenVarSet & open, const ast::SymbolTable & symtab
 		) {
-			return unifyDeclList( 
-				list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 
+			return unifyDeclList(
+				list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
 				symtab );
 		}
@@ -900,7 +900,7 @@
 
 		/// mark all assertions in `type` used in both `assn1` and `assn2`
-		static void markAssertions( 
-			ast::AssertionSet & assn1, ast::AssertionSet & assn2, 
-			const ast::ParameterizedType * type 
+		static void markAssertions(
+			ast::AssertionSet & assn1, ast::AssertionSet & assn2,
+			const ast::ParameterizedType * type
 		) {
 			for ( const auto & tyvar : type->forall ) {
@@ -918,13 +918,13 @@
 
 			if ( func->isVarArgs != func2->isVarArgs ) return;
-			
-			// Flatten the parameter lists for both functions so that tuple structure does not 
+
+			// Flatten the parameter lists for both functions so that tuple structure does not
 			// affect unification. Does not actually mutate function parameters.
 			auto params = flattenList( func->params, tenv );
 			auto params2 = flattenList( func2->params, tenv );
 
-			// sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 
+			// sizes don't have to match if ttypes are involved; need to be more precise w.r.t.
 			// where the ttype is to prevent errors
-			if ( 
+			if (
 				( params.size() != params2.size() || func->returns.size() != func2->returns.size() )
 				&& ! func->isTtype()
@@ -933,7 +933,7 @@
 
 			if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return;
-			if ( ! unifyDeclList( 
+			if ( ! unifyDeclList(
 				func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
-			
+
 			markAssertions( have, need, func );
 			markAssertions( have, need, func2 );
@@ -941,5 +941,5 @@
 			result = true;
 		}
-	
+
 	private:
 		template< typename RefType >
@@ -953,5 +953,5 @@
 		/// Creates a tuple type based on a list of TypeExpr
 		template< typename Iter >
-		static const ast::Type * tupleFromExprs( 
+		static const ast::Type * tupleFromExprs(
 			const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs
 		) {
@@ -973,5 +973,5 @@
 			const RefType * inst2 = handleRefType( inst, other );
 			if ( ! inst2 ) return;
-			
+
 			// check that parameters of types unify, if any
 			const std::vector< ast::ptr< ast::Expr > > & params = inst->params;
@@ -1002,5 +1002,5 @@
 				}
 
-				if ( ! unifyExact( 
+				if ( ! unifyExact(
 						pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
 					result = false;
@@ -1038,10 +1038,10 @@
 	private:
 		/// Creates a tuple type based on a list of Type
-		static ast::ptr< ast::Type > tupleFromTypes( 
+		static ast::ptr< ast::Type > tupleFromTypes(
 			const std::vector< ast::ptr< ast::Type > > & tys
 		) {
 			std::vector< ast::ptr< ast::Type > > out;
 			for ( const ast::Type * ty : tys ) {
-				// it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 
+				// it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
 				// that this results in a flat tuple
 				flatten( ty, out );
@@ -1051,8 +1051,8 @@
 		}
 
-		static bool unifyList( 
-			const std::vector< ast::ptr< ast::Type > > & list1, 
-			const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 
-			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
+		static bool unifyList(
+			const std::vector< ast::ptr< ast::Type > > & list1,
+			const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env,
+			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
 			const ast::SymbolTable & symtab
 		) {
@@ -1068,16 +1068,16 @@
 				if ( isTuple1 && ! isTuple2 ) {
 					// combine entirety of list2, then unify
-					return unifyExact( 
-						t1, tupleFromTypes( list2 ), env, need, have, open, 
+					return unifyExact(
+						t1, tupleFromTypes( list2 ), env, need, have, open,
 						noWiden(), symtab );
 				} else if ( ! isTuple1 && isTuple2 ) {
 					// combine entirety of list1, then unify
 					return unifyExact(
-						tupleFromTypes( list1 ), t2, env, need, have, open, 
+						tupleFromTypes( list1 ), t2, env, need, have, open,
 						noWiden(), symtab );
 				}
 
-				if ( ! unifyExact( 
-					t1, t2, env, need, have, open, noWiden(), symtab ) 
+				if ( ! unifyExact(
+					t1, t2, env, need, have, open, noWiden(), symtab )
 				) return false;
 
@@ -1089,8 +1089,8 @@
 				const ast::Type * t1 = *crnt1;
 				if ( ! Tuples::isTtype( t1 ) ) return false;
-				// xxx - this doesn't generate an empty tuple, contrary to comment; both ported 
+				// xxx - this doesn't generate an empty tuple, contrary to comment; both ported
 				// from Rob's code
-				return unifyExact( 
-						t1, tupleFromTypes( list2 ), env, need, have, open, 
+				return unifyExact(
+						t1, tupleFromTypes( list2 ), env, need, have, open,
 						noWiden(), symtab );
 			} else if ( crnt2 != list2.end() ) {
@@ -1098,8 +1098,8 @@
 				const ast::Type * t2 = *crnt2;
 				if ( ! Tuples::isTtype( t2 ) ) return false;
-				// xxx - this doesn't generate an empty tuple, contrary to comment; both ported 
+				// xxx - this doesn't generate an empty tuple, contrary to comment; both ported
 				// from Rob's code
 				return unifyExact(
-						tupleFromTypes( list1 ), t2, env, need, have, open, 
+						tupleFromTypes( list1 ), t2, env, need, have, open,
 						noWiden(), symtab );
 			}
@@ -1133,5 +1133,5 @@
 		void postvisit( const ast::OneType * ) {
 			result = dynamic_cast< const ast::OneType * >( type2 );
-		}	
+		}
 
 	  private:
@@ -1140,7 +1140,7 @@
 	};
 
-	bool unify( 
-			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
+	bool unify(
+			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
 			ast::OpenVarSet & open, const ast::SymbolTable & symtab
 	) {
@@ -1149,19 +1149,19 @@
 	}
 
-	bool unify( 
-			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
-			ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 
+	bool unify(
+			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
+			ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
 	) {
 		ast::OpenVarSet closed;
 		findOpenVars( type1, open, closed, need, have, FirstClosed );
 		findOpenVars( type2, open, closed, need, have, FirstOpen );
-		return unifyInexact( 
+		return unifyInexact(
 			type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
 	}
 
-	bool unifyExact( 
-			const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
-			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
+	bool unifyExact(
+			const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
+			ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
 			WidenMode widen, const ast::SymbolTable & symtab
 	) {
@@ -1170,6 +1170,6 @@
 		auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 );
 		auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 );
-		ast::OpenVarSet::const_iterator 
-			entry1 = var1 ? open.find( var1->name ) : open.end(), 
+		ast::OpenVarSet::const_iterator
+			entry1 = var1 ? open.find( var1->name ) : open.end(),
 			entry2 = var2 ? open.find( var2->name ) : open.end();
 		bool isopen1 = entry1 != open.end();
@@ -1178,6 +1178,6 @@
 		if ( isopen1 && isopen2 ) {
 			if ( entry1->second.kind != entry2->second.kind ) return false;
-			return env.bindVarToVar( 
-				var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 
+			return env.bindVarToVar(
+				var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have,
 				open, widen, symtab );
 		} else if ( isopen1 ) {
@@ -1192,18 +1192,18 @@
 	}
 
-	bool unifyInexact( 
-			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
-			const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 
-			ast::ptr<ast::Type> & common 
+	bool unifyInexact(
+			const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
+			const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
+			ast::ptr<ast::Type> & common
 	) {
 		ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
-		
-		// force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 
+
+		// force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and
 		// type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1
 		ast::ptr<ast::Type> t1{ type1 }, t2{ type2 };
 		reset_qualifiers( t1 );
 		reset_qualifiers( t2 );
-		
+
 		if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
 			t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision 1d7609346873ee72ada94a9702d5eca9232cd625)
+++ src/ResolvExpr/typeops.h	(revision 7870799883ca946218c97fb6a189d1da90a16e8e)
@@ -73,37 +73,37 @@
 
 	/// Replaces array types with equivalent pointer, and function types with a pointer-to-function
-	const ast::Type * adjustExprType( 
+	const ast::Type * adjustExprType(
 		const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
 
 	// in CastCost.cc
-	Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
-	Cost castCost( 
-		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
+	Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+	Cost castCost(
+		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
 		const ast::TypeEnvironment & env );
 
 	// in ConversionCost.cc
-	Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
-	Cost conversionCost( 
-		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
+	Cost conversionCost( const Type *src, const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+	Cost conversionCost(
+		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
 		const ast::TypeEnvironment & env );
 
 	// in AlternativeFinder.cc
-	Cost computeConversionCost( Type *actualType, Type *formalType, 
+	Cost computeConversionCost( Type *actualType, Type *formalType,
 		const SymTab::Indexer &indexer, const TypeEnvironment &env );
 
 	// in PtrsAssignable.cc
-	int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
+	int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment &env );
 	int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
 		const ast::TypeEnvironment & env );
 
 	// in PtrsCastable.cc
-	int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
-	int ptrsCastable( 
-		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
+	int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
+	int ptrsCastable(
+		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
 		const ast::TypeEnvironment & env );
 
 	// in Unify.cc
 	bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
-	bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+	bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
 
 	inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
@@ -112,15 +112,15 @@
 	}
 
-	inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
+	inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer &indexer ) {
 		TypeEnvironment env;
 		return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
 	}
 
-	bool typesCompatible( 
-		const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 
+	bool typesCompatible(
+		const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
 		const ast::TypeEnvironment & env = {} );
-	
+
 	bool typesCompatibleIgnoreQualifiers(
-		const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
+		const ast::Type *, const ast::Type *, const ast::SymbolTable &,
 		const ast::TypeEnvironment & env = {} );
 
@@ -133,10 +133,10 @@
 	Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
 	ast::ptr< ast::Type > commonType(
-		const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 
+		const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen,
 		const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open );
 
 	// in PolyCost.cc
 	int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
-	int polyCost( 
+	int polyCost(
 		const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
 
@@ -149,5 +149,5 @@
 	// new AST version in TypeEnvironment.cpp (only place it was used in old AST)
 
-	template<typename Iter> 
+	template<typename Iter>
 	bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment &env ) {
 		while ( begin != end ) {
@@ -176,8 +176,8 @@
 
 	/// flatten tuple type into existing list of types
-	static inline void flatten( 
-		const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 
+	static inline void flatten(
+		const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out
 	) {
-		if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {	
+		if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {
 			for ( const ast::Type * t : tupleType->types ) {
 				flatten( t, out );
