Skip to content

Clean up a few things in rustc_hir_analysis::check::region #138989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 18 additions & 21 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,18 @@ use tracing::debug;
struct Context {
/// The scope that contains any new variables declared, plus its depth in
/// the scope tree.
var_parent: Option<(Scope, ScopeDepth)>,
var_parent: Option<Scope>,

/// Region parent of expressions, etc., plus its depth in the scope tree.
parent: Option<(Scope, ScopeDepth)>,
}

impl Context {
fn set_var_parent(&mut self) {
self.var_parent = self.parent.map(|(p, _)| p);
}
}

struct ScopeResolutionVisitor<'tcx> {
tcx: TyCtxt<'tcx>,

Expand Down Expand Up @@ -78,7 +84,7 @@ fn record_var_lifetime(visitor: &mut ScopeResolutionVisitor<'_>, var_id: hir::It
//
// extern fn isalnum(c: c_int) -> c_int
}
Some((parent_scope, _)) => visitor.scope_tree.record_var_scope(var_id, parent_scope),
Some(parent_scope) => visitor.scope_tree.record_var_scope(var_id, parent_scope),
}
}

Expand Down Expand Up @@ -113,7 +119,7 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
// itself has returned.

visitor.enter_node_scope_with_dtor(blk.hir_id.local_id);
visitor.cx.var_parent = visitor.cx.parent;
visitor.cx.set_var_parent();

{
// This block should be kept approximately in sync with
Expand All @@ -132,7 +138,7 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
local_id: blk.hir_id.local_id,
data: ScopeData::Remainder(FirstStatementIndex::new(i)),
});
visitor.cx.var_parent = visitor.cx.parent;
visitor.cx.set_var_parent();
visitor.visit_stmt(statement);
// We need to back out temporarily to the last enclosing scope
// for the `else` block, so that even the temporaries receiving
Expand All @@ -157,7 +163,7 @@ fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hi
local_id: blk.hir_id.local_id,
data: ScopeData::Remainder(FirstStatementIndex::new(i)),
});
visitor.cx.var_parent = visitor.cx.parent;
visitor.cx.set_var_parent();
visitor.visit_stmt(statement)
}
hir::StmtKind::Item(..) => {
Expand Down Expand Up @@ -207,7 +213,7 @@ fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir:
visitor.terminating_scopes.insert(arm.hir_id.local_id);

visitor.enter_node_scope_with_dtor(arm.hir_id.local_id);
visitor.cx.var_parent = visitor.cx.parent;
visitor.cx.set_var_parent();

if let Some(expr) = arm.guard
&& !has_let_expr(expr)
Expand All @@ -221,8 +227,6 @@ fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir:
}

fn resolve_pat<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) {
visitor.record_child_scope(Scope { local_id: pat.hir_id.local_id, data: ScopeData::Node });

// If this is a binding then record the lifetime of that binding.
if let PatKind::Binding(..) = pat.kind {
record_var_lifetime(visitor, pat.hir_id.local_id);
Expand Down Expand Up @@ -486,7 +490,7 @@ fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hi
ScopeData::IfThen
};
visitor.enter_scope(Scope { local_id: then.hir_id.local_id, data });
visitor.cx.var_parent = visitor.cx.parent;
visitor.cx.set_var_parent();
visitor.visit_expr(cond);
visitor.visit_expr(then);
visitor.cx = expr_cx;
Expand All @@ -501,7 +505,7 @@ fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hi
ScopeData::IfThen
};
visitor.enter_scope(Scope { local_id: then.hir_id.local_id, data });
visitor.cx.var_parent = visitor.cx.parent;
visitor.cx.set_var_parent();
visitor.visit_expr(cond);
visitor.visit_expr(then);
visitor.cx = expr_cx;
Expand Down Expand Up @@ -560,7 +564,7 @@ fn resolve_local<'tcx>(
) {
debug!("resolve_local(pat={:?}, init={:?})", pat, init);

let blk_scope = visitor.cx.var_parent.map(|(p, _)| p);
let blk_scope = visitor.cx.var_parent;

// As an exception to the normal rules governing temporary
// lifetimes, initializers in a let have a temporary lifetime
Expand Down Expand Up @@ -625,10 +629,7 @@ fn resolve_local<'tcx>(
if is_binding_pat(pat) {
visitor.scope_tree.record_rvalue_candidate(
expr.hir_id,
RvalueCandidateType::Pattern {
target: expr.hir_id.local_id,
lifetime: blk_scope,
},
RvalueCandidate { target: expr.hir_id.local_id, lifetime: blk_scope },
);
}
}
Expand Down Expand Up @@ -733,10 +734,7 @@ fn resolve_local<'tcx>(
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
visitor.scope_tree.record_rvalue_candidate(
subexpr.hir_id,
RvalueCandidateType::Borrow {
target: subexpr.hir_id.local_id,
lifetime: blk_id,
},
RvalueCandidate { target: subexpr.hir_id.local_id, lifetime: blk_id },
);
}
hir::ExprKind::Struct(_, fields, _) => {
Expand Down Expand Up @@ -857,13 +855,12 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
self.enter_body(body.value.hir_id, |this| {
if this.tcx.hir_body_owner_kind(owner_id).is_fn_or_closure() {
// The arguments and `self` are parented to the fn.
this.cx.var_parent = this.cx.parent.take();
this.cx.set_var_parent();
for param in body.params {
this.visit_pat(param.pat);
}

// The body of the every fn is a root scope.
this.cx.parent = this.cx.var_parent;
this.visit_expr(body.value)
} else {
// Only functions have an outer terminating (drop) scope, while
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_hir_typeck/src/rvalue_scopes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use hir::Node;
use hir::def_id::DefId;
use rustc_hir as hir;
use rustc_middle::bug;
use rustc_middle::middle::region::{RvalueCandidateType, Scope, ScopeTree};
use rustc_middle::middle::region::{RvalueCandidate, Scope, ScopeTree};
use rustc_middle::ty::RvalueScopes;
use tracing::debug;

Expand Down Expand Up @@ -55,15 +55,11 @@ fn record_rvalue_scope_rec(
fn record_rvalue_scope(
rvalue_scopes: &mut RvalueScopes,
expr: &hir::Expr<'_>,
candidate: &RvalueCandidateType,
candidate: &RvalueCandidate,
) {
debug!("resolve_rvalue_scope(expr={expr:?}, candidate={candidate:?})");
match candidate {
RvalueCandidateType::Borrow { lifetime, .. }
| RvalueCandidateType::Pattern { lifetime, .. } => {
record_rvalue_scope_rec(rvalue_scopes, expr, *lifetime)
} // FIXME(@dingxiangfei2009): handle the candidates in the function call arguments
}
record_rvalue_scope_rec(rvalue_scopes, expr, candidate.lifetime)
// FIXME(@dingxiangfei2009): handle the candidates in the function call arguments
}

pub(crate) fn resolve_rvalue_scopes<'a, 'tcx>(
Expand Down
31 changes: 13 additions & 18 deletions compiler/rustc_middle/src/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ pub struct ScopeTree {
/// and not the enclosing *statement*. Expressions that are not present in this
/// table are not rvalue candidates. The set of rvalue candidates is computed
/// during type check based on a traversal of the AST.
pub rvalue_candidates: HirIdMap<RvalueCandidateType>,
pub rvalue_candidates: HirIdMap<RvalueCandidate>,

/// Backwards incompatible scoping that will be introduced in future editions.
/// This information is used later for linting to identify locals and
Expand Down Expand Up @@ -308,15 +308,14 @@ pub struct ScopeTree {
pub yield_in_scope: UnordMap<Scope, Vec<YieldData>>,
}

/// Identifies the reason that a given expression is an rvalue candidate
/// (see the `rvalue_candidates` field for more information what rvalue
/// candidates in general). In constants, the `lifetime` field is None
/// to indicate that certain expressions escape into 'static and
/// should have no local cleanup scope.
/// See the `rvalue_candidates` field for more information on rvalue
/// candidates in general.
/// The `lifetime` field is None to indicate that certain expressions escape
/// into 'static and should have no local cleanup scope.
#[derive(Debug, Copy, Clone, HashStable)]
pub enum RvalueCandidateType {
Borrow { target: hir::ItemLocalId, lifetime: Option<Scope> },
Pattern { target: hir::ItemLocalId, lifetime: Option<Scope> },
pub struct RvalueCandidate {
pub target: hir::ItemLocalId,
pub lifetime: Option<Scope>,
}

#[derive(Debug, Copy, Clone, HashStable)]
Expand Down Expand Up @@ -344,16 +343,12 @@ impl ScopeTree {
self.var_map.insert(var, lifetime);
}

pub fn record_rvalue_candidate(&mut self, var: HirId, candidate_type: RvalueCandidateType) {
debug!("record_rvalue_candidate(var={var:?}, type={candidate_type:?})");
match &candidate_type {
RvalueCandidateType::Borrow { lifetime: Some(lifetime), .. }
| RvalueCandidateType::Pattern { lifetime: Some(lifetime), .. } => {
assert!(var.local_id != lifetime.local_id)
}
_ => {}
pub fn record_rvalue_candidate(&mut self, var: HirId, candidate: RvalueCandidate) {
debug!("record_rvalue_candidate(var={var:?}, candidate={candidate:?})");
if let Some(lifetime) = &candidate.lifetime {
assert!(var.local_id != lifetime.local_id)
}
self.rvalue_candidates.insert(var, candidate_type);
self.rvalue_candidates.insert(var, candidate);
}

/// Returns the narrowest scope that encloses `id`, if any.
Expand Down
Loading