@@ -17,7 +17,6 @@ use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData};
17
17
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
18
18
use rustc_span:: symbol:: sym;
19
19
use rustc_span:: Span ;
20
- use smallvec:: SmallVec ;
21
20
use tracing:: debug;
22
21
23
22
mod drop_ranges;
@@ -29,13 +28,6 @@ struct InteriorVisitor<'a, 'tcx> {
29
28
expr_count : usize ,
30
29
kind : hir:: GeneratorKind ,
31
30
prev_unresolved_span : Option < Span > ,
32
- /// Match arm guards have temporary borrows from the pattern bindings.
33
- /// In case there is a yield point in a guard with a reference to such bindings,
34
- /// such borrows can span across this yield point.
35
- /// As such, we need to track these borrows and record them despite of the fact
36
- /// that they may succeed the said yield point in the post-order.
37
- guard_bindings : SmallVec < [ SmallVec < [ HirId ; 4 ] > ; 1 ] > ,
38
- guard_bindings_set : HirIdSet ,
39
31
linted_values : HirIdSet ,
40
32
drop_ranges : DropRanges ,
41
33
}
@@ -48,7 +40,6 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
48
40
scope : Option < region:: Scope > ,
49
41
expr : Option < & ' tcx Expr < ' tcx > > ,
50
42
source_span : Span ,
51
- guard_borrowing_from_pattern : bool ,
52
43
) {
53
44
use rustc_span:: DUMMY_SP ;
54
45
@@ -89,8 +80,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
89
80
// If it is a borrowing happening in the guard,
90
81
// it needs to be recorded regardless because they
91
82
// do live across this yield point.
92
- guard_borrowing_from_pattern
93
- || yield_data. expr_and_pat_count >= self . expr_count
83
+ yield_data. expr_and_pat_count >= self . expr_count
94
84
} )
95
85
. cloned ( )
96
86
} )
@@ -196,8 +186,6 @@ pub fn resolve_interior<'a, 'tcx>(
196
186
expr_count : 0 ,
197
187
kind,
198
188
prev_unresolved_span : None ,
199
- guard_bindings : <_ >:: default ( ) ,
200
- guard_bindings_set : <_ >:: default ( ) ,
201
189
linted_values : <_ >:: default ( ) ,
202
190
drop_ranges : drop_ranges:: compute_drop_ranges ( fcx, def_id, body) ,
203
191
} ;
@@ -284,8 +272,41 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
284
272
let Arm { guard, pat, body, .. } = arm;
285
273
self . visit_pat ( pat) ;
286
274
if let Some ( ref g) = guard {
287
- self . guard_bindings . push ( <_ >:: default ( ) ) ;
288
275
{
276
+ // If there is a guard, we need to count all variables bound in the pattern as
277
+ // borrowed for the entire guard body, regardless of whether they are accessed.
278
+ // We do this by walking the pattern bindings and recording `&T` for any `x: T`
279
+ // that is bound.
280
+
281
+ struct ArmPatCollector < ' a , ' b , ' tcx > {
282
+ interior_visitor : & ' a mut InteriorVisitor < ' b , ' tcx > ,
283
+ scope : Scope ,
284
+ }
285
+
286
+ impl < ' a , ' b , ' tcx > Visitor < ' tcx > for ArmPatCollector < ' a , ' b , ' tcx > {
287
+ fn visit_pat ( & mut self , pat : & ' tcx Pat < ' tcx > ) {
288
+ intravisit:: walk_pat ( self , pat) ;
289
+ if let PatKind :: Binding ( _, id, ident, ..) = pat. kind {
290
+ let ty =
291
+ self . interior_visitor . fcx . typeck_results . borrow ( ) . node_type ( id) ;
292
+ let tcx = self . interior_visitor . fcx . tcx ;
293
+ let ty = tcx. mk_ref (
294
+ // Use `ReErased` as `resolve_interior` is going to replace all the
295
+ // regions anyway.
296
+ tcx. mk_region ( ty:: ReErased ) ,
297
+ ty:: TypeAndMut { ty, mutbl : hir:: Mutability :: Not } ,
298
+ ) ;
299
+ self . interior_visitor . record (
300
+ ty,
301
+ id,
302
+ Some ( self . scope ) ,
303
+ None ,
304
+ ident. span ,
305
+ ) ;
306
+ }
307
+ }
308
+ }
309
+
289
310
ArmPatCollector {
290
311
interior_visitor : self ,
291
312
scope : Scope { id : g. body ( ) . hir_id . local_id , data : ScopeData :: Node } ,
@@ -301,12 +322,6 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
301
322
self . visit_let_expr ( l) ;
302
323
}
303
324
}
304
-
305
- let mut scope_var_ids =
306
- self . guard_bindings . pop ( ) . expect ( "should have pushed at least one earlier" ) ;
307
- for var_id in scope_var_ids. drain ( ..) {
308
- self . guard_bindings_set . remove ( & var_id) ;
309
- }
310
325
}
311
326
self . visit_expr ( body) ;
312
327
}
@@ -319,13 +334,11 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
319
334
if let PatKind :: Binding ( ..) = pat. kind {
320
335
let scope = self . region_scope_tree . var_scope ( pat. hir_id . local_id ) . unwrap ( ) ;
321
336
let ty = self . fcx . typeck_results . borrow ( ) . pat_ty ( pat) ;
322
- self . record ( ty, pat. hir_id , Some ( scope) , None , pat. span , false ) ;
337
+ self . record ( ty, pat. hir_id , Some ( scope) , None , pat. span ) ;
323
338
}
324
339
}
325
340
326
341
fn visit_expr ( & mut self , expr : & ' tcx Expr < ' tcx > ) {
327
- let mut guard_borrowing_from_pattern = false ;
328
-
329
342
match & expr. kind {
330
343
ExprKind :: Call ( callee, args) => match & callee. kind {
331
344
ExprKind :: Path ( qpath) => {
@@ -352,16 +365,6 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
352
365
}
353
366
_ => intravisit:: walk_expr ( self , expr) ,
354
367
} ,
355
- ExprKind :: Path ( qpath) => {
356
- intravisit:: walk_expr ( self , expr) ;
357
- let res = self . fcx . typeck_results . borrow ( ) . qpath_res ( qpath, expr. hir_id ) ;
358
- match res {
359
- Res :: Local ( id) if self . guard_bindings_set . contains ( & id) => {
360
- guard_borrowing_from_pattern = true ;
361
- }
362
- _ => { }
363
- }
364
- }
365
368
_ => intravisit:: walk_expr ( self , expr) ,
366
369
}
367
370
@@ -390,14 +393,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
390
393
// If there are adjustments, then record the final type --
391
394
// this is the actual value that is being produced.
392
395
if let Some ( adjusted_ty) = self . fcx . typeck_results . borrow ( ) . expr_ty_adjusted_opt ( expr) {
393
- self . record (
394
- adjusted_ty,
395
- expr. hir_id ,
396
- scope,
397
- Some ( expr) ,
398
- expr. span ,
399
- guard_borrowing_from_pattern,
400
- ) ;
396
+ self . record ( adjusted_ty, expr. hir_id , scope, Some ( expr) , expr. span ) ;
401
397
}
402
398
403
399
// Also record the unadjusted type (which is the only type if
@@ -425,68 +421,13 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
425
421
// The type table might not have information for this expression
426
422
// if it is in a malformed scope. (#66387)
427
423
if let Some ( ty) = self . fcx . typeck_results . borrow ( ) . expr_ty_opt ( expr) {
428
- if guard_borrowing_from_pattern {
429
- // Match guards create references to all the bindings in the pattern that are used
430
- // in the guard, e.g. `y if is_even(y) => ...` becomes `is_even(*r_y)` where `r_y`
431
- // is a reference to `y`, so we must record a reference to the type of the binding.
432
- let tcx = self . fcx . tcx ;
433
- let ref_ty = tcx. mk_ref (
434
- // Use `ReErased` as `resolve_interior` is going to replace all the regions anyway.
435
- tcx. mk_region ( ty:: ReErased ) ,
436
- ty:: TypeAndMut { ty, mutbl : hir:: Mutability :: Not } ,
437
- ) ;
438
- self . record (
439
- ref_ty,
440
- expr. hir_id ,
441
- scope,
442
- Some ( expr) ,
443
- expr. span ,
444
- guard_borrowing_from_pattern,
445
- ) ;
446
- }
447
- self . record (
448
- ty,
449
- expr. hir_id ,
450
- scope,
451
- Some ( expr) ,
452
- expr. span ,
453
- guard_borrowing_from_pattern,
454
- ) ;
424
+ self . record ( ty, expr. hir_id , scope, Some ( expr) , expr. span ) ;
455
425
} else {
456
426
self . fcx . tcx . sess . delay_span_bug ( expr. span , "no type for node" ) ;
457
427
}
458
428
}
459
429
}
460
430
461
- struct ArmPatCollector < ' a , ' b , ' tcx > {
462
- interior_visitor : & ' a mut InteriorVisitor < ' b , ' tcx > ,
463
- scope : Scope ,
464
- }
465
-
466
- impl < ' a , ' b , ' tcx > Visitor < ' tcx > for ArmPatCollector < ' a , ' b , ' tcx > {
467
- fn visit_pat ( & mut self , pat : & ' tcx Pat < ' tcx > ) {
468
- intravisit:: walk_pat ( self , pat) ;
469
- if let PatKind :: Binding ( _, id, ..) = pat. kind {
470
- self . interior_visitor
471
- . guard_bindings
472
- . last_mut ( )
473
- . expect ( "should have pushed at least one earlier" )
474
- . push ( id) ;
475
- self . interior_visitor . guard_bindings_set . insert ( id) ;
476
-
477
- let ty = self . interior_visitor . fcx . typeck_results . borrow ( ) . node_type ( id) ;
478
- let ty = self . interior_visitor . fcx . tcx . mk_ref (
479
- // Use `ReErased` as `resolve_interior` is going to replace all the regions anyway.
480
- self . interior_visitor . fcx . tcx . mk_region ( ty:: ReErased ) ,
481
- ty:: TypeAndMut { ty, mutbl : hir:: Mutability :: Not } ,
482
- ) ;
483
- // FIXME: use the right span
484
- let span = rustc_span:: DUMMY_SP ;
485
- self . interior_visitor . record ( ty, id, Some ( self . scope ) , None , span, true ) ;
486
- }
487
- }
488
- }
489
-
490
431
#[ derive( Default ) ]
491
432
pub struct SuspendCheckData < ' a , ' tcx > {
492
433
expr : Option < & ' tcx Expr < ' tcx > > ,
0 commit comments