Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/CodeGen/CodeGenerator.cc	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -836,4 +836,9 @@
 		assertf( ! genC, "Deleted expressions should not reach code generation." );
 		expr->expr->accept( *visitor );
+	}
+
+	void CodeGenerator::postvisit( DefaultArgExpr * arg ) {
+		assertf( ! genC, "Default argument expressions should not reach code generation." );
+		arg->expr->accept( *visitor );
 	}
 
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/CodeGen/CodeGenerator.h	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -94,4 +94,5 @@
 		void postvisit( ConstructorExpr * );
 		void postvisit( DeletedExpr * );
+		void postvisit( DefaultArgExpr * );
 		void postvisit( GenericExpr * );
 
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/Common/PassVisitor.h	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -125,4 +125,5 @@
 	virtual void visit( InitExpr *  initExpr ) override final;
 	virtual void visit( DeletedExpr *  delExpr ) override final;
+	virtual void visit( DefaultArgExpr * argExpr ) override final;
 	virtual void visit( GenericExpr * genExpr ) override final;
 
@@ -224,4 +225,5 @@
 	virtual Expression * mutate( InitExpr *  initExpr ) override final;
 	virtual Expression * mutate( DeletedExpr *  delExpr ) override final;
+	virtual Expression * mutate( DefaultArgExpr * argExpr ) override final;
 	virtual Expression * mutate( GenericExpr * genExpr ) override final;
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/Common/PassVisitor.impl.h	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -2084,4 +2084,27 @@
 
 //--------------------------------------------------------------------------
+// DefaultArgExpr
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl( node->expr, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( DefaultArgExpr * node ) {
+	MUTATE_START( node );
+
+	indexerScopedMutate( node->env, *this );
+	indexerScopedMutate( node->result, *this );
+	maybeMutate_impl( node->expr, *this );
+
+	MUTATE_END( Expression, node );
+}
+
+//--------------------------------------------------------------------------
 // GenericExpr
 template< typename pass_type >
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -437,4 +437,11 @@
 				}
 			}
+			if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( *actualExpr ) ) {
+				// default arguments should be free - don't include conversion cost.
+				// Unwrap them here because they are not relevant to the rest of the system.
+				*actualExpr = def->expr;
+				++formal;
+				continue;
+			}
 			Type * formalType = (*formal)->get_type();
 			convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
@@ -872,5 +879,5 @@
 								indexer ) ) {
 							results.emplace_back(
-								i, cnstExpr, move(env), move(need), move(have),
+								i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have),
 								move(openVars), nextArg, nTuples );
 						}
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/SynTree/Expression.cc	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -746,4 +746,19 @@
 	os << std::endl << indent+1 << "... deleted by: ";
 	deleteStmt->print( os, indent+1 );
+}
+
+
+DefaultArgExpr::DefaultArgExpr( Expression * expr ) : expr( expr ) {
+	assert( expr->result );
+	result = expr->result->clone();
+}
+DefaultArgExpr::DefaultArgExpr( const DefaultArgExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ) {}
+DefaultArgExpr::~DefaultArgExpr() {
+	delete expr;
+}
+
+void DefaultArgExpr::print( std::ostream & os, Indenter indent ) const {
+	os << "Default Argument Expression" << std::endl << indent+1;
+	expr->print( os, indent+1 );
 }
 
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/SynTree/Expression.h	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -865,4 +865,19 @@
 };
 
+/// expression wrapping the use of a default argument - should never make it past the resolver.
+class DefaultArgExpr : public Expression {
+public:
+	Expression * expr;
+
+	DefaultArgExpr( Expression * expr );
+	DefaultArgExpr( const DefaultArgExpr & other );
+	~DefaultArgExpr();
+
+	virtual DefaultArgExpr * clone() const { return new DefaultArgExpr( * this ); }
+	virtual void accept( Visitor & v ) { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+};
+
 /// C11 _Generic expression
 class GenericExpr : public Expression {
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/SynTree/Mutator.h	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -93,4 +93,5 @@
 	virtual Expression * mutate( InitExpr  * initExpr ) = 0;
 	virtual Expression * mutate( DeletedExpr * delExpr ) = 0;
+	virtual Expression * mutate( DefaultArgExpr * argExpr ) = 0;
 	virtual Expression * mutate( GenericExpr * genExpr ) = 0;
 
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/SynTree/SynTree.h	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -101,4 +101,5 @@
 class InitExpr;
 class DeletedExpr;
+class DefaultArgExpr;
 class GenericExpr;
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 2a6c11538c985073491173df0fbbc1adc2fdb62b)
+++ src/SynTree/Visitor.h	(revision 0f798534e5e22d73c97f4df465f395acdb91f398)
@@ -95,4 +95,5 @@
 	virtual void visit( InitExpr *  initExpr ) = 0;
 	virtual void visit( DeletedExpr * delExpr ) = 0;
+	virtual void visit( DefaultArgExpr * argExpr ) = 0;
 	virtual void visit( GenericExpr * genExpr ) = 0;
 
