Skip to content

Commit fcfefea

Browse files
put up a facade so that features are tested earlier
1 parent 7f869e6 commit fcfefea

File tree

10 files changed

+84
-90
lines changed

10 files changed

+84
-90
lines changed

compiler/rustc_hir_analysis/src/check/scope_map.rs

+23-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use hir::intravisit::Visitor;
22
use rustc_hir as hir;
33
use rustc_index::Idx;
44
use rustc_middle::{
5-
middle::region::{BodyScopeMap, FirstStatementIndex, Scope, ScopeData},
5+
middle::region::{BodyScopeMap, FirstStatementIndex, Scope, ScopeData, ScopeMapFacade},
66
ty::TyCtxt,
77
};
88
use rustc_span::source_map;
@@ -493,17 +493,28 @@ impl<'tcx> Visitor<'tcx> for ScopeCollector<'tcx> {
493493
}
494494
}
495495

496-
pub fn body_scope_map(tcx: TyCtxt<'_>, def_id: hir::def_id::DefId) -> &BodyScopeMap {
496+
pub fn body_scope_map<'tcx>(
497+
tcx: TyCtxt<'tcx>,
498+
def_id: hir::def_id::DefId,
499+
) -> &'tcx ScopeMapFacade<'tcx> {
497500
let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
498-
if typeck_root_def_id != def_id {
499-
return tcx.body_scope_map(typeck_root_def_id);
500-
}
501-
let map = if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) {
502-
let mut collector = ScopeCollector::new(tcx);
503-
collector.visit_body(tcx.hir().body(body_id));
504-
BodyScopeMap { expr_scope: collector.expr_scope, new_var_scope: collector.new_var_scope }
501+
if tcx.sess.at_least_rust_2024() && tcx.features().new_temp_lifetime {
502+
if typeck_root_def_id != def_id {
503+
return tcx.body_scope_map(typeck_root_def_id);
504+
}
505+
let map = if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) {
506+
let mut collector = ScopeCollector::new(tcx);
507+
collector.visit_body(tcx.hir().body(body_id));
508+
BodyScopeMap {
509+
expr_scope: collector.expr_scope,
510+
new_var_scope: collector.new_var_scope,
511+
}
512+
} else {
513+
BodyScopeMap { expr_scope: <_>::default(), new_var_scope: <_>::default() }
514+
};
515+
let map = tcx.arena.alloc(map);
516+
tcx.arena.alloc(ScopeMapFacade::Edition2024(map))
505517
} else {
506-
BodyScopeMap { expr_scope: <_>::default(), new_var_scope: <_>::default() }
507-
};
508-
tcx.arena.alloc(map)
518+
tcx.arena.alloc(ScopeMapFacade::Classical(tcx.region_scope_tree(typeck_root_def_id)))
519+
}
509520
}

compiler/rustc_middle/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ macro_rules! arena_types {
4040
[] const_allocs: rustc_middle::mir::interpret::Allocation,
4141
[] region_scope_tree: rustc_middle::middle::region::ScopeTree,
4242
[] body_scope_map: rustc_middle::middle::region::BodyScopeMap,
43+
[] scope_map_facade: rustc_middle::middle::region::ScopeMapFacade<'tcx>,
4344
// Required for the incremental on-disk cache
4445
[] mir_keys: rustc_hir::def_id::DefIdSet,
4546
[] dropck_outlives:

compiler/rustc_middle/src/middle/region.rs

+31-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//!
77
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
88
9-
use crate::ty::TyCtxt;
9+
use crate::ty::{RvalueScopes, TyCtxt};
1010
use rustc_data_structures::fx::FxIndexMap;
1111
use rustc_data_structures::unord::UnordMap;
1212
use rustc_hir as hir;
@@ -410,11 +410,39 @@ pub struct BodyScopeMap {
410410
}
411411

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

417-
pub fn temporary_scope_new(&self, expr_id: hir::ItemLocalId) -> Option<Scope> {
417+
pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> Option<Scope> {
418418
self.expr_scope.get(&expr_id).copied().flatten()
419419
}
420420
}
421+
422+
/// Facade to switch between classical, pre-2024, temporary lifetime rules
423+
/// and Edition 2024 rules.
424+
#[derive(Clone, Debug, HashStable)]
425+
pub enum ScopeMapFacade<'tcx> {
426+
Classical(&'tcx ScopeTree),
427+
Edition2024(&'tcx BodyScopeMap),
428+
}
429+
430+
impl<'tcx> ScopeMapFacade<'tcx> {
431+
pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Option<Scope> {
432+
match self {
433+
ScopeMapFacade::Classical(map) => map.var_scope(var_id),
434+
ScopeMapFacade::Edition2024(map) => map.var_scope(var_id),
435+
}
436+
}
437+
438+
pub fn temporary_scope(
439+
&self,
440+
rvalue_scopes: &RvalueScopes,
441+
expr_id: hir::ItemLocalId,
442+
) -> Option<Scope> {
443+
match self {
444+
ScopeMapFacade::Classical(map) => rvalue_scopes.temporary_scope(map, expr_id),
445+
ScopeMapFacade::Edition2024(map) => map.temporary_scope(expr_id),
446+
}
447+
}
448+
}

compiler/rustc_middle/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,7 @@ rustc_queries! {
11401140

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

compiler/rustc_mir_build/src/build/matches/mod.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -798,11 +798,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
798798
self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) });
799799
// Although there is almost always scope for given variable in corner cases
800800
// like #92893 we might get variable with no scope.
801-
let scope = if let Some(scope_map) = self.scope_map {
802-
scope_map.var_scope_new(var.0.local_id)
803-
} else {
804-
self.region_scope_tree.var_scope(var.0.local_id)
805-
};
801+
let scope = self.scope_map.var_scope(var.0.local_id);
806802
if let Some(region_scope) = scope
807803
&& schedule_drop
808804
{
@@ -818,11 +814,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
818814
for_guard: ForGuard,
819815
) {
820816
let local_id = self.var_local_id(var, for_guard);
821-
let scope = if let Some(scope_map) = self.scope_map {
822-
scope_map.var_scope_new(var.0.local_id)
823-
} else {
824-
self.region_scope_tree.var_scope(var.0.local_id)
825-
};
817+
let scope = self.scope_map.var_scope(var.0.local_id);
826818
if let Some(region_scope) = scope {
827819
self.schedule_drop(span, region_scope, local_id, DropKind::Value);
828820
}

compiler/rustc_mir_build/src/build/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ struct Builder<'a, 'tcx> {
167167
tcx: TyCtxt<'tcx>,
168168
infcx: InferCtxt<'tcx>,
169169
region_scope_tree: &'tcx region::ScopeTree,
170-
scope_map: Option<&'tcx region::BodyScopeMap>,
170+
scope_map: &'tcx region::ScopeMapFacade<'tcx>,
171171
param_env: ty::ParamEnv<'tcx>,
172172

173173
thir: &'a Thir<'tcx>,
@@ -753,8 +753,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
753753
tcx,
754754
infcx,
755755
region_scope_tree: tcx.region_scope_tree(def),
756-
scope_map: (tcx.sess.at_least_rust_2024() && tcx.features().new_temp_lifetime)
757-
.then(|| tcx.body_scope_map(def)),
756+
scope_map: tcx.body_scope_map(def),
758757
param_env,
759758
def_id: def,
760759
hir_id,

compiler/rustc_mir_build/src/thir/cx/expr.rs

+14-35
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,8 @@ impl<'tcx> Cx<'tcx> {
236236
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
237237
let tcx = self.tcx;
238238
let expr_ty = self.typeck_results().expr_ty(expr);
239-
let temp_lifetime = if let Some(scope_map) = self.scope_map {
240-
scope_map.temporary_scope_new(expr.hir_id.local_id)
241-
} else {
242-
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
243-
};
239+
let temp_lifetime =
240+
self.scope_map.temporary_scope(self.rvalue_scopes, expr.hir_id.local_id);
244241

245242
let kind = match expr.kind {
246243
// Here comes the interesting stuff:
@@ -717,11 +714,8 @@ impl<'tcx> Cx<'tcx> {
717714
},
718715
hir::ExprKind::Loop(body, ..) => {
719716
let block_ty = self.typeck_results().node_type(body.hir_id);
720-
let temp_lifetime = if let Some(scope_map) = self.scope_map {
721-
scope_map.temporary_scope_new(body.hir_id.local_id)
722-
} else {
723-
self.rvalue_scopes.temporary_scope(self.region_scope_tree, body.hir_id.local_id)
724-
};
717+
let temp_lifetime =
718+
self.scope_map.temporary_scope(self.rvalue_scopes, body.hir_id.local_id);
725719
let block = self.mirror_block(body);
726720
let body = self.thir.exprs.push(Expr {
727721
ty: block_ty,
@@ -830,11 +824,8 @@ impl<'tcx> Cx<'tcx> {
830824
span: Span,
831825
overloaded_callee: Option<Ty<'tcx>>,
832826
) -> Expr<'tcx> {
833-
let temp_lifetime = if let Some(scope_map) = self.scope_map {
834-
scope_map.temporary_scope_new(expr.hir_id.local_id)
835-
} else {
836-
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
837-
};
827+
let temp_lifetime =
828+
self.scope_map.temporary_scope(self.rvalue_scopes, expr.hir_id.local_id);
838829
let (ty, user_ty) = match overloaded_callee {
839830
Some(fn_def) => (fn_def, None),
840831
None => {
@@ -920,11 +911,8 @@ impl<'tcx> Cx<'tcx> {
920911
// a constant reference (or constant raw pointer for `static mut`) in MIR
921912
Res::Def(DefKind::Static(_), id) => {
922913
let ty = self.tcx.static_ptr_ty(id);
923-
let temp_lifetime = if let Some(scope_map) = self.scope_map {
924-
scope_map.temporary_scope_new(expr.hir_id.local_id)
925-
} else {
926-
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
927-
};
914+
let temp_lifetime =
915+
self.scope_map.temporary_scope(self.rvalue_scopes, expr.hir_id.local_id);
928916
let kind = if self.tcx.is_thread_local_static(id) {
929917
ExprKind::ThreadLocalRef(id)
930918
} else {
@@ -1003,11 +991,8 @@ impl<'tcx> Cx<'tcx> {
1003991

1004992
// construct the complete expression `foo()` for the overloaded call,
1005993
// which will yield the &T type
1006-
let temp_lifetime = if let Some(scope_map) = self.scope_map {
1007-
scope_map.temporary_scope_new(expr.hir_id.local_id)
1008-
} else {
1009-
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
1010-
};
994+
let temp_lifetime =
995+
self.scope_map.temporary_scope(self.rvalue_scopes, expr.hir_id.local_id);
1011996
let fun = self.method_callee(expr, span, overloaded_callee);
1012997
let fun = self.thir.exprs.push(fun);
1013998
let fun_ty = self.thir[fun].ty;
@@ -1027,11 +1012,8 @@ impl<'tcx> Cx<'tcx> {
10271012
closure_expr: &'tcx hir::Expr<'tcx>,
10281013
place: HirPlace<'tcx>,
10291014
) -> Expr<'tcx> {
1030-
let temp_lifetime = if let Some(scope_map) = self.scope_map {
1031-
scope_map.temporary_scope_new(closure_expr.hir_id.local_id)
1032-
} else {
1033-
self.rvalue_scopes.temporary_scope(self.region_scope_tree, closure_expr.hir_id.local_id)
1034-
};
1015+
let temp_lifetime =
1016+
self.scope_map.temporary_scope(self.rvalue_scopes, closure_expr.hir_id.local_id);
10351017
let var_ty = place.base_ty;
10361018

10371019
// The result of capture analysis in `rustc_hir_analysis/check/upvar.rs`represents a captured path
@@ -1086,11 +1068,8 @@ impl<'tcx> Cx<'tcx> {
10861068
let upvar_capture = captured_place.info.capture_kind;
10871069
let captured_place_expr =
10881070
self.convert_captured_hir_place(closure_expr, captured_place.place.clone());
1089-
let temp_lifetime = if let Some(scope_map) = self.scope_map {
1090-
scope_map.temporary_scope_new(closure_expr.hir_id.local_id)
1091-
} else {
1092-
self.rvalue_scopes.temporary_scope(self.region_scope_tree, closure_expr.hir_id.local_id)
1093-
};
1071+
let temp_lifetime =
1072+
self.scope_map.temporary_scope(self.rvalue_scopes, closure_expr.hir_id.local_id);
10941073

10951074
match upvar_capture {
10961075
ty::UpvarCapture::ByValue => captured_place_expr,

compiler/rustc_mir_build/src/thir/cx/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ struct Cx<'tcx> {
5757

5858
param_env: ty::ParamEnv<'tcx>,
5959

60-
region_scope_tree: &'tcx region::ScopeTree,
61-
scope_map: Option<&'tcx region::BodyScopeMap>,
60+
scope_map: &'tcx region::ScopeMapFacade<'tcx>,
6261
typeck_results: &'tcx ty::TypeckResults<'tcx>,
6362
rvalue_scopes: &'tcx RvalueScopes,
6463

@@ -98,9 +97,7 @@ impl<'tcx> Cx<'tcx> {
9897
tcx,
9998
thir: Thir::new(body_type),
10099
param_env: tcx.param_env(def),
101-
region_scope_tree: tcx.region_scope_tree(def),
102-
scope_map: (tcx.sess.at_least_rust_2024() && tcx.features().new_temp_lifetime)
103-
.then(|| tcx.body_scope_map(def)),
100+
scope_map: tcx.body_scope_map(def),
104101
typeck_results,
105102
rvalue_scopes: &typeck_results.rvalue_scopes,
106103
body_owner: def.to_def_id(),

src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,7 @@ pub(super) fn check<'tcx>(
5757
if let Some(indexed_extent) = indexed_extent {
5858
let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id);
5959
let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id);
60-
let var_scope = if cx.tcx.sess.at_least_rust_2024() && cx.tcx.features().new_temp_lifetime {
61-
let scope_map = cx.tcx.body_scope_map(parent_def_id);
62-
scope_map.var_scope_new(pat.hir_id.local_id)
63-
} else {
64-
region_scope_tree.var_scope(pat.hir_id.local_id)
65-
};
60+
let var_scope = cx.tcx.body_scope_map(parent_def_id).var_scope(pat.hir_id.local_id);
6661
let pat_extent = var_scope.unwrap();
6762
if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) {
6863
return;
@@ -262,13 +257,12 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
262257
match res {
263258
Res::Local(hir_id) => {
264259
let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id);
265-
let region_scope_tree = self.cx.tcx.region_scope_tree(parent_def_id);
266-
let extent = if self.cx.tcx.sess.at_least_rust_2024() && self.cx.tcx.features().new_temp_lifetime {
267-
self.cx.tcx.body_scope_map(parent_def_id).var_scope_new(hir_id.local_id)
268-
} else {
269-
region_scope_tree.var_scope(hir_id.local_id)
270-
}
271-
.unwrap();
260+
let extent = self
261+
.cx
262+
.tcx
263+
.body_scope_map(parent_def_id)
264+
.var_scope(hir_id.local_id)
265+
.unwrap();
272266
if index_used_directly {
273267
self.indexed_directly.insert(
274268
seqvar.segments[0].ident.name,

src/tools/clippy/clippy_lints/src/shadow.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,7 @@ impl<'tcx> LateLintPass<'tcx> for Shadow {
163163
fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {
164164
let def_id = owner.to_def_id();
165165
let scope_tree = cx.tcx.region_scope_tree(def_id);
166-
let get_scope = |id| {
167-
if cx.tcx.sess.at_least_rust_2024() && cx.tcx.features().new_temp_lifetime {
168-
let scope_map = cx.tcx.body_scope_map(def_id);
169-
scope_map.var_scope_new(id)
170-
} else {
171-
scope_tree.var_scope(id)
172-
}
173-
};
166+
let get_scope = |id| cx.tcx.body_scope_map(def_id).var_scope(id);
174167
if let Some(first_scope) = get_scope(first) {
175168
if let Some(second_scope) = get_scope(second) {
176169
return scope_tree.is_subscope_of(second_scope, first_scope);

0 commit comments

Comments
 (0)