Index: src/Tuples/Explode.h
===================================================================
--- src/Tuples/Explode.h	(revision 6242335009c5d2ebee1bb50d1d228f5aacb0e5bd)
+++ src/Tuples/Explode.h	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -27,25 +27,7 @@
 
 namespace Tuples {
-	/// helper function used by explode to properly distribute
-	/// '&' across a tuple expression
-	Expression * distributeAddr( Expression * expr );
-
 	/// helper function used by explode
 	template< typename OutputIterator >
 	void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
-		if ( isTupleAssign ) {
-			// tuple assignment needs AddressExprs to be recursively exploded to easily get at all of the components
-			if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
-				ResolvExpr::AltList alts;
-				explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
-				for ( ResolvExpr::Alternative & alt : alts ) {
-					// distribute '&' over all components
-					alt.expr = distributeAddr( alt.expr );
-					*out++ = alt;
-				}
-				// in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
-				return;
-			}
-		}
 		Type * res = expr->get_result();
 		if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 6242335009c5d2ebee1bb50d1d228f5aacb0e5bd)
+++ src/Tuples/TupleAssignment.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -77,5 +77,5 @@
 		if ( ! expr ) return false;
 		assert( expr->has_result() );
-		return dynamic_cast< TupleType * >( expr->get_result() );
+		return dynamic_cast< TupleType * >( expr->get_result()->stripReferences() );
 	}
 
@@ -89,10 +89,11 @@
 	}
 
-	bool pointsToTuple( Expression *expr ) {
+	bool refToTuple( Expression *expr ) {
+		assert( expr->get_result() );
 		// also check for function returning tuple of reference types
 		if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
-			return pointsToTuple( castExpr->get_arg() );
-		} else if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) {
-			return isTuple( addr->get_arg() );
+			return refToTuple( castExpr->get_arg() );
+		} else {
+			return isTuple( expr );
 		}
 		return false;
@@ -122,5 +123,5 @@
 					const ResolvExpr::Alternative & alt1 = ali->front();
 					auto begin = std::next(ali->begin(), 1), end = ali->end();
-					if ( pointsToTuple(alt1.expr) ) {
+					if ( refToTuple(alt1.expr) ) {
 						if ( isMultAssign( begin, end ) ) {
 							matcher.reset( new MultipleAssignMatcher( *this, *ali ) );
@@ -196,10 +197,7 @@
 			for ( ResolvExpr::Alternative & alt : lhs ) {
 				Expression *& expr = alt.expr;
-				Type * castType = expr->get_result()->clone();
-				Type * type = InitTweak::getPointerBase( castType );
-				assert( type );
+				Type * type = expr->get_result()->clone();
 				type->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
-				type->set_lvalue( true ); // xxx - might not need this
-				expr = new CastExpr( expr, castType );
+				expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), type ) );
 			}
 		}
@@ -221,5 +219,5 @@
 		assert( left );
 		std::list< Expression * > args;
-		args.push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( left ) ) ) );
+		args.push_back( new VariableExpr( left ) );
 		// args.push_back( new AddressExpr( new VariableExpr( left ) ) );
 		if ( right ) args.push_back( new VariableExpr( right ) );
@@ -241,9 +239,12 @@
 		assert( expr->has_result() && ! expr->get_result()->isVoid() );
 		ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
-		ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
-		ret->set_init( ctorInit );
-		ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
-		EnvRemover rm; // remove environments from subexpressions of StmtExprs
-		ctorInit->accept( rm );
+		// if expression type is a reference, don't need to construct anything, a simple initializer is sufficient.
+		if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
+			ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
+			ret->set_init( ctorInit );
+			ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
+			EnvRemover rm; // remove environments from subexpressions of StmtExprs
+			ctorInit->accept( rm );
+		}
 		return ret;
 	}
