Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision a6f26ca811f428cf8ed8e161488c50c47d54aae5)
+++ src/AST/Expr.hpp	(revision 4e13e2a4b77e6e3f69e8afbd343b850876c48b21)
@@ -541,5 +541,7 @@
 
 	CommaExpr( const CodeLocation & loc, const Expr * a1, const Expr * a2 )
-	: Expr( loc ), arg1( a1 ), arg2( a2 ) {}
+	: Expr( loc ), arg1( a1 ), arg2( a2 ) {
+		this->result = a2->result;
+	}
 
 	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
Index: src/AST/ForallSubstitutionTable.cpp
===================================================================
--- src/AST/ForallSubstitutionTable.cpp	(revision a6f26ca811f428cf8ed8e161488c50c47d54aae5)
+++ src/AST/ForallSubstitutionTable.cpp	(revision 4e13e2a4b77e6e3f69e8afbd343b850876c48b21)
@@ -19,4 +19,5 @@
 #include <vector>
 
+#include "Copy.hpp"                // for shallowCopy
 #include "Decl.hpp"
 #include "Node.hpp"
@@ -26,6 +27,6 @@
 namespace ast {
 
-std::vector< ptr< TypeDecl > > ForallSubstitutionTable::clone( 
-	const std::vector< ptr< TypeDecl > > & forall, Visitor & v 
+std::vector< ptr< TypeDecl > > ForallSubstitutionTable::clone(
+	const std::vector< ptr< TypeDecl > > & forall, Visitor & v
 ) {
 	std::vector< ptr< TypeDecl > > new_forall;
@@ -34,6 +35,5 @@
 	for ( const ast::TypeDecl * d : forall ) {
 		// create cloned type decl and insert into substitution map before further mutation
-		auto new_d = new ast::TypeDecl{
-			d->location, d->name, d->storage, d->base, d->kind, d->sized, d->init };
+		auto new_d = shallowCopy( d );
 		decls.insert( d, new_d );
 		// perform other mutations and add to output
Index: src/ResolvExpr/Candidate.hpp
===================================================================
--- src/ResolvExpr/Candidate.hpp	(revision a6f26ca811f428cf8ed8e161488c50c47d54aae5)
+++ src/ResolvExpr/Candidate.hpp	(revision 4e13e2a4b77e6e3f69e8afbd343b850876c48b21)
@@ -51,14 +51,20 @@
 
 	Candidate( const ast::Expr * x, const ast::TypeEnvironment & e )
-	: expr( x ), cost( Cost::zero ), cvtCost( Cost::zero ), env( e ), open(), need() {}
+	: expr( x ), cost( Cost::zero ), cvtCost( Cost::zero ), env( e ), open(), need() {
+		assert(x->result);
+	}
 
 	Candidate( const Candidate & o, const ast::Expr * x, const Cost & addedCost = Cost::zero )
 	: expr( x ), cost( o.cost + addedCost ), cvtCost( Cost::zero ), env( o.env ), open( o.open ),
-	  need( o.need ) {}
+	  need( o.need ) {
+		assert(x->result);
+	}
 
 	Candidate(
-		const ast::Expr * x, const ast::TypeEnvironment & e, const ast::OpenVarSet & o, 
+		const ast::Expr * x, const ast::TypeEnvironment & e, const ast::OpenVarSet & o,
 		const ast::AssertionSet & n, const Cost & c, const Cost & cvt = Cost::zero )
-	: expr( x ), cost( c ), cvtCost( cvt ), env( e ), open( o ), need( n.begin(), n.end() ) {}
+	: expr( x ), cost( c ), cvtCost( cvt ), env( e ), open( o ), need( n.begin(), n.end() ) {
+		assert(x->result);
+	}
 
 	Candidate(
@@ -66,5 +72,7 @@
 		ast::AssertionSet && n, const Cost & c, const Cost & cvt = Cost::zero )
 	: expr( x ), cost( c ), cvtCost( cvt ), env( std::move( e ) ), open( std::move( o ) ),
-	  need( n.begin(), n.end() ) {}
+	  need( n.begin(), n.end() ) {
+		assert(x->result);
+	}
 };
 
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision a6f26ca811f428cf8ed8e161488c50c47d54aae5)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 4e13e2a4b77e6e3f69e8afbd343b850876c48b21)
@@ -1485,4 +1485,5 @@
 			{
 				ast::ptr< ast::Type > newType = candidate->expr->result;
+				assertf(candidate->expr->result, "Result of expression %p for candidate is null", candidate->expr.get());
 				candidate->env.apply( newType );
 				mangleName = Mangle::mangle( newType );
Index: src/ResolvExpr/RenameVars.cc
===================================================================
--- src/ResolvExpr/RenameVars.cc	(revision a6f26ca811f428cf8ed8e161488c50c47d54aae5)
+++ src/ResolvExpr/RenameVars.cc	(revision 4e13e2a4b77e6e3f69e8afbd343b850876c48b21)
@@ -83,5 +83,5 @@
 			auto it = nameMap.find( type->name );
 			if ( it != nameMap.end() ) {
-				// unconditionally mutate because map will *always* have different name, 
+				// unconditionally mutate because map will *always* have different name,
 				// if this mutates, will *always* have been mutated by ForallSubstitutor above
 				ast::TypeInstType * mut = ast::mutate( type );
@@ -96,5 +96,5 @@
 		const NodeT * openLevel( const NodeT * type ) {
 			if ( type->forall.empty() ) return type;
-			
+
 			nameMap.beginScope();
 
@@ -121,5 +121,5 @@
 		void closeLevel( const ast::ParameterizedType * type ) {
 			if ( type->forall.empty() ) return;
-			
+
 			nameMap.endScope();
 		}
@@ -141,5 +141,5 @@
 		}
 	};
-	
+
 	struct RenameVars_new /*: public ast::WithForallSubstitutor*/ {
 		#warning when old RenameVars goes away, replace hack below with global pass inheriting from WithForallSubstitutor
