@@ -53,7 +53,6 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
53
53
// Find the actual method implementation being called and
54
54
// build the appropriate UFCS call expression with the
55
55
// callee-object as self parameter.
56
-
57
56
let method = method_callee ( cx, self , ty:: MethodCall :: expr ( self . id ) ) ;
58
57
let mut argrefs = vec ! [ fun. to_ref( ) ] ;
59
58
argrefs. extend ( args. iter ( ) . map ( |a| a. to_ref ( ) ) ) ;
@@ -64,12 +63,40 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
64
63
args : argrefs,
65
64
}
66
65
} 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
+ }
71
99
}
72
-
73
100
}
74
101
}
75
102
@@ -549,10 +576,11 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
549
576
def:: DefFn ( def_id, _) => ( def_id, ItemKind :: Function ) ,
550
577
def:: DefMethod ( def_id) => ( def_id, ItemKind :: Method ) ,
551
578
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.
553
581
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.
556
584
ty:: TyStruct ( adt_def, substs) => return ExprKind :: Adt {
557
585
adt_def : adt_def,
558
586
variant_index : 0 ,
@@ -563,7 +591,8 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
563
591
ref sty => panic ! ( "unexpected sty: {:?}" , sty)
564
592
} ,
565
593
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.
567
596
ty:: TyBareFn ( ..) => ( variant_id, ItemKind :: Function ) ,
568
597
// A unit variant, similar special case to the struct case above.
569
598
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
900
929
}
901
930
}
902
931
932
+ /// Converts a list of named fields (i.e. for struct-like struct/enum ADTs) into FieldExprRef.
903
933
fn field_refs < ' tcx > ( variant : VariantDef < ' tcx > ,
904
934
fields : & ' tcx [ hir:: Field ] )
905
935
-> Vec < FieldExprRef < ' tcx > >
0 commit comments