Index: src/AST/Node.cpp
===================================================================
--- src/AST/Node.cpp	(revision 64bdacc7dbbc4c6be28e0673e5190c3a35270510)
+++ src/AST/Node.cpp	(revision f5bace8ecd312e656098f5267daf64c5b419bcb4)
@@ -9,7 +9,7 @@
 // Author           : Thierry Delisle
 // Created On       : Thu May 16 14:16:00 2019
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb  1 09:09:39 2022
-// Update Count     : 3
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Mar 25 10:30:00 2022
+// Update Count     : 4
 //
 
@@ -19,4 +19,5 @@
 #include <csignal>  // MEMORY DEBUG -- for raise
 #include <iostream>
+#include <utility>
 
 #include "Attribute.hpp"
@@ -76,4 +77,11 @@
 void ast::ptr_base<node_t, ref_t>::_check() const {
 	// if(node) assert(node->was_ever_strong == false || node->strong_count > 0);
+}
+
+template< typename node_t, enum ast::Node::ref_type ref_t >
+void ast::ptr_base<node_t, ref_t>::swap( ptr_base & other ) noexcept {
+	std::swap( this->node, other.node );
+	_trap( this->node );
+	_trap( other.node );
 }
 
Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision 64bdacc7dbbc4c6be28e0673e5190c3a35270510)
+++ src/AST/Node.hpp	(revision f5bace8ecd312e656098f5267daf64c5b419bcb4)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 8 10:27:04 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Jun 5 9:47:00 2020
-// Update Count     : 6
+// Last Modified On : Fri Mar 25 10:33:00 2022
+// Update Count     : 7
 //
 
@@ -230,4 +230,7 @@
 	}
 
+	/// Swaps the nodes contained within two pointers.
+	void swap( ptr_base & other ) noexcept;
+
 	const node_t * get() const { _check(); return  node; }
 	const node_t * operator->() const { _check(); return  node; }
@@ -292,4 +295,11 @@
 template< typename node_t >
 using readonly = ptr_base< node_t, Node::ref_type::weak >;
+
+/// Non-member swap that an participate in overload resolution.
+template< typename node_t, enum Node::ref_type ref_t >
+void swap( ptr_base< node_t, ref_t > & l, ptr_base< node_t, ref_t > & r ) {
+	l.swap( r );
+}
+
 }
 
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 64bdacc7dbbc4c6be28e0673e5190c3a35270510)
+++ src/AST/Pass.impl.hpp	(revision f5bace8ecd312e656098f5267daf64c5b419bcb4)
@@ -354,5 +354,5 @@
 			// Take all the elements that are different in 'values'
 			// and swap them into 'container'
-			if( values[i] != nullptr ) std::swap(container[i], values[i]);
+			if( values[i] != nullptr ) swap(container[i], values[i]);
 		}
 
@@ -1054,12 +1054,12 @@
 			auto n = __pass::mutate<core_t>(node);
 			for(size_t i = 0; i < new_clauses.size(); i++) {
-				if(new_clauses.at(i).target.func != nullptr) std::swap(n->clauses.at(i).target.func, new_clauses.at(i).target.func);
+				if(new_clauses.at(i).target.func != nullptr) swap(n->clauses.at(i).target.func, new_clauses.at(i).target.func);
 
 				for(size_t j = 0; j < new_clauses.at(i).target.args.size(); j++) {
-					if(new_clauses.at(i).target.args.at(j) != nullptr) std::swap(n->clauses.at(i).target.args.at(j), new_clauses.at(i).target.args.at(j));
+					if(new_clauses.at(i).target.args.at(j) != nullptr) swap(n->clauses.at(i).target.args.at(j), new_clauses.at(i).target.args.at(j));
 				}
 
-				if(new_clauses.at(i).stmt != nullptr) std::swap(n->clauses.at(i).stmt, new_clauses.at(i).stmt);
-				if(new_clauses.at(i).cond != nullptr) std::swap(n->clauses.at(i).cond, new_clauses.at(i).cond);
+				if(new_clauses.at(i).stmt != nullptr) swap(n->clauses.at(i).stmt, new_clauses.at(i).stmt);
+				if(new_clauses.at(i).cond != nullptr) swap(n->clauses.at(i).cond, new_clauses.at(i).cond);
 			}
 			node = n;
@@ -2151,18 +2151,16 @@
 
 	if ( __visit_children() ) {
-		{
-			bool mutated = false;
-			std::unordered_map< ast::TypeInstType::TypeEnvKey, ast::ptr< ast::Type > > new_map;
-			for ( const auto & p : node->typeEnv ) {
-				guard_symtab guard { *this };
-				auto new_node = p.second->accept( *this );
-				if (new_node != p.second) mutated = true;
-				new_map.insert({ p.first, new_node });
-			}
-			if (mutated) {
-				auto new_node = __pass::mutate<core_t>( node );
-				new_node->typeEnv.swap( new_map );
-				node = new_node;
-			}
+		bool mutated = false;
+		std::unordered_map< ast::TypeInstType::TypeEnvKey, ast::ptr< ast::Type > > new_map;
+		for ( const auto & p : node->typeEnv ) {
+			guard_symtab guard { *this };
+			auto new_node = p.second->accept( *this );
+			if (new_node != p.second) mutated = true;
+			new_map.insert({ p.first, new_node });
+		}
+		if (mutated) {
+			auto new_node = __pass::mutate<core_t>( node );
+			new_node->typeEnv.swap( new_map );
+			node = new_node;
 		}
 	}
Index: src/ResolvExpr/RenameVars.h
===================================================================
--- src/ResolvExpr/RenameVars.h	(revision 64bdacc7dbbc4c6be28e0673e5190c3a35270510)
+++ src/ResolvExpr/RenameVars.h	(revision f5bace8ecd312e656098f5267daf64c5b419bcb4)
@@ -36,10 +36,7 @@
 	};
 	const ast::Type * renameTyVars( const ast::Type *, RenameMode mode = GEN_USAGE, bool reset = true );
-	
 
 	/// resets internal state of renamer to avoid overflow
 	void resetTyVarRenaming();
-
-	
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision 64bdacc7dbbc4c6be28e0673e5190c3a35270510)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision f5bace8ecd312e656098f5267daf64c5b419bcb4)
@@ -169,5 +169,4 @@
 
 struct FixArrayDimension {
-	// should not require a mutable symbol table - prevent pass template instantiation
 	const ResolveContext & context;
 	FixArrayDimension(const ResolveContext & context) : context( context ) {}
@@ -196,35 +195,23 @@
 
 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) {
-	if (!decl->isTypeFixed) {
-		auto mutDecl = mutate(decl);
+	if (decl->isTypeFixed) {
+		return decl;
+	}
+
+	auto mutDecl = mutate(decl);
+	{
 		auto resolvedType = resolveTypeof(decl->type, context);
 		resolvedType = fixArrayType(resolvedType, context);
 		mutDecl->type = resolvedType;
-
-		// check variable length if object is an array.
-		// xxx - should this be part of fixObjectType?
-
-		/*
-		if (auto arrayType = dynamic_cast<const ast::ArrayType *>(resolvedType)) {
-			auto dimExpr = findSingleExpression(arrayType->dimension, ast::sizeType, symtab);
-			if (auto varexpr = arrayType->dimension.as<ast::VariableExpr>()) {// hoisted previously
-				if (InitTweak::isConstExpr(varexpr->var.strict_as<ast::ObjectDecl>()->init)) {
-					auto mutType = mutate(arrayType);
-					mutType->isVarLen = ast::LengthFlag::VariableLen;
-					mutDecl->type = mutType;
-				}
-			}
-		}
-		*/
-
-
-		if (!mutDecl->name.empty()) 
-			mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables
-		
-		mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
-		mutDecl->isTypeFixed = true;
-		return mutDecl;
-	}
-	return decl;
+	}
+
+	// Do not mangle unnamed variables.
+	if (!mutDecl->name.empty()) {
+		mutDecl->mangleName = Mangle::mangle(mutDecl);
+	}
+
+	mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
+	mutDecl->isTypeFixed = true;
+	return mutDecl;
 }
 
Index: src/ResolvExpr/ResolveTypeof.h
===================================================================
--- src/ResolvExpr/ResolveTypeof.h	(revision 64bdacc7dbbc4c6be28e0673e5190c3a35270510)
+++ src/ResolvExpr/ResolveTypeof.h	(revision f5bace8ecd312e656098f5267daf64c5b419bcb4)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ResolveTypeof.h -- 
+// ResolveTypeof.h --
 //
 // Author           : Richard C. Bilson
