Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 1d2b64f538b2e524e418c78785233364f63db708)
+++ src/ResolvExpr/CommonType.cc	(revision f7ff3fba1d98de23216f2c17fe82d71ab5e67308)
@@ -42,4 +42,5 @@
 		virtual void visit( OneType *oneType );
 
+		void getCommonWithVoidPointer( PointerType* voidPointer, PointerType* otherPointer );
 		template< typename RefType > void handleRefType( RefType *inst, Type *other );
 
@@ -143,28 +144,23 @@
 	}
 
-	/// true if a common type for t must be a complete type
-	bool requiredComplete( Type * t ) {
-		if ( TypeInstType * inst = dynamic_cast< TypeInstType * > ( t ) ) {
-			return inst->get_baseType()->isComplete();
+	void CommonType::getCommonWithVoidPointer( PointerType* voidPointer, PointerType* otherPointer ) {
+		if ( TypeInstType* var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {
+			OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
+			if ( entry != openVars.end() ) {
+				AssertionSet need, have;
+				WidenMode widen( widenFirst, widenSecond );
+				if ( entry != openVars.end() && ! bindVar(var, voidPointer->get_base(), entry->second, env, need, have, openVars, widen, indexer ) ) return;
+			}
 		}
-		return false;
+		result = voidPointer->clone();
+		result->get_qualifiers() += otherPointer->get_qualifiers();
 	}
 
 	void CommonType::visit( PointerType *pointerType ) {
 		if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
-			// Note: relationship between formal and actual types is antisymmetric
-			//   void free(void *);
-			//   forall(otype T) void foo(T *);
-			//
-			// should be able to pass T* to free, but should not be able to pass a void* to foo.
-			// because of this, the requiredComplete check occurs only on the first, since it corresponds
-			// to the formal parameter type (though this may be incorrect in some cases, in which case
-			// perhaps the widen mode needs to incorporate another bit for whether this is a formal or actual context)
-			if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base(), indexer) && ! requiredComplete( pointerType->get_base() ) ) {
-				result = otherPointer->clone();
-				result->get_qualifiers() += pointerType->get_qualifiers();
+			if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base(), indexer) ) {
+				getCommonWithVoidPointer( otherPointer, pointerType );
 			} else if ( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base(), indexer) ) {
-				result = pointerType->clone();
-				result->get_qualifiers() += otherPointer->get_qualifiers();
+				getCommonWithVoidPointer( pointerType, otherPointer );
 			} else if ( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
 					   && ( pointerType->get_base()->get_qualifiers() <= otherPointer->get_base()->get_qualifiers() || widenSecond ) ) {
@@ -256,4 +252,7 @@
 					result->get_qualifiers() += zeroType->get_qualifiers();
 				}
+			} else if ( widenSecond && dynamic_cast< OneType* >( type2 ) ) {
+				result = new BasicType( zeroType->get_qualifiers(), BasicType::SignedInt );
+				result->get_qualifiers() += type2->get_qualifiers();
 			}
 		}
@@ -267,4 +266,7 @@
 					result->get_qualifiers() += oneType->get_qualifiers();
 				}
+			} else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
+				result = new BasicType( oneType->get_qualifiers(), BasicType::SignedInt );
+				result->get_qualifiers() += type2->get_qualifiers();
 			}
 		}
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 1d2b64f538b2e524e418c78785233364f63db708)
+++ src/ResolvExpr/Resolver.cc	(revision f7ff3fba1d98de23216f2c17fe82d71ab5e67308)
@@ -404,4 +404,6 @@
 	template< typename AggrInst >
 	TypeSubstitution makeGenericSubstitutuion( AggrInst * inst ) {
+		assert( inst );
+		assert( inst->get_baseParameters() );
 		std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
 		std::list< Expression * > typeSubs = inst->get_parameters();
@@ -444,5 +446,4 @@
 
 	void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
-
 		if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
 			TypeSubstitution sub = makeGenericSubstitutuion( sit );
@@ -455,5 +456,5 @@
 			}
 		} else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
-			TypeSubstitution sub = makeGenericSubstitutuion( sit );
+			TypeSubstitution sub = makeGenericSubstitutuion( uit );
 			UnionDecl * un = uit->get_baseUnion();
 			// only resolve to the first member of a union
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 1d2b64f538b2e524e418c78785233364f63db708)
+++ src/ResolvExpr/Unify.cc	(revision f7ff3fba1d98de23216f2c17fe82d71ab5e67308)
@@ -31,14 +31,4 @@
 
 namespace ResolvExpr {
-	struct WidenMode {
-		WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}
-		WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }
-		WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }
-		WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }
-		WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
-		operator bool() { return widenFirst && widenSecond; }
-
-		bool widenFirst : 1, widenSecond : 1;
-	};
 
 	class Unify : public Visitor {
Index: src/ResolvExpr/Unify.h
===================================================================
--- src/ResolvExpr/Unify.h	(revision 1d2b64f538b2e524e418c78785233364f63db708)
+++ src/ResolvExpr/Unify.h	(revision f7ff3fba1d98de23216f2c17fe82d71ab5e67308)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Unify.h -- 
+// Unify.h --
 //
 // Author           : Richard C. Bilson
@@ -27,4 +27,16 @@
 
 namespace ResolvExpr {
+	struct WidenMode {
+		WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}
+		WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }
+		WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }
+		WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }
+		WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
+		operator bool() { return widenFirst && widenSecond; }
+
+		bool widenFirst : 1, widenSecond : 1;
+	};
+
+	bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
 	bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
 	bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
