Skip to content

Commit

Permalink
put up a facade so that features are tested earlier
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Jan 30, 2024
1 parent 7f869e6 commit fcfefea
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 90 deletions.
35 changes: 23 additions & 12 deletions compiler/rustc_hir_analysis/src/check/scope_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use hir::intravisit::Visitor;
use rustc_hir as hir;
use rustc_index::Idx;
use rustc_middle::{
middle::region::{BodyScopeMap, FirstStatementIndex, Scope, ScopeData},
middle::region::{BodyScopeMap, FirstStatementIndex, Scope, ScopeData, ScopeMapFacade},
ty::TyCtxt,
};
use rustc_span::source_map;
Expand Down Expand Up @@ -493,17 +493,28 @@ impl<'tcx> Visitor<'tcx> for ScopeCollector<'tcx> {
}
}

pub fn body_scope_map(tcx: TyCtxt<'_>, def_id: hir::def_id::DefId) -> &BodyScopeMap {
pub fn body_scope_map<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: hir::def_id::DefId,
) -> &'tcx ScopeMapFacade<'tcx> {
let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
if typeck_root_def_id != def_id {
return tcx.body_scope_map(typeck_root_def_id);
}
let map = if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) {
let mut collector = ScopeCollector::new(tcx);
collector.visit_body(tcx.hir().body(body_id));
BodyScopeMap { expr_scope: collector.expr_scope, new_var_scope: collector.new_var_scope }
if tcx.sess.at_least_rust_2024() && tcx.features().new_temp_lifetime {
if typeck_root_def_id != def_id {
return tcx.body_scope_map(typeck_root_def_id);
}
let map = if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) {
let mut collector = ScopeCollector::new(tcx);
collector.visit_body(tcx.hir().body(body_id));
BodyScopeMap {
expr_scope: collector.expr_scope,
new_var_scope: collector.new_var_scope,
}
} else {
BodyScopeMap { expr_scope: <_>::default(), new_var_scope: <_>::default() }
};
let map = tcx.arena.alloc(map);
tcx.arena.alloc(ScopeMapFacade::Edition2024(map))
} else {
BodyScopeMap { expr_scope: <_>::default(), new_var_scope: <_>::default() }
};
tcx.arena.alloc(map)
tcx.arena.alloc(ScopeMapFacade::Classical(tcx.region_scope_tree(typeck_root_def_id)))
}
}
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ macro_rules! arena_types {
[] const_allocs: rustc_middle::mir::interpret::Allocation,
[] region_scope_tree: rustc_middle::middle::region::ScopeTree,
[] body_scope_map: rustc_middle::middle::region::BodyScopeMap,
[] scope_map_facade: rustc_middle::middle::region::ScopeMapFacade<'tcx>,
// Required for the incremental on-disk cache
[] mir_keys: rustc_hir::def_id::DefIdSet,
[] dropck_outlives:
Expand Down
34 changes: 31 additions & 3 deletions compiler/rustc_middle/src/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html

use crate::ty::TyCtxt;
use crate::ty::{RvalueScopes, TyCtxt};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::unord::UnordMap;
use rustc_hir as hir;
Expand Down Expand Up @@ -410,11 +410,39 @@ pub struct BodyScopeMap {
}

impl BodyScopeMap {
pub fn var_scope_new(&self, var_id: hir::ItemLocalId) -> Option<Scope> {
pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Option<Scope> {
self.new_var_scope.get(&var_id).copied().flatten()
}

pub fn temporary_scope_new(&self, expr_id: hir::ItemLocalId) -> Option<Scope> {
pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> Option<Scope> {
self.expr_scope.get(&expr_id).copied().flatten()
}
}

/// Facade to switch between classical, pre-2024, temporary lifetime rules
/// and Edition 2024 rules.
#[derive(Clone, Debug, HashStable)]
pub enum ScopeMapFacade<'tcx> {
Classical(&'tcx ScopeTree),
Edition2024(&'tcx BodyScopeMap),
}

impl<'tcx> ScopeMapFacade<'tcx> {
pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Option<Scope> {
match self {
ScopeMapFacade::Classical(map) => map.var_scope(var_id),
ScopeMapFacade::Edition2024(map) => map.var_scope(var_id),
}
}

pub fn temporary_scope(
&self,
rvalue_scopes: &RvalueScopes,
expr_id: hir::ItemLocalId,
) -> Option<Scope> {
match self {
ScopeMapFacade::Classical(map) => rvalue_scopes.temporary_scope(map, expr_id),
ScopeMapFacade::Edition2024(map) => map.temporary_scope(expr_id),
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ rustc_queries! {

/// Per-body `region::BodyScopeMap`. The `DefId` should point to the owner of the body;
/// in the case of closures, this will be redirected to the enclosing function.
query body_scope_map(def_id: DefId) -> &'tcx crate::middle::region::BodyScopeMap {
query body_scope_map(def_id: DefId) -> &'tcx crate::middle::region::ScopeMapFacade<'tcx> {
desc { |tcx| "computing drop scopes and temporary lifetime for `{}`", tcx.def_path_str(def_id) }
}

Expand Down
12 changes: 2 additions & 10 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -798,11 +798,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) });
// Although there is almost always scope for given variable in corner cases
// like #92893 we might get variable with no scope.
let scope = if let Some(scope_map) = self.scope_map {
scope_map.var_scope_new(var.0.local_id)
} else {
self.region_scope_tree.var_scope(var.0.local_id)
};
let scope = self.scope_map.var_scope(var.0.local_id);
if let Some(region_scope) = scope
&& schedule_drop
{
Expand All @@ -818,11 +814,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
for_guard: ForGuard,
) {
let local_id = self.var_local_id(var, for_guard);
let scope = if let Some(scope_map) = self.scope_map {
scope_map.var_scope_new(var.0.local_id)
} else {
self.region_scope_tree.var_scope(var.0.local_id)
};
let scope = self.scope_map.var_scope(var.0.local_id);
if let Some(region_scope) = scope {
self.schedule_drop(span, region_scope, local_id, DropKind::Value);
}
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ struct Builder<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
infcx: InferCtxt<'tcx>,
region_scope_tree: &'tcx region::ScopeTree,
scope_map: Option<&'tcx region::BodyScopeMap>,
scope_map: &'tcx region::ScopeMapFacade<'tcx>,
param_env: ty::ParamEnv<'tcx>,

thir: &'a Thir<'tcx>,
Expand Down Expand Up @@ -753,8 +753,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
tcx,
infcx,
region_scope_tree: tcx.region_scope_tree(def),
scope_map: (tcx.sess.at_least_rust_2024() && tcx.features().new_temp_lifetime)
.then(|| tcx.body_scope_map(def)),
scope_map: tcx.body_scope_map(def),
param_env,
def_id: def,
hir_id,
Expand Down
49 changes: 14 additions & 35 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,8 @@ impl<'tcx> Cx<'tcx> {
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
let tcx = self.tcx;
let expr_ty = self.typeck_results().expr_ty(expr);
let temp_lifetime = if let Some(scope_map) = self.scope_map {
scope_map.temporary_scope_new(expr.hir_id.local_id)
} else {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
};
let temp_lifetime =
self.scope_map.temporary_scope(self.rvalue_scopes, expr.hir_id.local_id);

let kind = match expr.kind {
// Here comes the interesting stuff:
Expand Down Expand Up @@ -717,11 +714,8 @@ impl<'tcx> Cx<'tcx> {
},
hir::ExprKind::Loop(body, ..) => {
let block_ty = self.typeck_results().node_type(body.hir_id);
let temp_lifetime = if let Some(scope_map) = self.scope_map {
scope_map.temporary_scope_new(body.hir_id.local_id)
} else {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, body.hir_id.local_id)
};
let temp_lifetime =
self.scope_map.temporary_scope(self.rvalue_scopes, body.hir_id.local_id);
let block = self.mirror_block(body);
let body = self.thir.exprs.push(Expr {
ty: block_ty,
Expand Down Expand Up @@ -830,11 +824,8 @@ impl<'tcx> Cx<'tcx> {
span: Span,
overloaded_callee: Option<Ty<'tcx>>,
) -> Expr<'tcx> {
let temp_lifetime = if let Some(scope_map) = self.scope_map {
scope_map.temporary_scope_new(expr.hir_id.local_id)
} else {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
};
let temp_lifetime =
self.scope_map.temporary_scope(self.rvalue_scopes, expr.hir_id.local_id);
let (ty, user_ty) = match overloaded_callee {
Some(fn_def) => (fn_def, None),
None => {
Expand Down Expand Up @@ -920,11 +911,8 @@ impl<'tcx> Cx<'tcx> {
// a constant reference (or constant raw pointer for `static mut`) in MIR
Res::Def(DefKind::Static(_), id) => {
let ty = self.tcx.static_ptr_ty(id);
let temp_lifetime = if let Some(scope_map) = self.scope_map {
scope_map.temporary_scope_new(expr.hir_id.local_id)
} else {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
};
let temp_lifetime =
self.scope_map.temporary_scope(self.rvalue_scopes, expr.hir_id.local_id);
let kind = if self.tcx.is_thread_local_static(id) {
ExprKind::ThreadLocalRef(id)
} else {
Expand Down Expand Up @@ -1003,11 +991,8 @@ impl<'tcx> Cx<'tcx> {

// construct the complete expression `foo()` for the overloaded call,
// which will yield the &T type
let temp_lifetime = if let Some(scope_map) = self.scope_map {
scope_map.temporary_scope_new(expr.hir_id.local_id)
} else {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
};
let temp_lifetime =
self.scope_map.temporary_scope(self.rvalue_scopes, expr.hir_id.local_id);
let fun = self.method_callee(expr, span, overloaded_callee);
let fun = self.thir.exprs.push(fun);
let fun_ty = self.thir[fun].ty;
Expand All @@ -1027,11 +1012,8 @@ impl<'tcx> Cx<'tcx> {
closure_expr: &'tcx hir::Expr<'tcx>,
place: HirPlace<'tcx>,
) -> Expr<'tcx> {
let temp_lifetime = if let Some(scope_map) = self.scope_map {
scope_map.temporary_scope_new(closure_expr.hir_id.local_id)
} else {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, closure_expr.hir_id.local_id)
};
let temp_lifetime =
self.scope_map.temporary_scope(self.rvalue_scopes, closure_expr.hir_id.local_id);
let var_ty = place.base_ty;

// The result of capture analysis in `rustc_hir_analysis/check/upvar.rs`represents a captured path
Expand Down Expand Up @@ -1086,11 +1068,8 @@ impl<'tcx> Cx<'tcx> {
let upvar_capture = captured_place.info.capture_kind;
let captured_place_expr =
self.convert_captured_hir_place(closure_expr, captured_place.place.clone());
let temp_lifetime = if let Some(scope_map) = self.scope_map {
scope_map.temporary_scope_new(closure_expr.hir_id.local_id)
} else {
self.rvalue_scopes.temporary_scope(self.region_scope_tree, closure_expr.hir_id.local_id)
};
let temp_lifetime =
self.scope_map.temporary_scope(self.rvalue_scopes, closure_expr.hir_id.local_id);

match upvar_capture {
ty::UpvarCapture::ByValue => captured_place_expr,
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_mir_build/src/thir/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ struct Cx<'tcx> {

param_env: ty::ParamEnv<'tcx>,

region_scope_tree: &'tcx region::ScopeTree,
scope_map: Option<&'tcx region::BodyScopeMap>,
scope_map: &'tcx region::ScopeMapFacade<'tcx>,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
rvalue_scopes: &'tcx RvalueScopes,

Expand Down Expand Up @@ -98,9 +97,7 @@ impl<'tcx> Cx<'tcx> {
tcx,
thir: Thir::new(body_type),
param_env: tcx.param_env(def),
region_scope_tree: tcx.region_scope_tree(def),
scope_map: (tcx.sess.at_least_rust_2024() && tcx.features().new_temp_lifetime)
.then(|| tcx.body_scope_map(def)),
scope_map: tcx.body_scope_map(def),
typeck_results,
rvalue_scopes: &typeck_results.rvalue_scopes,
body_owner: def.to_def_id(),
Expand Down
20 changes: 7 additions & 13 deletions src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,7 @@ pub(super) fn check<'tcx>(
if let Some(indexed_extent) = indexed_extent {
let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id);
let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id);
let var_scope = if cx.tcx.sess.at_least_rust_2024() && cx.tcx.features().new_temp_lifetime {
let scope_map = cx.tcx.body_scope_map(parent_def_id);
scope_map.var_scope_new(pat.hir_id.local_id)
} else {
region_scope_tree.var_scope(pat.hir_id.local_id)
};
let var_scope = cx.tcx.body_scope_map(parent_def_id).var_scope(pat.hir_id.local_id);
let pat_extent = var_scope.unwrap();
if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) {
return;
Expand Down Expand Up @@ -262,13 +257,12 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
match res {
Res::Local(hir_id) => {
let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id);
let region_scope_tree = self.cx.tcx.region_scope_tree(parent_def_id);
let extent = if self.cx.tcx.sess.at_least_rust_2024() && self.cx.tcx.features().new_temp_lifetime {
self.cx.tcx.body_scope_map(parent_def_id).var_scope_new(hir_id.local_id)
} else {
region_scope_tree.var_scope(hir_id.local_id)
}
.unwrap();
let extent = self
.cx
.tcx
.body_scope_map(parent_def_id)
.var_scope(hir_id.local_id)
.unwrap();
if index_used_directly {
self.indexed_directly.insert(
seqvar.segments[0].ident.name,
Expand Down
9 changes: 1 addition & 8 deletions src/tools/clippy/clippy_lints/src/shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,7 @@ impl<'tcx> LateLintPass<'tcx> for Shadow {
fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {
let def_id = owner.to_def_id();
let scope_tree = cx.tcx.region_scope_tree(def_id);
let get_scope = |id| {
if cx.tcx.sess.at_least_rust_2024() && cx.tcx.features().new_temp_lifetime {
let scope_map = cx.tcx.body_scope_map(def_id);
scope_map.var_scope_new(id)
} else {
scope_tree.var_scope(id)
}
};
let get_scope = |id| cx.tcx.body_scope_map(def_id).var_scope(id);
if let Some(first_scope) = get_scope(first) {
if let Some(second_scope) = get_scope(second) {
return scope_tree.is_subscope_of(second_scope, first_scope);
Expand Down

0 comments on commit fcfefea

Please sign in to comment.