Skip to content

Commit c3c4fd7

Browse files
authored
Rollup merge of #143494 - cjgillot:no-yield-in-scope, r=compiler-errors
Remove yields_in_scope from the scope tree. I believe this has not been in use since we removed the HIR-based generator interior type computation.
2 parents 8a5d239 + 39ee1b2 commit c3c4fd7

File tree

3 files changed

+37
-263
lines changed

3 files changed

+37
-263
lines changed

compiler/rustc_hir_analysis/src/check/region.rs

Lines changed: 37 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use rustc_hir::def_id::DefId;
1515
use rustc_hir::intravisit::{self, Visitor};
1616
use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt};
1717
use rustc_index::Idx;
18-
use rustc_middle::bug;
1918
use rustc_middle::middle::region::*;
2019
use rustc_middle::ty::TyCtxt;
2120
use rustc_session::lint;
@@ -34,14 +33,6 @@ struct Context {
3433
struct 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))]
202194
fn 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

217203
fn 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))]
246233
fn 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

Comments
 (0)