Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 9e23b446e321a87bbf5f2439c8d555a808d5e53c)
+++ src/GenPoly/Box.cc	(revision ffec1bfd5e6f76604c43a28508c5ddcc64bd3218)
@@ -189,6 +189,4 @@
 			/// Enters a new scope for type-variables, adding the type variables from ty
 			void beginTypeScope( Type *ty );
-			/// Exits the type-variable scope
-			void endTypeScope();
 			/// Enters a new scope for knowLayouts and knownOffsets and queues exit calls
 			void beginGenericScope();
@@ -198,4 +196,5 @@
 			UniqueName bufNamer;                           ///< Namer for VLA buffers
 			Expression * addrMember = nullptr;             ///< AddressExpr argument is MemberExpr?
+			bool expect_func_type = false;                 ///< used to avoid recursing too deep in type decls
 		};
 
@@ -1277,5 +1276,6 @@
 			FunctionType * ftype = functionDecl->type;
 			if ( ! ftype->returnVals.empty() && functionDecl->statements ) {
-				if ( ! isPrefix( functionDecl->name, "_thunk" ) && ! isPrefix( functionDecl->name, "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors
+				// intrinsic functions won't be using the _retval so no need to generate it.
+				if ( functionDecl->linkage != LinkageSpec::Intrinsic && !isPrefix( functionDecl->name, "_thunk" ) && ! isPrefix( functionDecl->name, "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors
 					assert( ftype->returnVals.size() == 1 );
 					DeclarationWithType * retval = ftype->returnVals.front();
@@ -1418,4 +1418,9 @@
 		void PolyGenericCalculator::beginGenericScope() {
 			GuardScope( *this );
+			// We expect the first function type see to be the type relating to this scope
+			// but any further type is probably some unrelated function pointer
+			// keep track of which is the first
+			GuardValue( expect_func_type );
+			expect_func_type = true;
 		}
 
@@ -1467,4 +1472,21 @@
 		void PolyGenericCalculator::premutate( FunctionType *funcType ) {
 			beginTypeScope( funcType );
+
+			GuardValue( expect_func_type );
+
+			if(!expect_func_type) {
+				GuardAction( [this]() {
+					knownLayouts.endScope();
+					knownOffsets.endScope();
+				});
+				// If this is the first function type we see
+				// Then it's the type of the declaration and we care about it
+				knownLayouts.beginScope();
+				knownOffsets.beginScope();
+			}
+
+			// The other functions type we will see in this scope are probably functions parameters
+			// they don't help us with the layout and offsets so don't mark them as known in this scope
+			expect_func_type = false;
 
 			// make sure that any type information passed into the function is accounted for
@@ -1745,4 +1767,6 @@
 				}
 
+				// std::cout << "TRUE 2" << std::endl;
+
 				return true;
 			} else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 9e23b446e321a87bbf5f2439c8d555a808d5e53c)
+++ src/GenPoly/GenPoly.cc	(revision ffec1bfd5e6f76604c43a28508c5ddcc64bd3218)
@@ -64,5 +64,5 @@
 		}
 
-		__attribute__((ununsed))
+		__attribute__((unused))
 		bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
 			for (auto &param : params) {
