@@ -53,7 +53,6 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
5353 // Find the actual method implementation being called and
5454 // build the appropriate UFCS call expression with the
5555 // callee-object as self parameter.
56-
5756 let method = method_callee ( cx, self , ty:: MethodCall :: expr ( self . id ) ) ;
5857 let mut argrefs = vec ! [ fun. to_ref( ) ] ;
5958 argrefs. extend ( args. iter ( ) . map ( |a| a. to_ref ( ) ) ) ;
@@ -64,12 +63,40 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
6463 args : argrefs,
6564 }
6665 } else {
67- ExprKind :: Call {
68- ty : & cx. tcx . node_id_to_type ( fun. id ) ,
69- fun : fun. to_ref ( ) ,
70- args : args. to_ref ( ) ,
66+ let adt_data = if let hir:: ExprPath ( ..) = fun. node {
67+ // Tuple-like ADTs are represented as ExprCall. We convert them here.
68+ expr_ty. ty_adt_def ( ) . and_then ( |adt_def|{
69+ match cx. tcx . def_map . borrow ( ) [ & fun. id ] . full_def ( ) {
70+ def:: DefVariant ( _, variant_id, false ) => {
71+ Some ( ( adt_def, adt_def. variant_index_with_id ( variant_id) ) )
72+ } ,
73+ def:: DefStruct ( _) => {
74+ Some ( ( adt_def, 0 ) )
75+ } ,
76+ _ => None
77+ }
78+ } )
79+ } else { None } ;
80+ if let Some ( ( adt_def, index) ) = adt_data {
81+ let substs = cx. tcx . mk_substs ( cx. tcx . node_id_item_substs ( fun. id ) . substs ) ;
82+ let field_refs = args. iter ( ) . enumerate ( ) . map ( |( idx, e) | FieldExprRef {
83+ name : Field :: new ( idx) ,
84+ expr : e. to_ref ( )
85+ } ) . collect ( ) ;
86+ ExprKind :: Adt {
87+ adt_def : adt_def,
88+ substs : substs,
89+ variant_index : index,
90+ fields : field_refs,
91+ base : None
92+ }
93+ } else {
94+ ExprKind :: Call {
95+ ty : cx. tcx . node_id_to_type ( fun. id ) ,
96+ fun : fun. to_ref ( ) ,
97+ args : args. to_ref ( ) ,
98+ }
7199 }
72-
73100 }
74101 }
75102
@@ -549,10 +576,11 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
549576 def:: DefFn ( def_id, _) => ( def_id, ItemKind :: Function ) ,
550577 def:: DefMethod ( def_id) => ( def_id, ItemKind :: Method ) ,
551578 def:: DefStruct ( def_id) => match cx. tcx . node_id_to_type ( expr. id ) . sty {
552- // A tuple-struct constructor.
579+ // A tuple-struct constructor. Should only be reached if not called in the same
580+ // expression.
553581 ty:: TyBareFn ( ..) => ( def_id, ItemKind :: Function ) ,
554- // This is a special case: a unit struct which is used as a value. We return a
555- // completely different ExprKind here to account for this special case.
582+ // A unit struct which is used as a value. We return a completely different ExprKind
583+ // here to account for this special case.
556584 ty:: TyStruct ( adt_def, substs) => return ExprKind :: Adt {
557585 adt_def : adt_def,
558586 variant_index : 0 ,
@@ -563,7 +591,8 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
563591 ref sty => panic ! ( "unexpected sty: {:?}" , sty)
564592 } ,
565593 def:: DefVariant ( enum_id, variant_id, false ) => match cx. tcx . node_id_to_type ( expr. id ) . sty {
566- // A variant constructor.
594+ // A variant constructor. Should only be reached if not called in the same
595+ // expression.
567596 ty:: TyBareFn ( ..) => ( variant_id, ItemKind :: Function ) ,
568597 // A unit variant, similar special case to the struct case above.
569598 ty:: TyEnum ( adt_def, substs) => {
@@ -900,6 +929,7 @@ fn loop_label<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr) -> Cod
900929 }
901930}
902931
932+ /// Converts a list of named fields (i.e. for struct-like struct/enum ADTs) into FieldExprRef.
903933fn field_refs < ' tcx > ( variant : VariantDef < ' tcx > ,
904934 fields : & ' tcx [ hir:: Field ] )
905935 -> Vec < FieldExprRef < ' tcx > >
0 commit comments