Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 24ceace338f4f1639e2ade17a788415b9ff66184)
+++ src/AST/Convert.cpp	(revision 7edd5c16a86670fe182e74cbc1238a3335dc5566)
@@ -93,8 +93,8 @@
 	};
 
-    template<typename T>
-    Getter<T> get() {
-        return Getter<T>{ *this };
-    }
+	template<typename T>
+	Getter<T> get() {
+		return Getter<T>{ *this };
+	}
 
 	Label makeLabel(Statement * labelled, const ast::Label& label) {
@@ -1651,4 +1651,5 @@
 			// GET_ACCEPT_1(type, FunctionType),
 			std::move(forall),
+			std::move(assertions),
 			std::move(paramVars),
 			std::move(returnVars),
@@ -1664,5 +1665,4 @@
 		cache.emplace( old, decl );
 
-		decl->assertions = std::move(assertions);
 		decl->withExprs = GET_ACCEPT_V(withExprs, Expr);
 		decl->stmts = GET_ACCEPT_1(statements, CompoundStmt);
Index: src/AST/Copy.cpp
===================================================================
--- src/AST/Copy.cpp	(revision 24ceace338f4f1639e2ade17a788415b9ff66184)
+++ src/AST/Copy.cpp	(revision 7edd5c16a86670fe182e74cbc1238a3335dc5566)
@@ -10,6 +10,6 @@
 // Created On       : Thr Nov 11  9:16:00 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Nov 11  9:28:00 2021
-// Update Count     : 0
+// Last Modified On : Tue May  3 16:28:00 2022
+// Update Count     : 1
 //
 
@@ -77,4 +77,8 @@
 	}
 
+	void postvisit( const UniqueExpr * node ) {
+		readonlyInsert( &node->object );
+	}
+
 	void postvisit( const MemberExpr * node ) {
 		readonlyInsert( &node->member );
Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 24ceace338f4f1639e2ade17a788415b9ff66184)
+++ src/AST/Decl.cpp	(revision 7edd5c16a86670fe182e74cbc1238a3335dc5566)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Thu May 9 10:00:00 2019
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jan 12 16:54:55 2021
-// Update Count     : 23
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu May  5 12:10:00 2022
+// Update Count     : 24
 //
 
@@ -53,5 +53,5 @@
 // --- FunctionDecl
 
-FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name, 
+FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name,
 	std::vector<ptr<TypeDecl>>&& forall,
 	std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
@@ -74,4 +74,30 @@
 	}
 	this->type = ftype;
+}
+
+FunctionDecl::FunctionDecl( const CodeLocation & location, const std::string & name,
+	std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions,
+	std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
+	CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
+	std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)
+: DeclWithType( location, name, storage, linkage, std::move(attrs), fs ),
+		params( std::move(params) ), returns( std::move(returns) ),
+		type_params( std::move( forall) ), assertions( std::move( assertions ) ),
+		type( nullptr ), stmts( stmts ) {
+	FunctionType * type = new FunctionType( (isVarArgs) ? VariableArgs : FixedArgs );
+	for ( auto & param : this->params ) {
+		type->params.emplace_back( param->get_type() );
+	}
+	for ( auto & ret : this->returns ) {
+		type->returns.emplace_back( ret->get_type() );
+	}
+	for ( auto & param : this->type_params ) {
+		type->forall.emplace_back( new TypeInstType( param ) );
+	}
+	for ( auto & assertion : this->assertions ) {
+		type->assertions.emplace_back(
+			new VariableExpr( assertion->location, assertion ) );
+	}
+	this->type = type;
 }
 
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 24ceace338f4f1639e2ade17a788415b9ff66184)
+++ src/AST/Decl.hpp	(revision 7edd5c16a86670fe182e74cbc1238a3335dc5566)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Thu May 9 10:00:00 2019
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Mar 12 18:25:05 2021
-// Update Count     : 32
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu May  5 12:09:00 2022
+// Update Count     : 33
 //
 
@@ -135,10 +135,20 @@
 	std::vector< ptr<Expr> > withExprs;
 
+	// The difference between the two constructors is in how they handle
+	// assertions. The first constructor uses the assertions from the type
+	// parameters, in the style of the old ast, and puts them on the type.
+	// The second takes an explicite list of assertions and builds a list of
+	// references to them on the type.
+
 	FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall,
 		std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
 		CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
 		std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false);
-	// : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),
-	//  stmts( stmts ) {}
+
+	FunctionDecl( const CodeLocation & location, const std::string & name,
+		std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions,
+		std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
+		CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
+		std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false);
 
 	const Type * get_type() const override;
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 24ceace338f4f1639e2ade17a788415b9ff66184)
+++ src/AST/Expr.hpp	(revision 7edd5c16a86670fe182e74cbc1238a3335dc5566)
@@ -784,5 +784,5 @@
 public:
 	ptr<Expr> expr;
-	ptr<ObjectDecl> object;
+	readonly<ObjectDecl> object;
 	ptr<VariableExpr> var;
 	unsigned long long id;
Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision 24ceace338f4f1639e2ade17a788415b9ff66184)
+++ src/AST/Node.hpp	(revision 7edd5c16a86670fe182e74cbc1238a3335dc5566)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 8 10:27:04 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Mar 25 10:33:00 2022
-// Update Count     : 7
+// Last Modified On : Mon May  9 10:20:00 2022
+// Update Count     : 8
 //
 
@@ -49,5 +49,6 @@
 
 	bool unique() const { return strong_count == 1; }
-	bool isManaged() const {return strong_count > 0; }
+	bool isManaged() const { return strong_count > 0; }
+	bool isReferenced() const { return weak_count > 0; }
 
 private:
Index: src/AST/Stmt.cpp
===================================================================
--- src/AST/Stmt.cpp	(revision 24ceace338f4f1639e2ade17a788415b9ff66184)
+++ src/AST/Stmt.cpp	(revision 7edd5c16a86670fe182e74cbc1238a3335dc5566)
@@ -9,12 +9,12 @@
 // Author           : Aaron B. Moss
 // Created On       : Wed May  8 13:00:00 2019
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb  2 19:01:20 2022
-// Update Count     : 3
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue May  3 15:18:20 2022
+// Update Count     : 4
 //
 
 #include "Stmt.hpp"
 
-
+#include "Copy.hpp"
 #include "DeclReplacer.hpp"
 #include "Type.hpp"
@@ -23,5 +23,17 @@
 
 // --- CompoundStmt
-CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids(other.kids) {
+CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids() {
+	// Statements can have weak references to them, if that happens inserting
+	// the original node into the new list will put the original node in a
+	// bad state, where it cannot be mutated. To avoid this, just perform an
+	// additional shallow copy on the statement.
+	for ( const Stmt * kid : other.kids ) {
+		if ( kid->isReferenced() ) {
+			kids.emplace_back( ast::shallowCopy( kid ) );
+		} else {
+			kids.emplace_back( kid );
+		}
+	}
+
 	// when cloning a compound statement, we may end up cloning declarations which
 	// are referred to by VariableExprs throughout the block. Cloning a VariableExpr
