Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 02cea2d984751c7c758ec159716a71562ab4c9f7)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision b6fe7e6c491f467e31d7ef488c6c0c23df6534a8)
@@ -197,5 +197,5 @@
 	}
 
-	void AlternativeFinder::find( Expression *expr, bool adjust ) {
+	void AlternativeFinder::find( Expression *expr, bool adjust, bool prune ) {
 		expr->accept( *this );
 		if ( alternatives.empty() ) {
@@ -207,24 +207,26 @@
 			}
 		}
-		PRINT(
-			std::cerr << "alternatives before prune:" << std::endl;
-			printAlts( alternatives, std::cerr );
-		)
-		AltList::iterator oldBegin = alternatives.begin();
-		pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
-		if ( alternatives.begin() == oldBegin ) {
-			std::ostringstream stream;
-			stream << "Can't choose between alternatives for expression ";
-			expr->print( stream );
-			stream << "Alternatives are:";
-			AltList winners;
-			findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
-			printAlts( winners, stream, 8 );
-			throw SemanticError( stream.str() );
-		}
-		alternatives.erase( oldBegin, alternatives.end() );
-		PRINT(
-			std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
-		)
+		if ( prune ) {
+			PRINT(
+				std::cerr << "alternatives before prune:" << std::endl;
+				printAlts( alternatives, std::cerr );
+			)
+			AltList::iterator oldBegin = alternatives.begin();
+			pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
+			if ( alternatives.begin() == oldBegin ) {
+				std::ostringstream stream;
+				stream << "Can't choose between alternatives for expression ";
+				expr->print( stream );
+				stream << "Alternatives are:";
+				AltList winners;
+				findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
+				printAlts( winners, stream, 8 );
+				throw SemanticError( stream.str() );
+			}
+			alternatives.erase( oldBegin, alternatives.end() );
+			PRINT(
+				std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
+			)
+		}
 
 		// Central location to handle gcc extension keyword for all expression types.
@@ -234,10 +236,10 @@
 	}
 
-	void AlternativeFinder::findWithAdjustment( Expression *expr ) {
-		find( expr, true );
+	void AlternativeFinder::findWithAdjustment( Expression *expr, bool prune ) {
+		find( expr, true, prune );
 	}
 
 	template< typename StructOrUnionType >
-	void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name ) {
+	void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
 		std::list< Declaration* > members;
 		aggInst->lookup( name, members );
@@ -760,7 +762,7 @@
 			if ( agg->expr->get_results().size() == 1 ) {
 				if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
-					addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() );
+					addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
 				} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
-					addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() );
+					addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
 				} // if
 			} // if
@@ -789,7 +791,7 @@
 			renameTypes( alternatives.back().expr );
 			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
-				addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), "" );
+				addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
 			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
-				addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), "" );
+				addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
 			} // if
 		} // for
@@ -1012,4 +1014,14 @@
 		alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
 	}
+
+	void AlternativeFinder::visit( ConstructorExpr * ctorExpr ) {
+		AlternativeFinder finder( indexer, env );
+		// don't prune here, since it's guaranteed all alternatives will have the same type
+		// (giving the alternatives different types is half of the point of ConstructorExpr nodes)
+		finder.findWithAdjustment( ctorExpr->get_callExpr(), false );
+		for ( Alternative & alt : finder.alternatives ) {
+			alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) );
+		}
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 02cea2d984751c7c758ec159716a71562ab4c9f7)
+++ src/ResolvExpr/AlternativeFinder.h	(revision b6fe7e6c491f467e31d7ef488c6c0c23df6534a8)
@@ -29,7 +29,7 @@
 	  public:
 		AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env );
-		void find( Expression *expr, bool adjust = false );
+		void find( Expression *expr, bool adjust = false, bool prune = true );
 		/// Calls find with the adjust flag set; adjustment turns array and function types into equivalent pointer types
-		void findWithAdjustment( Expression *expr );
+		void findWithAdjustment( Expression *expr, bool prune = true );
 		AltList &get_alternatives() { return alternatives; }
 
@@ -66,4 +66,5 @@
 		virtual void visit( TupleExpr *tupleExpr );
 		virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
+		virtual void visit( ConstructorExpr * ctorExpr );
 	  public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
 		template< typename InputIterator, typename OutputIterator >
@@ -72,5 +73,5 @@
 	  private:
 		/// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
-		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name );
+		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name );
 		/// Adds alternatives for offsetof expressions, given the base type and name of the member
 		template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
