Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 13a615491527669d9d35564c78694c473dbdbfc9)
+++ src/GenPoly/Box.cc	(revision 4573e3c3cd56364e99408f1914866d1580cd88a2)
@@ -734,5 +734,5 @@
 				Type * newType = param->clone();
 				if ( env ) env->apply( newType );
-				ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 );
+				ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr );
 				newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
 				stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
@@ -745,9 +745,31 @@
 		}
 
+		// find instances of polymorphic type parameters
+		struct PolyFinder {
+			const TyVarMap * tyVars = nullptr;
+			bool found = false;
+
+			void previsit( TypeInstType * t ) {
+				if ( isPolyType( t, *tyVars ) ) {
+					found = true;
+				}
+			}
+		};
+
+		// true if there is an instance of a polymorphic type parameter in t
+		bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {
+			PassVisitor<PolyFinder> finder;
+			finder.pass.tyVars = &tyVars;
+			maybeAccept( t, finder );
+			return finder.pass.found;
+		}
+
 		/// cast parameters to polymorphic functions so that types are replaced with
 		/// void * if they are type parameters in the formal type.
 		/// this gets rid of warnings from gcc.
 		void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
-			if ( getFunctionType( formal ) ) {
+			// type contains polymorphism, but isn't exactly a polytype, in which case it
+			// has some real actual type (e.g. unsigned int) and casting to void * is wrong
+			if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) {
 				Type * newType = formal->clone();
 				newType = ScrubTyVars::scrub( newType, tyVars );
@@ -757,6 +779,6 @@
 
 		void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
-			for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
-				assertf( arg != appExpr->get_args().end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
+			for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->parameters.end(); ++param, ++arg ) {
+				assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
 				addCast( *arg, (*param)->get_type(), exprTyVars );
 				boxParam( (*param)->get_type(), *arg, exprTyVars );
@@ -767,10 +789,7 @@
 			std::list< Expression *>::iterator cur = arg;
 			for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
-				for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
+				for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
 					InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
-					if ( inferParam == appExpr->get_inferParams().end() ) {
-						std::cerr << "looking for assertion: " << (*assert) << std::endl << appExpr << std::endl;
-					}
-					assertf( inferParam != appExpr->get_inferParams().end(), "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" );
+					assertf( inferParam != appExpr->get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
 					Expression *newExpr = inferParam->second.expr->clone();
 					addCast( newExpr, (*assert)->get_type(), tyVars );
@@ -782,5 +801,5 @@
 
 		void makeRetParm( FunctionType *funcType ) {
-			DeclarationWithType *retParm = funcType->get_returnVals().front();
+			DeclarationWithType *retParm = funcType->returnVals.front();
 
 			// make a new parameter that is a pointer to the type of the old return value
@@ -795,5 +814,4 @@
 			// actually make the adapter type
 			FunctionType *adapter = adaptee->clone();
-//			if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
 			if ( isDynRet( adapter, tyVars ) ) {
 				makeRetParm( adapter );
