diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 2f0bb24537e..984c95b314b 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -31,6 +31,7 @@ macro_rules! arena_types { [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, [decode] code_region: rustc_middle::mir::coverage::CodeRegion, [] const_allocs: rustc_middle::mir::interpret::Allocation, + [] region_scope_tree: rustc_middle::middle::region::ScopeTree, // Required for the incremental on-disk cache [] mir_keys: rustc_hir::def_id::DefIdSet, [] dropck_outlives: diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0c936b7ae10..fd1be1b4879 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1048,6 +1048,12 @@ desc { "reachability" } } + /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; + /// in the case of closures, this will be redirected to the enclosing function. + query region_scope_tree(def_id: DefId) -> &'tcx crate::middle::region::ScopeTree { + desc { |tcx| "computing drop scopes for `{}`", tcx.def_path_str(def_id) } + } + /// Generates a MIR body for the shim. query mir_shims(key: ty::InstanceDef<'tcx>) -> mir::Body<'tcx> { storage(ArenaCacheSelector<'tcx>) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6b92a4c0a2e..3c08db5dc68 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -6,7 +6,6 @@ use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource}; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; -use crate::middle::region::ScopeTree; use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath}; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstAllocation, ConstValue, Scalar}; @@ -538,12 +537,6 @@ pub struct TypeckResults<'tcx> { /// issue by fake reading `t`. pub closure_fake_reads: FxHashMap, FakeReadCause, hir::HirId)>>, - /// Tracks critical information about regions in a body. - /// This includes containment relationship between regions, - /// liveness relationship between variables and regions and - /// information about yield points. - pub region_scope_tree: ScopeTree, - /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions /// by applying extended parameter rules. /// Details may be find in `rustc_typeck::check::rvalue_scopes`. @@ -586,7 +579,6 @@ pub fn new(hir_owner: LocalDefId) -> TypeckResults<'tcx> { concrete_opaque_types: Default::default(), closure_min_captures: Default::default(), closure_fake_reads: Default::default(), - region_scope_tree: Default::default(), rvalue_scopes: Default::default(), generator_interior_types: ty::Binder::dummy(Default::default()), treat_byte_string_as_slice: Default::default(), diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index e8b939fb51d..a83328c0cab 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -108,8 +108,7 @@ fn ast_block_stmts( let_scope_stack.push(remainder_scope); // Declare the bindings, which may create a source scope. - let remainder_span = - remainder_scope.span(this.tcx, &this.typeck_results.region_scope_tree); + let remainder_span = remainder_scope.span(this.tcx, this.region_scope_tree); let visibility_scope = Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None)); diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 9df86c6ada1..15660365938 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -700,7 +700,7 @@ pub(crate) fn storage_live_binding( self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) }); // Altough there is almost always scope for given variable in corner cases // like #92893 we might get variable with no scope. - if let Some(region_scope) = self.typeck_results.region_scope_tree.var_scope(var.local_id) && schedule_drop{ + if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) && schedule_drop{ self.schedule_drop(span, region_scope, local_id, DropKind::Storage); } Place::from(local_id) @@ -713,7 +713,7 @@ pub(crate) fn schedule_drop_for_binding( for_guard: ForGuard, ) { let local_id = self.var_local_id(var, for_guard); - if let Some(region_scope) = self.typeck_results.region_scope_tree.var_scope(var.local_id) { + if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) { self.schedule_drop(span, region_scope, local_id, DropKind::Value); } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index c42f2b3a67a..4ae74433df6 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -398,6 +398,7 @@ struct Builder<'a, 'tcx> { tcx: TyCtxt<'tcx>, infcx: &'a InferCtxt<'a, 'tcx>, typeck_results: &'tcx TypeckResults<'tcx>, + region_scope_tree: &'tcx region::ScopeTree, param_env: ty::ParamEnv<'tcx>, thir: &'a Thir<'tcx>, @@ -880,6 +881,7 @@ fn new( tcx, infcx, typeck_results: tcx.typeck_opt_const_arg(def), + region_scope_tree: tcx.region_scope_tree(def.did), param_env, def_id: def.did.to_def_id(), hir_id, diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 53f9706f021..2d14a78accf 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -916,8 +916,7 @@ pub(crate) fn schedule_drop( } if scope.region_scope == region_scope { - let region_scope_span = - region_scope.span(self.tcx, &self.typeck_results.region_scope_tree); + let region_scope_span = region_scope.span(self.tcx, &self.region_scope_tree); // Attribute scope exit drops to scope's closing brace. let scope_end = self.tcx.sess.source_map().end_point(region_scope_span); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index bd17df60cd7..d853a5e9ee7 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -72,7 +72,7 @@ fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam) -> Cx<'tcx> { tcx, thir: Thir::new(), param_env: tcx.param_env(def.did), - region_scope_tree: &typeck_results.region_scope_tree, + region_scope_tree: tcx.region_scope_tree(def.did), typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, body_owner: def.did.to_def_id(), diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 649bc211321..ac2dc6522ad 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -4,7 +4,7 @@ }; use crate::check::callee::{self, DeferredCallResolution}; use crate::check::method::{self, MethodCallee, SelfSource}; -use crate::check::{region, rvalue_scopes}; +use crate::check::rvalue_scopes; use crate::check::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy}; use rustc_data_structures::captures::Captures; @@ -622,10 +622,9 @@ pub fn field_ty( } pub(in super::super) fn resolve_rvalue_scopes(&self, def_id: DefId) { - let scope_tree = region::region_scope_tree(self.tcx, def_id); + let scope_tree = self.tcx.region_scope_tree(def_id); let rvalue_scopes = { rvalue_scopes::resolve_rvalue_scopes(self, &scope_tree, def_id) }; let mut typeck_results = self.inh.typeck_results.borrow_mut(); - typeck_results.region_scope_tree = scope_tree; typeck_results.rvalue_scopes = rvalue_scopes; } diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 02167ddef44..f09c7f51f47 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -184,7 +184,7 @@ pub fn resolve_interior<'a, 'tcx>( let mut visitor = InteriorVisitor { fcx, types: FxIndexSet::default(), - region_scope_tree: &typeck_results.region_scope_tree, + region_scope_tree: fcx.tcx.region_scope_tree(def_id), rvalue_scopes: &typeck_results.rvalue_scopes, expr_count: 0, kind, @@ -195,7 +195,7 @@ pub fn resolve_interior<'a, 'tcx>( intravisit::walk_body(&mut visitor, body); // Check that we visited the same amount of expressions as the RegionResolutionVisitor - let region_expr_count = typeck_results.region_scope_tree.body_expr_count(body_id).unwrap(); + let region_expr_count = fcx.tcx.region_scope_tree(def_id).body_expr_count(body_id).unwrap(); assert_eq!(region_expr_count, visitor.expr_count); // The types are already kept in insertion order. diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs index ba6fcb98924..c2b4c478ba3 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs @@ -42,7 +42,7 @@ pub fn compute_drop_ranges<'a, 'tcx>( let consumed_borrowed_places = find_consumed_and_borrowed(fcx, def_id, body); let typeck_results = &fcx.typeck_results.borrow(); - let num_exprs = typeck_results.region_scope_tree.body_expr_count(body.id()).unwrap_or(0); + let num_exprs = fcx.tcx.region_scope_tree(def_id).body_expr_count(body.id()).unwrap_or(0); let (mut drop_ranges, borrowed_temporaries) = build_control_flow_graph( fcx.tcx.hir(), fcx.tcx, diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 280fae5fe6d..1df82eca82a 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -138,6 +138,7 @@ use crate::util::common::indenter; use self::coercion::DynamicCoerceMany; +use self::region::region_scope_tree; pub use self::Expectation::*; #[macro_export] @@ -255,6 +256,7 @@ pub fn provide(providers: &mut Providers) { check_trait_item_well_formed, check_impl_item_well_formed, check_mod_item_types, + region_scope_tree, ..*providers }; } diff --git a/compiler/rustc_typeck/src/check/region.rs b/compiler/rustc_typeck/src/check/region.rs index 43d189abcf7..9e94511fdc4 100644 --- a/compiler/rustc_typeck/src/check/region.rs +++ b/compiler/rustc_typeck/src/check/region.rs @@ -797,14 +797,14 @@ fn visit_local(&mut self, l: &'tcx Local<'tcx>) { /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; /// in the case of closures, this will be redirected to the enclosing function. -pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> ScopeTree { +pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { let typeck_root_def_id = tcx.typeck_root_def_id(def_id); if typeck_root_def_id != def_id { - return region_scope_tree(tcx, typeck_root_def_id); + return tcx.region_scope_tree(typeck_root_def_id); } let id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - if let Some(body_id) = tcx.hir().maybe_body_owned_by(id) { + let scope_tree = if let Some(body_id) = tcx.hir().maybe_body_owned_by(id) { let mut visitor = RegionResolutionVisitor { tcx, scope_tree: ScopeTree::default(), @@ -821,5 +821,7 @@ pub fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> ScopeTree { visitor.scope_tree } else { ScopeTree::default() - } + }; + + tcx.arena.alloc(scope_tree) } diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 16096ea3d74..c37f4ce3a93 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -71,8 +71,6 @@ pub fn resolve_type_vars_in_body( wbcx.visit_user_provided_sigs(); wbcx.visit_generator_interior_types(); - wbcx.typeck_results.region_scope_tree = - mem::take(&mut self.typeck_results.borrow_mut().region_scope_tree); wbcx.typeck_results.rvalue_scopes = mem::take(&mut self.typeck_results.borrow_mut().rvalue_scopes); diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index e2b82f9fd02..4f85364965b 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -55,11 +55,7 @@ pub(super) fn check<'tcx>( // ensure that the indexed variable was declared before the loop, see #601 if let Some(indexed_extent) = indexed_extent { let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id); - let parent_body_id = cx - .tcx - .hir() - .body_owned_by(cx.tcx.hir().local_def_id_to_hir_id(parent_def_id)); - let region_scope_tree = &cx.tcx.typeck_body(parent_body_id).region_scope_tree; + let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id); let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id).unwrap(); if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) { return; @@ -282,14 +278,9 @@ fn check( match res { Res::Local(hir_id) => { let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id); - let parent_body_id = self.cx - .tcx - .hir() - .body_owned_by(self.cx.tcx.hir().local_def_id_to_hir_id(parent_def_id)); let extent = self.cx .tcx - .typeck_body(parent_body_id) - .region_scope_tree + .region_scope_tree(parent_def_id) .var_scope(hir_id.local_id) .unwrap(); if index_used_directly { diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index db32b8d740b..2a80e6f918d 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -162,10 +162,7 @@ fn is_shadow( first: ItemLocalId, second: ItemLocalId, ) -> bool { - let scope_tree = &cx - .tcx - .typeck_body(cx.tcx.hir().body_owned_by(cx.tcx.hir().local_def_id_to_hir_id(owner))) - .region_scope_tree; + let scope_tree = cx.tcx.region_scope_tree(owner); let first_scope = scope_tree.var_scope(first).unwrap(); let second_scope = scope_tree.var_scope(second).unwrap(); scope_tree.is_subscope_of(second_scope, first_scope)