Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 4d860ea34731ff1d6c9c167ea3410d0e077fd040)
+++ src/CodeGen/CodeGenerator.cc	(revision d3652dff49964cd0e31a788e5a2cfb4c84d10393)
@@ -1157,9 +1157,9 @@
 
 	void CodeGenerator::postvisit( WithStmt * with ) {
-		if ( ! options.genC ) {
-			output << "with ( ";
-			genCommaList( with->exprs.begin(), with->exprs.end() );
-			output << " ) ";
-		}
+		assertf( ! options.genC, "WithStmts should not reach code generation." );
+
+		output << "with ( ";
+		genCommaList( with->exprs.begin(), with->exprs.end() );
+		output << " ) ";
 		with->stmt->accept( *visitor );
 	}
Index: src/GenPoly/BoxNew.cpp
===================================================================
--- src/GenPoly/BoxNew.cpp	(revision 4d860ea34731ff1d6c9c167ea3410d0e077fd040)
+++ src/GenPoly/BoxNew.cpp	(revision d3652dff49964cd0e31a788e5a2cfb4c84d10393)
@@ -1726,16 +1726,4 @@
 
 // --------------------------------------------------------------------------
-// TODO: This is kind of a blind test. I believe all withExprs are handled
-// in the resolver and we could clear them out after that.
-struct RemoveWithExprs final {
-	ast::FunctionDecl const * postvisit( ast::FunctionDecl const * decl ) {
-		if ( decl->withExprs.empty() ) return decl;
-		auto mutDecl = mutate( decl );
-		mutDecl->withExprs.clear();
-		return mutDecl;
-	}
-};
-
-// --------------------------------------------------------------------------
 /// Inserts code to access polymorphic layout inforation.
 /// * Replaces member and size/alignment/offsetof expressions on polymorphic
@@ -2511,5 +2499,4 @@
 	ast::Pass<DeclAdapter>::run( translationUnit );
 	ast::Pass<RewireAdapters>::run( translationUnit );
-	ast::Pass<RemoveWithExprs>::run( translationUnit );
 	ast::Pass<PolyGenericCalculator>::run( translationUnit );
 	ast::Pass<Eraser>::run( translationUnit );
Index: src/ResolvExpr/EraseWith.cpp
===================================================================
--- src/ResolvExpr/EraseWith.cpp	(revision d3652dff49964cd0e31a788e5a2cfb4c84d10393)
+++ src/ResolvExpr/EraseWith.cpp	(revision d3652dff49964cd0e31a788e5a2cfb4c84d10393)
@@ -0,0 +1,46 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// EraseWith.cpp -- After resolution, erase all with constructs.
+//
+// Author           : Andrew Beach
+// Created On       : Sun Oct  8  9:42:00 2023
+// Last Modified By : Andrew Beach
+// Last Modified On : Sun Oct  8 10:03:00 2023
+// Update Count     : 0
+//
+
+#include "EraseWith.hpp"
+
+#include "AST/Decl.hpp"
+#include "AST/Pass.hpp"
+#include "AST/Stmt.hpp"
+
+namespace ResolvExpr {
+
+namespace {
+
+struct WithEraser {
+	ast::FunctionDecl const * postvisit( ast::FunctionDecl const * decl ) {
+		if ( decl->withExprs.empty() ) return decl;
+		auto mutDecl = mutate( decl );
+		mutDecl->withExprs.clear();
+		return mutDecl;
+	}
+
+	ast::Stmt const * postvisit( ast::DeclStmt const * stmt ) {
+		if ( auto decl = stmt->decl.as<ast::WithStmt>() ) return decl->stmt;
+		return stmt;
+	}
+};
+
+} // namespace
+
+void eraseWith( ast::TranslationUnit & translationUnit ) {
+	ast::Pass<WithEraser>::run( translationUnit );
+}
+
+} // namespace ResolvExpr
Index: src/ResolvExpr/EraseWith.hpp
===================================================================
--- src/ResolvExpr/EraseWith.hpp	(revision d3652dff49964cd0e31a788e5a2cfb4c84d10393)
+++ src/ResolvExpr/EraseWith.hpp	(revision d3652dff49964cd0e31a788e5a2cfb4c84d10393)
@@ -0,0 +1,29 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// EraseWith.hpp -- After resolution, erase all with constructs.
+//
+// Author           : Andrew Beach
+// Created On       : Sun Oct  8  9:36:00 2023
+// Last Modified By : Andrew Beach
+// Last Modified On : Sun Oct  8  9:47:00 2023
+// Update Count     : 0
+//
+
+#pragma once
+
+namespace ast {
+	class TranslationUnit;
+}
+
+namespace ResolvExpr {
+
+void eraseWith( ast::TranslationUnit & translationUnit );
+/// Remove withExprs from functions and any WithStmt nodes.
+/// This must be done after all resolution that needs to see the names from
+/// a with. We put it after the last pass to use WithSymbolTable.
+
+}
Index: src/ResolvExpr/module.mk
===================================================================
--- src/ResolvExpr/module.mk	(revision 4d860ea34731ff1d6c9c167ea3410d0e077fd040)
+++ src/ResolvExpr/module.mk	(revision d3652dff49964cd0e31a788e5a2cfb4c84d10393)
@@ -72,5 +72,7 @@
 	ResolvExpr/AlternativePrinter.h \
 	ResolvExpr/CandidatePrinter.cpp \
-	ResolvExpr/CandidatePrinter.hpp
+	ResolvExpr/CandidatePrinter.hpp \
+	ResolvExpr/EraseWith.cpp \
+	ResolvExpr/EraseWith.hpp
 
 SRCDEMANGLE += $(SRC_RESOLVEXPR)
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 4d860ea34731ff1d6c9c167ea3410d0e077fd040)
+++ src/main.cc	(revision d3652dff49964cd0e31a788e5a2cfb4c84d10393)
@@ -62,4 +62,5 @@
 #include "Parser/RunParser.hpp"             // for buildList, dumpParseTree,...
 #include "ResolvExpr/CandidatePrinter.hpp"  // for printCandidates
+#include "ResolvExpr/EraseWith.hpp"         // for eraseWith
 #include "ResolvExpr/Resolver.h"            // for resolve
 #include "SynTree/LinkageSpec.h"            // for Spec, Cforall, Intrinsic
@@ -396,4 +397,5 @@
 
 		PASS( "Fix Init", InitTweak::fix, transUnit, buildingLibrary() );
+		PASS( "Erase With", ResolvExpr::eraseWith, transUnit );
 
 		// fix ObjectDecl - replaces ConstructorInit nodes
