Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision c93bc28fc58cf97703952c9f870947a14d155972)
+++ src/SynTree/Expression.cc	(revision 5ccb10d750e81ef921035bdd254327997acd80ae)
@@ -611,4 +611,5 @@
 CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : initializer( initializer ) {
 	assert( type && initializer );
+	type->set_lvalue( true );
 	set_result( type );
 }
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision c93bc28fc58cf97703952c9f870947a14d155972)
+++ src/SynTree/TupleExpr.cc	(revision 5ccb10d750e81ef921035bdd254327997acd80ae)
@@ -60,5 +60,6 @@
 	assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d in expr %s", type->size(), index, toString( tuple ).c_str() );
 	set_result( (*std::next( type->get_types().begin(), index ))->clone() );
-	get_result()->set_lvalue( type->get_lvalue() );
+	// like MemberExpr, TupleIndexExpr is always an lvalue
+	get_result()->set_lvalue( true );
 }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision c93bc28fc58cf97703952c9f870947a14d155972)
+++ src/SynTree/Type.h	(revision 5ccb10d750e81ef921035bdd254327997acd80ae)
@@ -311,4 +311,9 @@
 	virtual int referenceDepth() const;
 
+	// Since reference types act like value types, their size is the size of the base.
+	// This makes it simple to cast the empty tuple to a reference type, since casts that increase
+	// the number of values are disallowed.
+	virtual unsigned size() const { return base->size(); }
+
 	virtual ReferenceType *clone() const { return new ReferenceType( *this ); }
 	virtual void accept( Visitor & v ) { v.visit( this ); }
