Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 08fc48f4a5c70b7f3e402da3afef2763f754ff3a)
+++ src/GenPoly/Box.cc	(revision c04531fcbc266fccd0a1d26c2875cce9fe45e9a8)
@@ -25,4 +25,6 @@
 
 #include "Box.h"
+
+#include "CodeGen/OperatorTable.h"
 #include "Common/ScopedMap.h"            // for ScopedMap, ScopedMap<>::iter...
 #include "Common/SemanticError.h"        // for SemanticError
@@ -564,5 +566,5 @@
 			// To compound the issue, the right side can be *x, etc. because of lvalue-returning functions
 			if ( UntypedExpr * assign = dynamic_cast< UntypedExpr * >( commaExpr->get_arg1() ) ) {
-				if ( InitTweak::isAssignment( InitTweak::getFunctionName( assign ) ) ) {
+				if ( CodeGen::isAssignment( InitTweak::getFunctionName( assign ) ) ) {
 					assert( assign->get_args().size() == 2 );
 					if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( assign->get_args().back() ) ) {
@@ -604,5 +606,5 @@
 						}
 					} else {
-						throw SemanticError( "Cannot pass non-struct type for generic struct" );
+						throw SemanticError( "Cannot pass non-struct type for generic struct: ", argBaseType );
 					}
 				}
@@ -1019,4 +1021,5 @@
 						} // if
 						if ( baseType1 || baseType2 ) {
+							delete ret->get_result();
 							ret->set_result( appExpr->get_result()->clone() );
 							if ( appExpr->get_env() ) {
@@ -1032,5 +1035,7 @@
 						assert( ! appExpr->get_args().empty() );
 						if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
+							// remove dereference from polymorphic types since they are boxed.
 							Expression *ret = appExpr->get_args().front();
+							// fix expr type to remove pointer
 							delete ret->get_result();
 							ret->set_result( appExpr->get_result()->clone() );
@@ -1122,6 +1127,6 @@
 
 			assert( appExpr->get_function()->has_result() );
-			PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() );
-			FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() );
+			FunctionType * function = getFunctionType( appExpr->get_function()->get_result() );
+			assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() );
 
 			if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
@@ -1200,6 +1205,6 @@
 							if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
 								assert( appExpr->get_function()->has_result() );
-								PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() );
-								FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() );
+								FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
+								assert( function );
 								needs = needsAdapter( function, scopeTyVars );
 							} // if
@@ -1210,6 +1215,7 @@
 			// isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
 			// out of the if condition.
+			addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
+			// ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
 			bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
-			addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
 			if ( polytype || needs ) {
 				Expression *ret = addrExpr->get_arg();
@@ -1278,5 +1284,6 @@
 				if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
 					std::string adapterName = makeAdapterName( mangleName );
-					paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
+					// adapter may not be used in body, pass along with unused attribute.
+					paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );
 					adaptersDone.insert( adaptersDone.begin(), mangleName );
 				}
@@ -1384,5 +1391,7 @@
 			std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
 			std::list< DeclarationWithType *> inferredParams;
-			ObjectDecl newObj( "", Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
+			// size/align/offset parameters may not be used in body, pass along with unused attribute.
+			ObjectDecl newObj( "", Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0,
+			                   { new Attribute( "unused" ) } );
 			ObjectDecl newPtr( "", Type::StorageClasses(), LinkageSpec::C, 0,
 			                   new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
@@ -1407,4 +1416,6 @@
 				for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
 //      *assert = (*assert)->acceptMutator( *this );
+					// assertion parameters may not be used in body, pass along with unused attribute.
+					(*assert)->get_attributes().push_back( new Attribute( "unused" ) );
 					inferredParams.push_back( *assert );
 				}
