From fd40d0c210c684b51fb3e8794c92fb4244197efb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 26 Nov 2019 19:55:03 +0200 Subject: [PATCH 1/3] rustc: move MIR source_scope_local_data's ClearCrossCrate to be around elements. --- src/librustc/mir/mod.rs | 11 +++- src/librustc_mir/borrow_check/mod.rs | 67 ++++++++++---------- src/librustc_mir/build/mod.rs | 9 ++- src/librustc_mir/build/scope.rs | 11 ++-- src/librustc_mir/interpret/eval_context.rs | 4 +- src/librustc_mir/shim.rs | 16 +++-- src/librustc_mir/transform/check_unsafety.rs | 31 +++------ src/librustc_mir/transform/const_prop.rs | 49 +++++--------- 8 files changed, 94 insertions(+), 104 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index c745dd9444cd6..8b734057dd03c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -106,7 +106,7 @@ pub struct Body<'tcx> { /// Crate-local information for each source scope, that can't (and /// needn't) be tracked across crates. - pub source_scope_local_data: ClearCrossCrate>, + pub source_scope_local_data: IndexVec>, /// The yield type of the function, if it is a generator. pub yield_ty: Option>, @@ -163,7 +163,7 @@ impl<'tcx> Body<'tcx> { pub fn new( basic_blocks: IndexVec>, source_scopes: IndexVec, - source_scope_local_data: ClearCrossCrate>, + source_scope_local_data: IndexVec>, local_decls: LocalDecls<'tcx>, user_type_annotations: CanonicalUserTypeAnnotations<'tcx>, arg_count: usize, @@ -429,6 +429,13 @@ pub enum ClearCrossCrate { } impl ClearCrossCrate { + pub fn as_ref(&'a self) -> ClearCrossCrate<&'a T> { + match self { + ClearCrossCrate::Clear => ClearCrossCrate::Clear, + ClearCrossCrate::Set(v) => ClearCrossCrate::Set(v), + } + } + pub fn assert_crate_local(self) -> T { match self { ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"), diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 649aeac12de94..c5236407d135f 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -300,11 +300,10 @@ fn do_mir_borrowck<'a, 'tcx>( let mut initial_diag = mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow); - let lint_root = if let ClearCrossCrate::Set(ref vsi) = mbcx.body.source_scope_local_data { - let scope = mbcx.body.source_info(location).scope; - vsi[scope].lint_root - } else { - id + let scope = mbcx.body.source_info(location).scope; + let lint_root = match &mbcx.body.source_scope_local_data[scope] { + ClearCrossCrate::Set(data) => data.lint_root, + _ => id, }; // Span and message don't matter; we overwrite them below anyway @@ -338,38 +337,40 @@ fn do_mir_borrowck<'a, 'tcx>( debug!("mbcx.used_mut: {:?}", mbcx.used_mut); let used_mut = mbcx.used_mut; for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) { - if let ClearCrossCrate::Set(ref vsi) = mbcx.body.source_scope_local_data { - let local_decl = &mbcx.body.local_decls[local]; - - // Skip over locals that begin with an underscore or have no name - match mbcx.local_names[local] { - Some(name) => if name.as_str().starts_with("_") { - continue; - }, - None => continue, - } + let local_decl = &mbcx.body.local_decls[local]; + let lint_root = match &mbcx.body.source_scope_local_data[local_decl.source_info.scope] { + ClearCrossCrate::Set(data) => data.lint_root, + _ => continue, + }; - let span = local_decl.source_info.span; - if span.desugaring_kind().is_some() { - // If the `mut` arises as part of a desugaring, we should ignore it. + // Skip over locals that begin with an underscore or have no name + match mbcx.local_names[local] { + Some(name) => if name.as_str().starts_with("_") { continue; - } + }, + None => continue, + } - let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); - tcx.struct_span_lint_hir( - UNUSED_MUT, - vsi[local_decl.source_info.scope].lint_root, - span, - "variable does not need to be mutable", - ) - .span_suggestion_short( - mut_span, - "remove this `mut`", - String::new(), - Applicability::MachineApplicable, - ) - .emit(); + let span = local_decl.source_info.span; + if span.desugaring_kind().is_some() { + // If the `mut` arises as part of a desugaring, we should ignore it. + continue; } + + let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); + tcx.struct_span_lint_hir( + UNUSED_MUT, + lint_root, + span, + "variable does not need to be mutable", + ) + .span_suggestion_short( + mut_span, + "remove this `mut`", + String::new(), + Applicability::MachineApplicable, + ) + .emit(); } // Buffer any move errors that we collected and de-duplicated. diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 180f2cc089f02..15b7789e811da 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -309,7 +309,7 @@ struct Builder<'a, 'tcx> { /// The vector of all scopes that we have created thus far; /// we track this for debuginfo later. source_scopes: IndexVec, - source_scope_local_data: IndexVec, + source_scope_local_data: IndexVec>, source_scope: SourceScope, /// The guard-context: each time we build the guard expression for @@ -741,7 +741,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Body::new( self.cfg.basic_blocks, self.source_scopes, - ClearCrossCrate::Set(self.source_scope_local_data), + self.source_scope_local_data, self.local_decls, self.canonical_user_type_annotations, self.arg_count, @@ -941,7 +941,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.hir.root_lint_level ); let parent_root = tcx.maybe_lint_level_root_bounded( - self.source_scope_local_data[original_source_scope].lint_root, + self.source_scope_local_data[original_source_scope] + .as_ref() + .assert_crate_local() + .lint_root, self.hir.root_lint_level, ); if current_root != parent_root { diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 1b3d8641f204e..f8cc5edaae5ef 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -430,7 +430,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // We estimate the true lint roots here to avoid creating a lot of source scopes. let parent_root = tcx.maybe_lint_level_root_bounded( - self.source_scope_local_data[source_scope].lint_root, + self.source_scope_local_data[source_scope] + .as_ref() + .assert_crate_local() + .lint_root, self.hir.root_lint_level, ); let current_root = tcx.maybe_lint_level_root_bounded( @@ -657,13 +660,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { lint_root: if let LintLevel::Explicit(lint_root) = lint_level { lint_root } else { - self.source_scope_local_data[parent].lint_root + self.source_scope_local_data[parent].as_ref().assert_crate_local().lint_root }, safety: safety.unwrap_or_else(|| { - self.source_scope_local_data[parent].safety + self.source_scope_local_data[parent].as_ref().assert_crate_local().safety }) }; - self.source_scope_local_data.push(scope_local_data); + self.source_scope_local_data.push(ClearCrossCrate::Set(scope_local_data)); scope } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 626e81fa91186..4b07f217ab3f5 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -849,8 +849,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { block.terminator().source_info }; - match body.source_scope_local_data { - mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root), + match &body.source_scope_local_data[source_info.scope] { + mir::ClearCrossCrate::Set(data) => Some(data.lint_root), mir::ClearCrossCrate::Clear => None, } }); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index b5cb6a92816be..0128d15c6eaec 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -201,7 +201,9 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) IndexVec::from_elem_n( SourceScopeData { span: span, parent_scope: None }, 1 ), - ClearCrossCrate::Clear, + IndexVec::from_elem_n( + ClearCrossCrate::Clear, 1 + ), local_decls_for_sig(&sig, span), IndexVec::new(), sig.inputs().len(), @@ -367,7 +369,9 @@ impl CloneShimBuilder<'tcx> { IndexVec::from_elem_n( SourceScopeData { span: self.span, parent_scope: None }, 1 ), - ClearCrossCrate::Clear, + IndexVec::from_elem_n( + ClearCrossCrate::Clear, 1 + ), self.local_decls, IndexVec::new(), self.sig.inputs().len(), @@ -827,7 +831,9 @@ fn build_call_shim<'tcx>( IndexVec::from_elem_n( SourceScopeData { span: span, parent_scope: None }, 1 ), - ClearCrossCrate::Clear, + IndexVec::from_elem_n( + ClearCrossCrate::Clear, 1 + ), local_decls, IndexVec::new(), sig.inputs().len(), @@ -913,7 +919,9 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> { IndexVec::from_elem_n( SourceScopeData { span: span, parent_scope: None }, 1 ), - ClearCrossCrate::Clear, + IndexVec::from_elem_n( + ClearCrossCrate::Clear, 1 + ), local_decls, IndexVec::new(), sig.inputs().len(), diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index b7cc4e9fcf66c..b1c4101dbc759 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -1,6 +1,4 @@ use rustc_data_structures::fx::FxHashSet; -use rustc_index::vec::IndexVec; -use rustc_data_structures::sync::Lrc; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt}; @@ -24,7 +22,6 @@ pub struct UnsafetyChecker<'a, 'tcx> { body: &'a Body<'tcx>, const_context: bool, min_const_fn: bool, - source_scope_local_data: &'a IndexVec, violations: Vec, source_info: SourceInfo, tcx: TyCtxt<'tcx>, @@ -39,7 +36,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { const_context: bool, min_const_fn: bool, body: &'a Body<'tcx>, - source_scope_local_data: &'a IndexVec, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Self { @@ -51,7 +47,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { body, const_context, min_const_fn, - source_scope_local_data, violations: vec![], source_info: SourceInfo { span: body.span, @@ -219,8 +214,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if context.is_borrow() { if util::is_disaligned(self.tcx, self.body, self.param_env, place) { let source_info = self.source_info; - let lint_root = - self.source_scope_local_data[source_info.scope].lint_root; + let lint_root = self.body.source_scope_local_data[source_info.scope] + .as_ref() + .assert_crate_local() + .lint_root; self.register_violations(&[UnsafetyViolation { source_info, description: Symbol::intern("borrow of packed field"), @@ -346,7 +343,10 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { fn register_violations(&mut self, violations: &[UnsafetyViolation], unsafe_blocks: &[(hir::HirId, bool)]) { - let safety = self.source_scope_local_data[self.source_info.scope].safety; + let safety = self.body.source_scope_local_data[self.source_info.scope] + .as_ref() + .assert_crate_local() + .safety; let within_unsafe = match safety { // `unsafe` blocks are required in safe code Safety::Safe => { @@ -516,17 +516,6 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult // `mir_built` force this. let body = &tcx.mir_built(def_id).borrow(); - let source_scope_local_data = match body.source_scope_local_data { - ClearCrossCrate::Set(ref data) => data, - ClearCrossCrate::Clear => { - debug!("unsafety_violations: {:?} - remote, skipping", def_id); - return UnsafetyCheckResult { - violations: Lrc::new([]), - unsafe_blocks: Lrc::new([]) - } - } - }; - let param_env = tcx.param_env(def_id); let id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -536,9 +525,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false), }; - let mut checker = UnsafetyChecker::new( - const_context, min_const_fn, - body, source_scope_local_data, tcx, param_env); + let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env); checker.visit_body(body); check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks); diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 8de16308e8375..c2280fafafb74 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -74,17 +74,11 @@ impl<'tcx> MirPass<'tcx> for ConstProp { trace!("ConstProp starting for {:?}", source.def_id()); - // Steal some data we need from `body`. - let source_scope_local_data = std::mem::replace( - &mut body.source_scope_local_data, - ClearCrossCrate::Clear - ); - let dummy_body = &Body::new( body.basic_blocks().clone(), Default::default(), - ClearCrossCrate::Clear, + body.source_scope_local_data.clone(), body.local_decls.clone(), Default::default(), body.arg_count, @@ -100,19 +94,11 @@ impl<'tcx> MirPass<'tcx> for ConstProp { let mut optimization_finder = ConstPropagator::new( body, dummy_body, - source_scope_local_data, tcx, source ); optimization_finder.visit_body(body); - // put back the data we stole from `mir` - let source_scope_local_data = optimization_finder.release_stolen_data(); - std::mem::replace( - &mut body.source_scope_local_data, - source_scope_local_data - ); - trace!("ConstProp done for {:?}", source.def_id()); } } @@ -265,7 +251,9 @@ struct ConstPropagator<'mir, 'tcx> { source: MirSource<'tcx>, can_const_prop: IndexVec, param_env: ParamEnv<'tcx>, - source_scope_local_data: ClearCrossCrate>, + // FIXME(eddyb) avoid cloning these two fields more than once, + // by accessing them through `ecx` instead. + source_scope_local_data: IndexVec>, local_decls: IndexVec>, ret: Option>, } @@ -297,7 +285,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn new( body: &Body<'tcx>, dummy_body: &'mir Body<'tcx>, - source_scope_local_data: ClearCrossCrate>, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, ) -> ConstPropagator<'mir, 'tcx> { @@ -335,17 +322,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { source, param_env, can_const_prop, - source_scope_local_data, + // FIXME(eddyb) avoid cloning these two fields more than once, + // by accessing them through `ecx` instead. + source_scope_local_data: body.source_scope_local_data.clone(), //FIXME(wesleywiser) we can't steal this because `Visitor::super_visit_body()` needs it local_decls: body.local_decls.clone(), ret: ret.map(Into::into), } } - fn release_stolen_data(self) -> ClearCrossCrate> { - self.source_scope_local_data - } - fn get_const(&self, local: Local) -> Option> { if local == RETURN_PLACE { // Try to read the return place as an immediate so that if it is representable as a @@ -375,14 +360,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { F: FnOnce(&mut Self) -> InterpResult<'tcx, T>, { self.ecx.tcx.span = source_info.span; - let lint_root = match self.source_scope_local_data { - ClearCrossCrate::Set(ref ivs) => { - //FIXME(#51314): remove this check - if source_info.scope.index() >= ivs.len() { - return None; - } - ivs[source_info.scope].lint_root - }, + // FIXME(eddyb) move this to the `Panic(_)` error case, so that + // `f(self)` is always called, and that the only difference when + // `source_scope_local_data` is missing, is that the lint isn't emitted. + let lint_root = match &self.source_scope_local_data[source_info.scope] { + ClearCrossCrate::Set(data) => data.lint_root, ClearCrossCrate::Clear => return None, }; let r = match f(self) { @@ -506,8 +488,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let right_size = r.layout.size; let r_bits = r.to_scalar().and_then(|r| r.to_bits(right_size)); if r_bits.ok().map_or(false, |b| b >= left_bits as u128) { - let source_scope_local_data = match self.source_scope_local_data { - ClearCrossCrate::Set(ref data) => data, + let lint_root = match &self.source_scope_local_data[source_info.scope] { + ClearCrossCrate::Set(data) => data.lint_root, ClearCrossCrate::Clear => return None, }; let dir = if *op == BinOp::Shr { @@ -515,10 +497,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } else { "left" }; - let hir_id = source_scope_local_data[source_info.scope].lint_root; self.tcx.lint_hir( ::rustc::lint::builtin::EXCEEDING_BITSHIFTS, - hir_id, + lint_root, span, &format!("attempt to shift {} with overflow", dir)); return None; From 314f8d524a6277cf82f0b29a4db0715a3a7b4b02 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 26 Nov 2019 19:55:32 +0200 Subject: [PATCH 2/3] rustc_mir: fix inliner to also copy over source_scope_local_data. --- src/librustc_mir/transform/inline.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 867673beb35cc..70a0fb2d1035c 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -388,16 +388,25 @@ impl Inliner<'tcx> { let mut local_map = IndexVec::with_capacity(callee_body.local_decls.len()); let mut scope_map = IndexVec::with_capacity(callee_body.source_scopes.len()); - for mut scope in callee_body.source_scopes.iter().cloned() { + for (callee_idx, scope) in callee_body.source_scopes.iter_enumerated() { + let mut scope = scope.clone(); if scope.parent_scope.is_none() { scope.parent_scope = Some(callsite.location.scope); + // FIXME(eddyb) is this really needed? + // (also note that it's always overwritten below) scope.span = callee_body.span; } + // FIXME(eddyb) this doesn't seem right at all. + // The inlined source scopes should probably be annotated as + // such, but also contain all of the original information. scope.span = callsite.location.span; let idx = caller_body.source_scopes.push(scope); scope_map.push(idx); + + let local_data = callee_body.source_scope_local_data[callee_idx].clone(); + assert_eq!(idx, caller_body.source_scope_local_data.push(local_data)); } for loc in callee_body.vars_and_temps_iter() { From 3aead8538adcc9f80ea1b77fed5b964f155bc093 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 26 Nov 2019 22:17:35 +0200 Subject: [PATCH 3/3] rustc: move mir::SourceScopeLocalData to a field of SourceScopeData. --- src/librustc/mir/mod.rs | 10 +++---- src/librustc/mir/visit.rs | 1 + src/librustc_mir/borrow_check/mod.rs | 4 +-- src/librustc_mir/build/mod.rs | 6 ++--- src/librustc_mir/build/scope.rs | 20 +++++++------- src/librustc_mir/interpret/eval_context.rs | 2 +- src/librustc_mir/shim.rs | 28 +++++++++----------- src/librustc_mir/transform/check_unsafety.rs | 6 +++-- src/librustc_mir/transform/const_prop.rs | 17 ++++++------ src/librustc_mir/transform/inline.rs | 6 +---- src/librustc_mir/transform/promote_consts.rs | 1 - 11 files changed, 45 insertions(+), 56 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 8b734057dd03c..3e3184260f099 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -104,10 +104,6 @@ pub struct Body<'tcx> { /// and used for debuginfo. Indexed by a `SourceScope`. pub source_scopes: IndexVec, - /// Crate-local information for each source scope, that can't (and - /// needn't) be tracked across crates. - pub source_scope_local_data: IndexVec>, - /// The yield type of the function, if it is a generator. pub yield_ty: Option>, @@ -163,7 +159,6 @@ impl<'tcx> Body<'tcx> { pub fn new( basic_blocks: IndexVec>, source_scopes: IndexVec, - source_scope_local_data: IndexVec>, local_decls: LocalDecls<'tcx>, user_type_annotations: CanonicalUserTypeAnnotations<'tcx>, arg_count: usize, @@ -183,7 +178,6 @@ impl<'tcx> Body<'tcx> { phase: MirPhase::Build, basic_blocks, source_scopes, - source_scope_local_data, yield_ty: None, generator_drop: None, generator_layout: None, @@ -2028,6 +2022,10 @@ rustc_index::newtype_index! { pub struct SourceScopeData { pub span: Span, pub parent_scope: Option, + + /// Crate-local information for this source scope, that can't (and + /// needn't) be tracked across crates. + pub local_data: ClearCrossCrate, } #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 464d4c74366e5..348d516d99f60 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -317,6 +317,7 @@ macro_rules! make_mir_visitor { let SourceScopeData { span, parent_scope, + local_data: _, } = scope_data; self.visit_span(span); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index c5236407d135f..3a783f674e9ae 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -301,7 +301,7 @@ fn do_mir_borrowck<'a, 'tcx>( mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow); let scope = mbcx.body.source_info(location).scope; - let lint_root = match &mbcx.body.source_scope_local_data[scope] { + let lint_root = match &mbcx.body.source_scopes[scope].local_data { ClearCrossCrate::Set(data) => data.lint_root, _ => id, }; @@ -338,7 +338,7 @@ fn do_mir_borrowck<'a, 'tcx>( let used_mut = mbcx.used_mut; for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) { let local_decl = &mbcx.body.local_decls[local]; - let lint_root = match &mbcx.body.source_scope_local_data[local_decl.source_info.scope] { + let lint_root = match &mbcx.body.source_scopes[local_decl.source_info.scope].local_data { ClearCrossCrate::Set(data) => data.lint_root, _ => continue, }; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 15b7789e811da..775a50f10ff32 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -309,7 +309,6 @@ struct Builder<'a, 'tcx> { /// The vector of all scopes that we have created thus far; /// we track this for debuginfo later. source_scopes: IndexVec, - source_scope_local_data: IndexVec>, source_scope: SourceScope, /// The guard-context: each time we build the guard expression for @@ -704,7 +703,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block_context: BlockContext::new(), source_scopes: IndexVec::new(), source_scope: OUTERMOST_SOURCE_SCOPE, - source_scope_local_data: IndexVec::new(), guard_context: vec![], push_unsafe_count: 0, unpushed_unsafe: safety, @@ -741,7 +739,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Body::new( self.cfg.basic_blocks, self.source_scopes, - self.source_scope_local_data, self.local_decls, self.canonical_user_type_annotations, self.arg_count, @@ -941,7 +938,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.hir.root_lint_level ); let parent_root = tcx.maybe_lint_level_root_bounded( - self.source_scope_local_data[original_source_scope] + self.source_scopes[original_source_scope] + .local_data .as_ref() .assert_crate_local() .lint_root, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index f8cc5edaae5ef..78e642e4348f7 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -430,7 +430,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // We estimate the true lint roots here to avoid creating a lot of source scopes. let parent_root = tcx.maybe_lint_level_root_bounded( - self.source_scope_local_data[source_scope] + self.source_scopes[source_scope] + .local_data .as_ref() .assert_crate_local() .lint_root, @@ -651,23 +652,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let parent = self.source_scope; debug!("new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}", span, lint_level, safety, - parent, self.source_scope_local_data.get(parent)); - let scope = self.source_scopes.push(SourceScopeData { - span, - parent_scope: Some(parent), - }); + parent, self.source_scopes.get(parent)); let scope_local_data = SourceScopeLocalData { lint_root: if let LintLevel::Explicit(lint_root) = lint_level { lint_root } else { - self.source_scope_local_data[parent].as_ref().assert_crate_local().lint_root + self.source_scopes[parent].local_data.as_ref().assert_crate_local().lint_root }, safety: safety.unwrap_or_else(|| { - self.source_scope_local_data[parent].as_ref().assert_crate_local().safety + self.source_scopes[parent].local_data.as_ref().assert_crate_local().safety }) }; - self.source_scope_local_data.push(ClearCrossCrate::Set(scope_local_data)); - scope + self.source_scopes.push(SourceScopeData { + span, + parent_scope: Some(parent), + local_data: ClearCrossCrate::Set(scope_local_data), + }) } /// Given a span and the current source scope, make a SourceInfo. diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 4b07f217ab3f5..dc62cbefe3442 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -849,7 +849,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { block.terminator().source_info }; - match &body.source_scope_local_data[source_info.scope] { + match &body.source_scopes[source_info.scope].local_data { mir::ClearCrossCrate::Set(data) => Some(data.lint_root), mir::ClearCrossCrate::Clear => None, } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 0128d15c6eaec..b1b7b36323620 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -199,10 +199,8 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) let mut body = Body::new( blocks, IndexVec::from_elem_n( - SourceScopeData { span: span, parent_scope: None }, 1 - ), - IndexVec::from_elem_n( - ClearCrossCrate::Clear, 1 + SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear }, + 1, ), local_decls_for_sig(&sig, span), IndexVec::new(), @@ -367,10 +365,12 @@ impl CloneShimBuilder<'tcx> { Body::new( self.blocks, IndexVec::from_elem_n( - SourceScopeData { span: self.span, parent_scope: None }, 1 - ), - IndexVec::from_elem_n( - ClearCrossCrate::Clear, 1 + SourceScopeData { + span: self.span, + parent_scope: None, + local_data: ClearCrossCrate::Clear, + }, + 1, ), self.local_decls, IndexVec::new(), @@ -829,10 +829,8 @@ fn build_call_shim<'tcx>( let mut body = Body::new( blocks, IndexVec::from_elem_n( - SourceScopeData { span: span, parent_scope: None }, 1 - ), - IndexVec::from_elem_n( - ClearCrossCrate::Clear, 1 + SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear }, + 1, ), local_decls, IndexVec::new(), @@ -917,10 +915,8 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> { let body = Body::new( IndexVec::from_elem_n(start_block, 1), IndexVec::from_elem_n( - SourceScopeData { span: span, parent_scope: None }, 1 - ), - IndexVec::from_elem_n( - ClearCrossCrate::Clear, 1 + SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear }, + 1, ), local_decls, IndexVec::new(), diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index b1c4101dbc759..d12d21aee6abe 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -214,7 +214,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if context.is_borrow() { if util::is_disaligned(self.tcx, self.body, self.param_env, place) { let source_info = self.source_info; - let lint_root = self.body.source_scope_local_data[source_info.scope] + let lint_root = self.body.source_scopes[source_info.scope] + .local_data .as_ref() .assert_crate_local() .lint_root; @@ -343,7 +344,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { fn register_violations(&mut self, violations: &[UnsafetyViolation], unsafe_blocks: &[(hir::HirId, bool)]) { - let safety = self.body.source_scope_local_data[self.source_info.scope] + let safety = self.body.source_scopes[self.source_info.scope] + .local_data .as_ref() .assert_crate_local() .safety; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index c2280fafafb74..dcea886c2b607 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -9,7 +9,7 @@ use rustc::hir::def_id::DefId; use rustc::mir::{ AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue, Local, UnOp, StatementKind, Statement, LocalKind, TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, - BinOp, SourceScope, SourceScopeLocalData, LocalDecl, BasicBlock, RETURN_PLACE, + BinOp, SourceScope, SourceScopeData, LocalDecl, BasicBlock, RETURN_PLACE, }; use rustc::mir::visit::{ Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, @@ -77,8 +77,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { let dummy_body = &Body::new( body.basic_blocks().clone(), - Default::default(), - body.source_scope_local_data.clone(), + body.source_scopes.clone(), body.local_decls.clone(), Default::default(), body.arg_count, @@ -253,7 +252,7 @@ struct ConstPropagator<'mir, 'tcx> { param_env: ParamEnv<'tcx>, // FIXME(eddyb) avoid cloning these two fields more than once, // by accessing them through `ecx` instead. - source_scope_local_data: IndexVec>, + source_scopes: IndexVec, local_decls: IndexVec>, ret: Option>, } @@ -324,7 +323,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { can_const_prop, // FIXME(eddyb) avoid cloning these two fields more than once, // by accessing them through `ecx` instead. - source_scope_local_data: body.source_scope_local_data.clone(), + source_scopes: body.source_scopes.clone(), //FIXME(wesleywiser) we can't steal this because `Visitor::super_visit_body()` needs it local_decls: body.local_decls.clone(), ret: ret.map(Into::into), @@ -361,9 +360,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { { self.ecx.tcx.span = source_info.span; // FIXME(eddyb) move this to the `Panic(_)` error case, so that - // `f(self)` is always called, and that the only difference when - // `source_scope_local_data` is missing, is that the lint isn't emitted. - let lint_root = match &self.source_scope_local_data[source_info.scope] { + // `f(self)` is always called, and that the only difference when the + // scope's `local_data` is missing, is that the lint isn't emitted. + let lint_root = match &self.source_scopes[source_info.scope].local_data { ClearCrossCrate::Set(data) => data.lint_root, ClearCrossCrate::Clear => return None, }; @@ -488,7 +487,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let right_size = r.layout.size; let r_bits = r.to_scalar().and_then(|r| r.to_bits(right_size)); if r_bits.ok().map_or(false, |b| b >= left_bits as u128) { - let lint_root = match &self.source_scope_local_data[source_info.scope] { + let lint_root = match &self.source_scopes[source_info.scope].local_data { ClearCrossCrate::Set(data) => data.lint_root, ClearCrossCrate::Clear => return None, }; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 70a0fb2d1035c..ebfadd0cfd3ed 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -388,8 +388,7 @@ impl Inliner<'tcx> { let mut local_map = IndexVec::with_capacity(callee_body.local_decls.len()); let mut scope_map = IndexVec::with_capacity(callee_body.source_scopes.len()); - for (callee_idx, scope) in callee_body.source_scopes.iter_enumerated() { - let mut scope = scope.clone(); + for mut scope in callee_body.source_scopes.iter().cloned() { if scope.parent_scope.is_none() { scope.parent_scope = Some(callsite.location.scope); // FIXME(eddyb) is this really needed? @@ -404,9 +403,6 @@ impl Inliner<'tcx> { let idx = caller_body.source_scopes.push(scope); scope_map.push(idx); - - let local_data = callee_body.source_scope_local_data[callee_idx].clone(); - assert_eq!(idx, caller_body.source_scope_local_data.push(local_data)); } for loc in callee_body.vars_and_temps_iter() { diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 2c3aec103a58b..ca2fd8634e6df 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -1097,7 +1097,6 @@ pub fn promote_candidates<'tcx>( // FIXME: maybe try to filter this to avoid blowing up // memory usage? body.source_scopes.clone(), - body.source_scope_local_data.clone(), initial_locals, IndexVec::new(), 0,