@@ -15,7 +15,6 @@ use rustc_hir::def_id::DefId;
1515use rustc_hir:: intravisit:: { self , Visitor } ;
1616use rustc_hir:: { Arm , Block , Expr , LetStmt , Pat , PatKind , Stmt } ;
1717use rustc_index:: Idx ;
18- use rustc_middle:: bug;
1918use rustc_middle:: middle:: region:: * ;
2019use rustc_middle:: ty:: TyCtxt ;
2120use rustc_session:: lint;
@@ -34,14 +33,6 @@ struct Context {
3433struct ScopeResolutionVisitor < ' tcx > {
3534 tcx : TyCtxt < ' tcx > ,
3635
37- // The number of expressions and patterns visited in the current body.
38- expr_and_pat_count : usize ,
39- // When this is `true`, we record the `Scopes` we encounter
40- // when processing a Yield expression. This allows us to fix
41- // up their indices.
42- pessimistic_yield : bool ,
43- // Stores scopes when `pessimistic_yield` is `true`.
44- fixup_scopes : Vec < Scope > ,
4536 // The generated scope tree.
4637 scope_tree : ScopeTree ,
4738
@@ -199,19 +190,14 @@ fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir:
199190 visitor. cx = prev_cx;
200191}
201192
193+ #[ tracing:: instrument( level = "debug" , skip( visitor) ) ]
202194fn resolve_pat < ' tcx > ( visitor : & mut ScopeResolutionVisitor < ' tcx > , pat : & ' tcx hir:: Pat < ' tcx > ) {
203195 // If this is a binding then record the lifetime of that binding.
204196 if let PatKind :: Binding ( ..) = pat. kind {
205197 record_var_lifetime ( visitor, pat. hir_id . local_id ) ;
206198 }
207199
208- debug ! ( "resolve_pat - pre-increment {} pat = {:?}" , visitor. expr_and_pat_count, pat) ;
209-
210200 intravisit:: walk_pat ( visitor, pat) ;
211-
212- visitor. expr_and_pat_count += 1 ;
213-
214- debug ! ( "resolve_pat - post-increment {} pat = {:?}" , visitor. expr_and_pat_count, pat) ;
215201}
216202
217203fn resolve_stmt < ' tcx > ( visitor : & mut ScopeResolutionVisitor < ' tcx > , stmt : & ' tcx hir:: Stmt < ' tcx > ) {
@@ -243,68 +229,15 @@ fn resolve_stmt<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, stmt: &'tcx hi
243229 }
244230}
245231
232+ #[ tracing:: instrument( level = "debug" , skip( visitor) ) ]
246233fn resolve_expr < ' tcx > (
247234 visitor : & mut ScopeResolutionVisitor < ' tcx > ,
248235 expr : & ' tcx hir:: Expr < ' tcx > ,
249236 terminating : bool ,
250237) {
251- debug ! ( "resolve_expr - pre-increment {} expr = {:?}" , visitor. expr_and_pat_count, expr) ;
252-
253238 let prev_cx = visitor. cx ;
254239 visitor. enter_node_scope_with_dtor ( expr. hir_id . local_id , terminating) ;
255240
256- let prev_pessimistic = visitor. pessimistic_yield ;
257-
258- // Ordinarily, we can rely on the visit order of HIR intravisit
259- // to correspond to the actual execution order of statements.
260- // However, there's a weird corner case with compound assignment
261- // operators (e.g. `a += b`). The evaluation order depends on whether
262- // or not the operator is overloaded (e.g. whether or not a trait
263- // like AddAssign is implemented).
264-
265- // For primitive types (which, despite having a trait impl, don't actually
266- // end up calling it), the evaluation order is right-to-left. For example,
267- // the following code snippet:
268- //
269- // let y = &mut 0;
270- // *{println!("LHS!"); y} += {println!("RHS!"); 1};
271- //
272- // will print:
273- //
274- // RHS!
275- // LHS!
276- //
277- // However, if the operator is used on a non-primitive type,
278- // the evaluation order will be left-to-right, since the operator
279- // actually get desugared to a method call. For example, this
280- // nearly identical code snippet:
281- //
282- // let y = &mut String::new();
283- // *{println!("LHS String"); y} += {println!("RHS String"); "hi"};
284- //
285- // will print:
286- // LHS String
287- // RHS String
288- //
289- // To determine the actual execution order, we need to perform
290- // trait resolution. Unfortunately, we need to be able to compute
291- // yield_in_scope before type checking is even done, as it gets
292- // used by AST borrowcheck.
293- //
294- // Fortunately, we don't need to know the actual execution order.
295- // It suffices to know the 'worst case' order with respect to yields.
296- // Specifically, we need to know the highest 'expr_and_pat_count'
297- // that we could assign to the yield expression. To do this,
298- // we pick the greater of the two values from the left-hand
299- // and right-hand expressions. This makes us overly conservative
300- // about what types could possibly live across yield points,
301- // but we will never fail to detect that a type does actually
302- // live across a yield point. The latter part is critical -
303- // we're already overly conservative about what types will live
304- // across yield points, as the generated MIR will determine
305- // when things are actually live. However, for typecheck to work
306- // properly, we can't miss any types.
307-
308241 match expr. kind {
309242 // Conditional or repeating scopes are always terminating
310243 // scopes, meaning that temporaries cannot outlive them.
@@ -360,55 +293,42 @@ fn resolve_expr<'tcx>(
360293 let body = visitor. tcx . hir_body ( body) ;
361294 visitor. visit_body ( body) ;
362295 }
296+ // Ordinarily, we can rely on the visit order of HIR intravisit
297+ // to correspond to the actual execution order of statements.
298+ // However, there's a weird corner case with compound assignment
299+ // operators (e.g. `a += b`). The evaluation order depends on whether
300+ // or not the operator is overloaded (e.g. whether or not a trait
301+ // like AddAssign is implemented).
302+ //
303+ // For primitive types (which, despite having a trait impl, don't actually
304+ // end up calling it), the evaluation order is right-to-left. For example,
305+ // the following code snippet:
306+ //
307+ // let y = &mut 0;
308+ // *{println!("LHS!"); y} += {println!("RHS!"); 1};
309+ //
310+ // will print:
311+ //
312+ // RHS!
313+ // LHS!
314+ //
315+ // However, if the operator is used on a non-primitive type,
316+ // the evaluation order will be left-to-right, since the operator
317+ // actually get desugared to a method call. For example, this
318+ // nearly identical code snippet:
319+ //
320+ // let y = &mut String::new();
321+ // *{println!("LHS String"); y} += {println!("RHS String"); "hi"};
322+ //
323+ // will print:
324+ // LHS String
325+ // RHS String
326+ //
327+ // To determine the actual execution order, we need to perform
328+ // trait resolution. Fortunately, we don't need to know the actual execution order.
363329 hir:: ExprKind :: AssignOp ( _, left_expr, right_expr) => {
364- debug ! (
365- "resolve_expr - enabling pessimistic_yield, was previously {}" ,
366- prev_pessimistic
367- ) ;
368-
369- let start_point = visitor. fixup_scopes . len ( ) ;
370- visitor. pessimistic_yield = true ;
371-
372- // If the actual execution order turns out to be right-to-left,
373- // then we're fine. However, if the actual execution order is left-to-right,
374- // then we'll assign too low a count to any `yield` expressions
375- // we encounter in 'right_expression' - they should really occur after all of the
376- // expressions in 'left_expression'.
377330 visitor. visit_expr ( right_expr) ;
378- visitor. pessimistic_yield = prev_pessimistic;
379-
380- debug ! ( "resolve_expr - restoring pessimistic_yield to {}" , prev_pessimistic) ;
381331 visitor. visit_expr ( left_expr) ;
382- debug ! ( "resolve_expr - fixing up counts to {}" , visitor. expr_and_pat_count) ;
383-
384- // Remove and process any scopes pushed by the visitor
385- let target_scopes = visitor. fixup_scopes . drain ( start_point..) ;
386-
387- for scope in target_scopes {
388- let yield_data =
389- visitor. scope_tree . yield_in_scope . get_mut ( & scope) . unwrap ( ) . last_mut ( ) . unwrap ( ) ;
390- let count = yield_data. expr_and_pat_count ;
391- let span = yield_data. span ;
392-
393- // expr_and_pat_count never decreases. Since we recorded counts in yield_in_scope
394- // before walking the left-hand side, it should be impossible for the recorded
395- // count to be greater than the left-hand side count.
396- if count > visitor. expr_and_pat_count {
397- bug ! (
398- "Encountered greater count {} at span {:?} - expected no greater than {}" ,
399- count,
400- span,
401- visitor. expr_and_pat_count
402- ) ;
403- }
404- let new_count = visitor. expr_and_pat_count ;
405- debug ! (
406- "resolve_expr - increasing count for scope {:?} from {} to {} at span {:?}" ,
407- scope, count, new_count, span
408- ) ;
409-
410- yield_data. expr_and_pat_count = new_count;
411- }
412332 }
413333
414334 hir:: ExprKind :: If ( cond, then, Some ( otherwise) ) => {
@@ -453,43 +373,6 @@ fn resolve_expr<'tcx>(
453373 _ => intravisit:: walk_expr ( visitor, expr) ,
454374 }
455375
456- visitor. expr_and_pat_count += 1 ;
457-
458- debug ! ( "resolve_expr post-increment {}, expr = {:?}" , visitor. expr_and_pat_count, expr) ;
459-
460- if let hir:: ExprKind :: Yield ( _, source) = & expr. kind {
461- // Mark this expr's scope and all parent scopes as containing `yield`.
462- let mut scope = Scope { local_id : expr. hir_id . local_id , data : ScopeData :: Node } ;
463- loop {
464- let data = YieldData {
465- span : expr. span ,
466- expr_and_pat_count : visitor. expr_and_pat_count ,
467- source : * source,
468- } ;
469- match visitor. scope_tree . yield_in_scope . get_mut ( & scope) {
470- Some ( yields) => yields. push ( data) ,
471- None => {
472- visitor. scope_tree . yield_in_scope . insert ( scope, vec ! [ data] ) ;
473- }
474- }
475-
476- if visitor. pessimistic_yield {
477- debug ! ( "resolve_expr in pessimistic_yield - marking scope {:?} for fixup" , scope) ;
478- visitor. fixup_scopes . push ( scope) ;
479- }
480-
481- // Keep traversing up while we can.
482- match visitor. scope_tree . parent_map . get ( & scope) {
483- // Don't cross from closure bodies to their parent.
484- Some ( & superscope) => match superscope. data {
485- ScopeData :: CallSite => break ,
486- _ => scope = superscope,
487- } ,
488- None => break ,
489- }
490- }
491- }
492-
493376 visitor. cx = prev_cx;
494377}
495378
@@ -612,8 +495,8 @@ fn resolve_local<'tcx>(
612495 }
613496 }
614497
615- // Make sure we visit the initializer first, so expr_and_pat_count remains correct .
616- // The correct order, as shared between coroutine_interior, drop_ranges and intravisitor,
498+ // Make sure we visit the initializer first.
499+ // The correct order, as shared between drop_ranges and intravisitor,
617500 // is to walk initializer, followed by pattern bindings, finally followed by the `else` block.
618501 if let Some ( expr) = init {
619502 visitor. visit_expr ( expr) ;
@@ -798,26 +681,15 @@ impl<'tcx> ScopeResolutionVisitor<'tcx> {
798681 }
799682
800683 fn enter_body ( & mut self , hir_id : hir:: HirId , f : impl FnOnce ( & mut Self ) ) {
801- // Save all state that is specific to the outer function
802- // body. These will be restored once down below, once we've
803- // visited the body.
804- let outer_ec = mem:: replace ( & mut self . expr_and_pat_count , 0 ) ;
805684 let outer_cx = self . cx ;
806- // The 'pessimistic yield' flag is set to true when we are
807- // processing a `+=` statement and have to make pessimistic
808- // control flow assumptions. This doesn't apply to nested
809- // bodies within the `+=` statements. See #69307.
810- let outer_pessimistic_yield = mem:: replace ( & mut self . pessimistic_yield , false ) ;
811685
812686 self . enter_scope ( Scope { local_id : hir_id. local_id , data : ScopeData :: CallSite } ) ;
813687 self . enter_scope ( Scope { local_id : hir_id. local_id , data : ScopeData :: Arguments } ) ;
814688
815689 f ( self ) ;
816690
817691 // Restore context we had at the start.
818- self . expr_and_pat_count = outer_ec;
819692 self . cx = outer_cx;
820- self . pessimistic_yield = outer_pessimistic_yield;
821693 }
822694}
823695
@@ -919,10 +791,7 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
919791 let mut visitor = ScopeResolutionVisitor {
920792 tcx,
921793 scope_tree : ScopeTree :: default ( ) ,
922- expr_and_pat_count : 0 ,
923794 cx : Context { parent : None , var_parent : None } ,
924- pessimistic_yield : false ,
925- fixup_scopes : vec ! [ ] ,
926795 extended_super_lets : Default :: default ( ) ,
927796 } ;
928797
0 commit comments