1
+ use crate :: build:: ExprCategory as Category ;
1
2
use crate :: thir:: cx:: Cx ;
2
3
use crate :: thir:: util:: UserAnnotatedTyHelpers ;
3
4
use rustc_data_structures:: stack:: ensure_sufficient_stack;
@@ -24,20 +25,26 @@ use rustc_target::abi::VariantIdx;
24
25
impl < ' tcx > Cx < ' tcx > {
25
26
crate fn mirror_expr ( & mut self , expr : & ' tcx hir:: Expr < ' tcx > ) -> ExprId {
26
27
// `mirror_expr` is recursing very deep. Make sure the stack doesn't overflow.
27
- ensure_sufficient_stack ( || self . mirror_expr_inner ( expr) )
28
+ ensure_sufficient_stack ( || self . mirror_expr_inner ( expr, None ) )
28
29
}
29
30
30
- crate fn mirror_exprs ( & mut self , exprs : & ' tcx [ hir:: Expr < ' tcx > ] ) -> Box < [ ExprId ] > {
31
- exprs. iter ( ) . map ( |expr| self . mirror_expr_inner ( expr) ) . collect ( )
31
+ crate fn mirror_exprs (
32
+ & mut self ,
33
+ exprs : impl Iterator < Item = ( & ' tcx hir:: Expr < ' tcx > , Option < Ty < ' tcx > > ) > ,
34
+ ) -> Box < [ ExprId ] > {
35
+ exprs. map ( |( expr, ty) | self . mirror_expr_inner ( expr, ty) ) . collect ( )
32
36
}
33
37
34
- pub ( super ) fn mirror_expr_inner ( & mut self , hir_expr : & ' tcx hir:: Expr < ' tcx > ) -> ExprId {
38
+ #[ instrument( level = "debug" , skip( self ) ) ]
39
+ pub ( super ) fn mirror_expr_inner (
40
+ & mut self ,
41
+ hir_expr : & ' tcx hir:: Expr < ' tcx > ,
42
+ ty : Option < Ty < ' tcx > > ,
43
+ ) -> ExprId {
35
44
let temp_lifetime = self . region_scope_tree . temporary_scope ( hir_expr. hir_id . local_id ) ;
36
45
let expr_scope =
37
46
region:: Scope { id : hir_expr. hir_id . local_id , data : region:: ScopeData :: Node } ;
38
47
39
- debug ! ( "Expr::make_mirror(): id={}, span={:?}" , hir_expr. hir_id, hir_expr. span) ;
40
-
41
48
let mut expr = self . make_mirror_unadjusted ( hir_expr) ;
42
49
43
50
let adjustment_span = match self . adjustment_span {
@@ -47,12 +54,16 @@ impl<'tcx> Cx<'tcx> {
47
54
48
55
// Now apply adjustments, if any.
49
56
for adjustment in self . typeck_results . expr_adjustments ( hir_expr) {
50
- debug ! ( "make_mirror: expr={:?} applying adjustment={:?}" , expr, adjustment) ;
57
+ debug ! ( ? expr, ? adjustment) ;
51
58
let span = expr. span ;
52
59
expr =
53
60
self . apply_adjustment ( hir_expr, expr, adjustment, adjustment_span. unwrap_or ( span) ) ;
54
61
}
55
62
63
+ if !matches ! ( Category :: of( & expr. kind) , Some ( Category :: Constant ) ) {
64
+ expr. ty = ty. unwrap_or ( expr. ty ) ;
65
+ }
66
+
56
67
// Next, wrap this up in the expr's scope.
57
68
expr = Expr {
58
69
temp_lifetime,
@@ -172,7 +183,7 @@ impl<'tcx> Cx<'tcx> {
172
183
// is guaranteed to exist, since a method call always has a receiver.
173
184
let old_adjustment_span = self . adjustment_span . replace ( ( args[ 0 ] . hir_id , expr_span) ) ;
174
185
tracing:: info!( "Using method span: {:?}" , expr. span) ;
175
- let args = self . mirror_exprs ( args) ;
186
+ let args = self . mirror_exprs ( args. iter ( ) . zip ( std :: iter :: repeat ( None ) ) ) ;
176
187
self . adjustment_span = old_adjustment_span;
177
188
ExprKind :: Call {
178
189
ty : expr. ty ,
@@ -194,12 +205,16 @@ impl<'tcx> Cx<'tcx> {
194
205
195
206
let method = self . method_callee ( expr, fun. span , None ) ;
196
207
197
- let arg_tys = args. iter ( ) . map ( |e| self . typeck_results ( ) . expr_ty_adjusted ( e) ) ;
208
+ let arg_tys: Vec < _ > =
209
+ args. iter ( ) . map ( |e| self . typeck_results ( ) . expr_ty_adjusted ( e) ) . collect ( ) ;
198
210
let tupled_args = Expr {
199
- ty : self . tcx . mk_tup ( arg_tys) ,
211
+ ty : self . tcx . mk_tup ( arg_tys. iter ( ) ) ,
200
212
temp_lifetime,
201
213
span : expr. span ,
202
- kind : ExprKind :: Tuple { fields : self . mirror_exprs ( args) } ,
214
+ kind : ExprKind :: Tuple {
215
+ fields : self
216
+ . mirror_exprs ( args. iter ( ) . zip ( arg_tys. into_iter ( ) . map ( Some ) ) ) ,
217
+ } ,
203
218
} ;
204
219
let tupled_args = self . thir . exprs . push ( tupled_args) ;
205
220
@@ -256,7 +271,7 @@ impl<'tcx> Cx<'tcx> {
256
271
ExprKind :: Call {
257
272
ty : self . typeck_results ( ) . node_type ( fun. hir_id ) ,
258
273
fun : self . mirror_expr ( fun) ,
259
- args : self . mirror_exprs ( args) ,
274
+ args : self . mirror_exprs ( args. iter ( ) . zip ( std :: iter :: repeat ( None ) ) ) ,
260
275
from_hir_call : true ,
261
276
fn_span : expr. span ,
262
277
}
@@ -763,10 +778,17 @@ impl<'tcx> Cx<'tcx> {
763
778
ExprKind :: Use { source : self . mirror_expr ( source) }
764
779
}
765
780
hir:: ExprKind :: Box ( ref value) => ExprKind :: Box { value : self . mirror_expr ( value) } ,
766
- hir:: ExprKind :: Array ( ref fields) => {
767
- ExprKind :: Array { fields : self . mirror_exprs ( fields) }
768
- }
769
- hir:: ExprKind :: Tup ( ref fields) => ExprKind :: Tuple { fields : self . mirror_exprs ( fields) } ,
781
+ hir:: ExprKind :: Array ( ref fields) => ExprKind :: Array {
782
+ fields : self . mirror_exprs (
783
+ fields
784
+ . iter ( )
785
+ . zip ( std:: iter:: repeat ( Some ( expr_ty. sequence_element_type ( self . tcx ) ) ) ) ,
786
+ ) ,
787
+ } ,
788
+ hir:: ExprKind :: Tup ( ref fields) => ExprKind :: Tuple {
789
+ fields : self
790
+ . mirror_exprs ( fields. iter ( ) . zip ( expr_ty. tuple_fields ( ) . iter ( ) . map ( Some ) ) ) ,
791
+ } ,
770
792
771
793
hir:: ExprKind :: Yield ( ref v, _) => ExprKind :: Yield { value : self . mirror_expr ( v) } ,
772
794
hir:: ExprKind :: Err => unreachable ! ( ) ,
0 commit comments