Index: src/ResolvExpr/AdjustExprType.cc
===================================================================
--- src/ResolvExpr/AdjustExprType.cc	(revision 00ac42e19976f383d054c37519d503de894b5ba7)
+++ src/ResolvExpr/AdjustExprType.cc	(revision 21300d75a007db91aebde37600bdcb7eeb14a5d5)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// AdjustExprType.cc --
+// AdjustExprType_old.cc --
 //
 // Author           : Richard C. Bilson
@@ -14,4 +14,9 @@
 //
 
+#include "AST/Node.hpp"
+#include "AST/Pass.hpp"
+#include "AST/SymbolTable.hpp"
+#include "AST/Type.hpp"
+#include "AST/TypeEnvironment.hpp"
 #include "Common/PassVisitor.h"
 #include "SymTab/Indexer.h"       // for Indexer
@@ -22,7 +27,9 @@
 
 namespace ResolvExpr {
-	class AdjustExprType : public WithShortCircuiting {
-	  public:
-		AdjustExprType( const TypeEnvironment & env, const SymTab::Indexer & indexer );
+
+namespace {
+	class AdjustExprType_old final : public WithShortCircuiting {
+		public:
+		AdjustExprType_old( const TypeEnvironment & env, const SymTab::Indexer & indexer );
 		void premutate( VoidType * ) { visit_children = false; }
 		void premutate( BasicType * ) { visit_children = false; }
@@ -44,26 +51,14 @@
 		Type * postmutate( TypeInstType *aggregateUseType );
 
-	  private:
+		private:
 		const TypeEnvironment & env;
 		const SymTab::Indexer & indexer;
 	};
 
-	void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
-		PassVisitor<AdjustExprType> adjuster( env, indexer );
-		Type *newType = type->acceptMutator( adjuster );
-		type = newType;
-	}
-
-	void adjustExprType( Type *& type ) {
-		TypeEnvironment env;
-		SymTab::Indexer indexer;
-		adjustExprType( type, env, indexer );
-	}
-
-	AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
+	AdjustExprType_old::AdjustExprType_old( const TypeEnvironment &env, const SymTab::Indexer &indexer )
 		: env( env ), indexer( indexer ) {
 	}
 
-	Type * AdjustExprType::postmutate( ArrayType * arrayType ) {
+	Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) {
 		PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
 		arrayType->base = nullptr;
@@ -72,9 +67,9 @@
 	}
 
-	Type * AdjustExprType::postmutate( FunctionType * functionType ) {
+	Type * AdjustExprType_old::postmutate( FunctionType * functionType ) {
 		return new PointerType{ Type::Qualifiers(), functionType };
 	}
 
-	Type * AdjustExprType::postmutate( TypeInstType * typeInst ) {
+	Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) {
 		if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) {
 			if ( eqvClass->data.kind == TypeDecl::Ftype ) {
@@ -90,4 +85,74 @@
 		return typeInst;
 	}
+} // anonymous namespace
+
+void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+	PassVisitor<AdjustExprType_old> adjuster( env, indexer );
+	Type *newType = type->acceptMutator( adjuster );
+	type = newType;
+}
+
+void adjustExprType( Type *& type ) {
+	TypeEnvironment env;
+	SymTab::Indexer indexer;
+	adjustExprType( type, env, indexer );
+}
+
+namespace {
+	struct AdjustExprType_new final : public ast::WithShortCircuiting {
+		const ast::TypeEnvironment & tenv;
+		const ast::SymbolTable & symtab;
+
+		AdjustExprType_new( const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
+		: tenv( e ), symtab( syms ) {}
+
+		void premutate( const ast::VoidType * ) { visit_children = false; }
+		void premutate( const ast::BasicType * ) { visit_children = false; }
+		void premutate( const ast::PointerType * ) { visit_children = false; }
+		void premutate( const ast::ArrayType * ) { visit_children = false; }
+		void premutate( const ast::FunctionType * ) { visit_children = false; }
+		void premutate( const ast::StructInstType * ) { visit_children = false; }
+		void premutate( const ast::UnionInstType * ) { visit_children = false; }
+		void premutate( const ast::EnumInstType * ) { visit_children = false; }
+		void premutate( const ast::TraitInstType * ) { visit_children = false; }
+		void premutate( const ast::TypeInstType * ) { visit_children = false; }
+		void premutate( const ast::TupleType * ) { visit_children = false; }
+		void premutate( const ast::VarArgsType * ) { visit_children = false; }
+		void premutate( const ast::ZeroType * ) { visit_children = false; }
+		void premutate( const ast::OneType * ) { visit_children = false; }
+
+		const ast::Type * postmutate( const ast::ArrayType * at ) {
+			return new ast::PointerType{ at->base, at->qualifiers };
+		}
+
+		const ast::Type * postmutate( const ast::FunctionType * ft ) {
+			return new ast::PointerType{ ft };
+		}
+
+		const ast::Type * postmutate( const ast::TypeInstType * inst ) {
+			// replace known function-type-variables with pointer-to-function
+			if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name ) ) {
+				if ( eqvClass->data.kind == ast::TypeVar::Ftype ) {
+					return new ast::PointerType{ inst };
+				}
+			} else if ( const ast::NamedTypeDecl * ntDecl = symtab.lookupType( inst->name ) ) {
+				if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( ntDecl ) ) {
+					if ( tyDecl->kind == ast::TypeVar::Ftype ) {
+						return new ast::PointerType{ inst };
+					}
+				}
+			}
+			return inst;
+		}
+	};
+} // anonymous namespace
+
+const ast::Type * adjustExprType( 
+	const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
+) {
+	ast::Pass<AdjustExprType_new> adjuster{ env, symtab };
+	return type->accept( adjuster );
+}
+
 } // namespace ResolvExpr
 
