Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/CodeGen/CodeGenerator.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -656,5 +656,7 @@
 	}
 
-	void CodeGenerator::visit( TupleExpr * tupleExpr ) { assert( false ); }
+	void CodeGenerator::visit( UntypedTupleExpr * tupleExpr ) { assertf( false, "UntypedTupleExpr should not make it to Code Gen" ); }
+
+	void CodeGenerator::visit( TupleExpr * tupleExpr ) { assertf( false, "TupleExpr should not make it to Code Gen" ); }
 
 	void CodeGenerator::visit( TypeExpr * typeExpr ) {}
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/CodeGen/CodeGenerator.h	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -72,4 +72,5 @@
 		virtual void visit( CommaExpr *commaExpr );
 		virtual void visit( CompoundLiteralExpr *compLitExpr );
+		virtual void visit( UntypedTupleExpr *tupleExpr );
 		virtual void visit( TupleExpr *tupleExpr );
 		virtual void visit( TypeExpr *typeExpr );
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/InitTweak/InitTweak.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -487,4 +487,5 @@
 		virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }
 		virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
+		virtual void visit( UntypedTupleExpr *tupleExpr ) { isConstExpr = false; }
 		virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
 		virtual void visit( TupleAssignExpr *tupleExpr ) { isConstExpr = false; }
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/Parser/ExpressionNode.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -323,7 +323,7 @@
 
 Expression *build_tuple( ExpressionNode * expr_node ) {
-	TupleExpr *ret = new TupleExpr();
-	buildMoveList( expr_node, ret->get_exprs() );
-	return ret;
+	std::list< Expression * > exprs;
+	buildMoveList( expr_node, exprs );
+	return new UntypedTupleExpr( exprs );;
 }
 
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -351,13 +351,12 @@
 		if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
 			// formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
-			TupleExpr * tupleExpr = new TupleExpr();
+			std::list< Expression * > exprs;
 			for ( Type * type : *tupleType ) {
-				if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) {
-					delete tupleExpr;
+				if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs ) ) ) {
+					deleteAll( exprs );
 					return false;
 				}
 			}
-			tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) );
-			*out++ = tupleExpr;
+			*out++ = new TupleExpr( exprs );
 		} else if ( actualIt != actualEnd ) {
 			if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {
@@ -1058,5 +1057,5 @@
 	}
 
-	void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
+	void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {
 		std::list< AlternativeFinder > subExprAlternatives;
 		findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
@@ -1064,12 +1063,15 @@
 		combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
 		for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
-			TupleExpr *newExpr = new TupleExpr;
-			makeExprList( *i, newExpr->get_exprs() );
-			newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
+			std::list< Expression * > exprs;
+			makeExprList( *i, exprs );
 
 			TypeEnvironment compositeEnv;
 			simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
-			alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
+			alternatives.push_back( Alternative( new TupleExpr( exprs ) , compositeEnv, sumCost( *i ) ) );
 		} // for
+	}
+
+	void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
+		alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
 	}
 
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -64,7 +64,8 @@
 		virtual void visit( ConditionalExpr *conditionalExpr );
 		virtual void visit( CommaExpr *commaExpr );
-		virtual void visit( TupleExpr *tupleExpr );
 		virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
 		virtual void visit( ConstructorExpr * ctorExpr );
+		virtual void visit( UntypedTupleExpr *tupleExpr );
+		virtual void visit( TupleExpr *tupleExpr );
 		virtual void visit( TupleIndexExpr *tupleExpr );
 		virtual void visit( TupleAssignExpr *tupleExpr );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SymTab/Indexer.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -453,14 +453,4 @@
 	}
 
-	void Indexer::visit( TupleExpr *tupleExpr ) {
-		acceptNewScope( tupleExpr->get_result(), *this );
-		acceptAll( tupleExpr->get_exprs(), *this );
-	}
-
-	void Indexer::visit( TupleAssignExpr *tupleExpr ) {
-		acceptNewScope( tupleExpr->get_result(), *this );
-		maybeAccept( tupleExpr->get_stmtExpr(), *this );
-	}
-
 	void Indexer::visit( TypeExpr *typeExpr ) {
 		acceptNewScope( typeExpr->get_result(), *this );
@@ -474,7 +464,69 @@
 	}
 
+	void Indexer::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
+		acceptNewScope( impCpCtorExpr->get_result(), *this );
+		maybeAccept( impCpCtorExpr->get_callExpr(), *this );
+		acceptAll( impCpCtorExpr->get_tempDecls(), *this );
+		acceptAll( impCpCtorExpr->get_returnDecls(), *this );
+		acceptAll( impCpCtorExpr->get_dtors(), *this );
+	}
+
+	void Indexer::visit( ConstructorExpr * ctorExpr ) {
+		acceptNewScope( ctorExpr->get_result(), *this );
+		maybeAccept( ctorExpr->get_callExpr(), *this );
+	}
+
+	void Indexer::visit( CompoundLiteralExpr *compLitExpr ) {
+		acceptNewScope( compLitExpr->get_result(), *this );
+		maybeAccept( compLitExpr->get_type(), *this );
+		maybeAccept( compLitExpr->get_initializer(), *this );
+	}
+
 	void Indexer::visit( UntypedValofExpr *valofExpr ) {
 		acceptNewScope( valofExpr->get_result(), *this );
 		maybeAccept( valofExpr->get_body(), *this );
+	}
+
+	void Indexer::visit( RangeExpr *rangeExpr ) {
+		maybeAccept( rangeExpr->get_low(), *this );
+		maybeAccept( rangeExpr->get_high(), *this );
+	}
+
+	void Indexer::visit( UntypedTupleExpr *tupleExpr ) {
+		acceptNewScope( tupleExpr->get_result(), *this );
+		acceptAll( tupleExpr->get_exprs(), *this );
+	}
+
+	void Indexer::visit( TupleExpr *tupleExpr ) {
+		acceptNewScope( tupleExpr->get_result(), *this );
+		acceptAll( tupleExpr->get_exprs(), *this );
+	}
+
+	void Indexer::visit( TupleIndexExpr *tupleExpr ) {
+		acceptNewScope( tupleExpr->get_result(), *this );
+		maybeAccept( tupleExpr->get_tuple(), *this );
+	}
+
+	void Indexer::visit( MemberTupleExpr *tupleExpr ) {
+		acceptNewScope( tupleExpr->get_result(), *this );
+		maybeAccept( tupleExpr->get_member(), *this );
+		maybeAccept( tupleExpr->get_aggregate(), *this );
+	}
+
+	void Indexer::visit( TupleAssignExpr *tupleExpr ) {
+		acceptNewScope( tupleExpr->get_result(), *this );
+		maybeAccept( tupleExpr->get_stmtExpr(), *this );
+	}
+
+	void Indexer::visit( StmtExpr *stmtExpr ) {
+		acceptNewScope( stmtExpr->get_result(), *this );
+		maybeAccept( stmtExpr->get_statements(), *this );
+		acceptAll( stmtExpr->get_returnDecls(), *this );
+		acceptAll( stmtExpr->get_dtors(), *this );
+	}
+
+	void Indexer::visit( UniqueExpr *uniqueExpr ) {
+		acceptNewScope( uniqueExpr->get_result(), *this );
+		maybeAccept( uniqueExpr->get_expr(), *this );
 	}
 
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SymTab/Indexer.h	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -66,7 +66,16 @@
 		virtual void visit( TypeExpr *typeExpr );
 		virtual void visit( AsmExpr *asmExpr );
+		virtual void visit( ImplicitCopyCtorExpr *impCpCtorExpr );
+		virtual void visit( ConstructorExpr * ctorExpr );
+		virtual void visit( CompoundLiteralExpr *compLitExpr );
 		virtual void visit( UntypedValofExpr *valofExpr );
+		virtual void visit( RangeExpr *rangeExpr );
+		virtual void visit( UntypedTupleExpr *tupleExpr );
 		virtual void visit( TupleExpr *tupleExpr );
+		virtual void visit( TupleIndexExpr *tupleExpr );
+		virtual void visit( MemberTupleExpr *tupleExpr );
 		virtual void visit( TupleAssignExpr *tupleExpr );
+		virtual void visit( StmtExpr * stmtExpr );
+		virtual void visit( UniqueExpr * uniqueExpr );
 
 		virtual void visit( TraitInstType *contextInst );
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SynTree/Expression.h	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -634,12 +634,28 @@
 };
 
+/// UntypedTupleExpr represents a tuple expression ( [a, b, c] ) before resolution
+class UntypedTupleExpr : public Expression {
+  public:
+	UntypedTupleExpr( const std::list< Expression * > & exprs, Expression *_aname = nullptr );
+	UntypedTupleExpr( const UntypedTupleExpr &other );
+	virtual ~UntypedTupleExpr();
+
+	std::list<Expression*>& get_exprs() { return exprs; }
+
+	virtual UntypedTupleExpr *clone() const { return new UntypedTupleExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	std::list<Expression*> exprs;
+};
+
 /// TupleExpr represents a tuple expression ( [a, b, c] )
 class TupleExpr : public Expression {
   public:
-	TupleExpr( const std::list< Expression * > & exprs = std::list< Expression * >(), Expression *_aname = nullptr );
+	TupleExpr( const std::list< Expression * > & exprs, Expression *_aname = nullptr );
 	TupleExpr( const TupleExpr &other );
 	virtual ~TupleExpr();
 
-	void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
 	std::list<Expression*>& get_exprs() { return exprs; }
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SynTree/Mutator.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -345,4 +345,5 @@
 Expression* Mutator::mutate( ImplicitCopyCtorExpr *impCpCtorExpr ) {
 	impCpCtorExpr->set_env( maybeMutate( impCpCtorExpr->get_env(), *this ) );
+	impCpCtorExpr->set_result( maybeMutate( impCpCtorExpr->get_result(), *this ) );
 	impCpCtorExpr->set_callExpr( maybeMutate( impCpCtorExpr->get_callExpr(), *this ) );
 	mutateAll( impCpCtorExpr->get_tempDecls(), *this );
@@ -378,4 +379,11 @@
 	rangeExpr->set_high( maybeMutate( rangeExpr->get_high(), *this ) );
 	return rangeExpr;
+}
+
+Expression *Mutator::mutate( UntypedTupleExpr *tupleExpr ) {
+	tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
+	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
+	mutateAll( tupleExpr->get_exprs(), *this );
+	return tupleExpr;
 }
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SynTree/Mutator.h	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -78,4 +78,5 @@
 	virtual Expression* mutate( UntypedValofExpr *valofExpr );
 	virtual Expression* mutate( RangeExpr *rangeExpr );
+	virtual Expression* mutate( UntypedTupleExpr *tupleExpr );
 	virtual Expression* mutate( TupleExpr *tupleExpr );
 	virtual Expression* mutate( TupleIndexExpr *tupleExpr );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SynTree/SynTree.h	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -83,4 +83,5 @@
 class UntypedValofExpr;
 class RangeExpr;
+class UntypedTupleExpr;
 class TupleExpr;
 class TupleIndexExpr;
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SynTree/TupleExpr.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -21,10 +21,23 @@
 #include "VarExprReplacer.h"
 
+UntypedTupleExpr::UntypedTupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) {
+}
+
+UntypedTupleExpr::UntypedTupleExpr( const UntypedTupleExpr &other ) : Expression( other ) {
+	cloneAll( other.exprs, exprs );
+}
+
+UntypedTupleExpr::~UntypedTupleExpr() {
+	deleteAll( exprs );
+}
+
+void UntypedTupleExpr::print( std::ostream &os, int indent ) const {
+	os << "Untyped Tuple:" << std::endl;
+	printAll( exprs, os, indent+2 );
+	Expression::print( os, indent );
+}
+
 TupleExpr::TupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) {
-	if ( ! exprs.empty() ) {
-		if ( std::all_of( exprs.begin(), exprs.end(), [](Expression * expr) { return expr->get_result(); } ) ) {
-			set_result( Tuples::makeTupleType( exprs ) );
-		}
-	}
+	set_result( Tuples::makeTupleType( exprs ) );
 }
 
@@ -45,5 +58,5 @@
 TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) : tuple( tuple ), index( index )  {
 	TupleType * type = safe_dynamic_cast< TupleType * >( tuple->get_result() );
-	assert( type->size() > index );
+	assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d", type->size(), index );
 	set_result( (*std::next( type->get_types().begin(), index ))->clone() );
 	get_result()->set_isLvalue( type->get_isLvalue() );
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SynTree/Visitor.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -273,4 +273,5 @@
 
 void Visitor::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
+	maybeAccept( impCpCtorExpr->get_result(), *this );
 	maybeAccept( impCpCtorExpr->get_callExpr(), *this );
 	acceptAll( impCpCtorExpr->get_tempDecls(), *this );
@@ -298,4 +299,9 @@
 	maybeAccept( rangeExpr->get_low(), *this );
 	maybeAccept( rangeExpr->get_high(), *this );
+}
+
+void Visitor::visit( UntypedTupleExpr *tupleExpr ) {
+	maybeAccept( tupleExpr->get_result(), *this );
+	acceptAll( tupleExpr->get_exprs(), *this );
 }
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/SynTree/Visitor.h	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -78,4 +78,5 @@
 	virtual void visit( UntypedValofExpr *valofExpr );
 	virtual void visit( RangeExpr *rangeExpr );
+	virtual void visit( UntypedTupleExpr *tupleExpr );
 	virtual void visit( TupleExpr *tupleExpr );
 	virtual void visit( TupleIndexExpr *tupleExpr );
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision 0c286cfb20d6d3d7349e7b9e1173b377dba3fa2c)
+++ src/Tuples/TupleExpansion.cc	(revision 907eccb29a08fe51aa5e5c20aa28f841482b4436)
@@ -144,5 +144,5 @@
 
 	Expression * MemberTupleExpander::mutate( UntypedMemberExpr * memberExpr ) {
-		if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * > ( memberExpr->get_member() ) ) {
+		if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr->get_member() ) ) {
 			Expression * aggr = memberExpr->get_aggregate()->clone()->acceptMutator( *this );
 			// aggregate expressions which might be impure must be wrapped in unique expressions
@@ -315,4 +315,5 @@
 			qualifiers &= type->get_qualifiers();
 		} // for
+		if ( exprs.empty() ) qualifiers = Type::Qualifiers();
 		return tupleType;
 	}
