Skip to content

Commit b3d835f

Browse files
authored
Rollup merge of rust-lang#66789 - eddyb:mir-source-scope-local-data, r=oli-obk
rustc: move mir::SourceScopeLocalData to a field of SourceScopeData. By having one `ClearCrossCrate<SourceScopeLocalData>` for each scope, as opposed to a single `ClearCrossCrate` for all the `SourceScopeLocalData`s, we can represent the fact that some scopes have `SourceScopeLocalData` associated with them, and some don't. This is useful when doing MIR inlining across crates, because the `ClearCrossCrate` will be `Clear` for the cross-crate MIR scopes and `Set` for the local ones. Also see rust-lang#66203 (comment) for some context around this approach. Fixes rust-lang#51314.
2 parents 535a09a + 3aead85 commit b3d835f

File tree

11 files changed

+110
-122
lines changed

11 files changed

+110
-122
lines changed

src/librustc/mir/mod.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,6 @@ pub struct Body<'tcx> {
104104
/// and used for debuginfo. Indexed by a `SourceScope`.
105105
pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
106106

107-
/// Crate-local information for each source scope, that can't (and
108-
/// needn't) be tracked across crates.
109-
pub source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
110-
111107
/// The yield type of the function, if it is a generator.
112108
pub yield_ty: Option<Ty<'tcx>>,
113109

@@ -163,7 +159,6 @@ impl<'tcx> Body<'tcx> {
163159
pub fn new(
164160
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
165161
source_scopes: IndexVec<SourceScope, SourceScopeData>,
166-
source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
167162
local_decls: LocalDecls<'tcx>,
168163
user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
169164
arg_count: usize,
@@ -183,7 +178,6 @@ impl<'tcx> Body<'tcx> {
183178
phase: MirPhase::Build,
184179
basic_blocks,
185180
source_scopes,
186-
source_scope_local_data,
187181
yield_ty: None,
188182
generator_drop: None,
189183
generator_layout: None,
@@ -429,6 +423,13 @@ pub enum ClearCrossCrate<T> {
429423
}
430424

431425
impl<T> ClearCrossCrate<T> {
426+
pub fn as_ref(&'a self) -> ClearCrossCrate<&'a T> {
427+
match self {
428+
ClearCrossCrate::Clear => ClearCrossCrate::Clear,
429+
ClearCrossCrate::Set(v) => ClearCrossCrate::Set(v),
430+
}
431+
}
432+
432433
pub fn assert_crate_local(self) -> T {
433434
match self {
434435
ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
@@ -2021,6 +2022,10 @@ rustc_index::newtype_index! {
20212022
pub struct SourceScopeData {
20222023
pub span: Span,
20232024
pub parent_scope: Option<SourceScope>,
2025+
2026+
/// Crate-local information for this source scope, that can't (and
2027+
/// needn't) be tracked across crates.
2028+
pub local_data: ClearCrossCrate<SourceScopeLocalData>,
20242029
}
20252030

20262031
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]

src/librustc/mir/visit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ macro_rules! make_mir_visitor {
317317
let SourceScopeData {
318318
span,
319319
parent_scope,
320+
local_data: _,
320321
} = scope_data;
321322

322323
self.visit_span(span);

src/librustc_mir/borrow_check/mod.rs

+34-33
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,10 @@ fn do_mir_borrowck<'a, 'tcx>(
300300
let mut initial_diag =
301301
mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow);
302302

303-
let lint_root = if let ClearCrossCrate::Set(ref vsi) = mbcx.body.source_scope_local_data {
304-
let scope = mbcx.body.source_info(location).scope;
305-
vsi[scope].lint_root
306-
} else {
307-
id
303+
let scope = mbcx.body.source_info(location).scope;
304+
let lint_root = match &mbcx.body.source_scopes[scope].local_data {
305+
ClearCrossCrate::Set(data) => data.lint_root,
306+
_ => id,
308307
};
309308

310309
// Span and message don't matter; we overwrite them below anyway
@@ -338,38 +337,40 @@ fn do_mir_borrowck<'a, 'tcx>(
338337
debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
339338
let used_mut = mbcx.used_mut;
340339
for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
341-
if let ClearCrossCrate::Set(ref vsi) = mbcx.body.source_scope_local_data {
342-
let local_decl = &mbcx.body.local_decls[local];
343-
344-
// Skip over locals that begin with an underscore or have no name
345-
match mbcx.local_names[local] {
346-
Some(name) => if name.as_str().starts_with("_") {
347-
continue;
348-
},
349-
None => continue,
350-
}
340+
let local_decl = &mbcx.body.local_decls[local];
341+
let lint_root = match &mbcx.body.source_scopes[local_decl.source_info.scope].local_data {
342+
ClearCrossCrate::Set(data) => data.lint_root,
343+
_ => continue,
344+
};
351345

352-
let span = local_decl.source_info.span;
353-
if span.desugaring_kind().is_some() {
354-
// If the `mut` arises as part of a desugaring, we should ignore it.
346+
// Skip over locals that begin with an underscore or have no name
347+
match mbcx.local_names[local] {
348+
Some(name) => if name.as_str().starts_with("_") {
355349
continue;
356-
}
350+
},
351+
None => continue,
352+
}
357353

358-
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
359-
tcx.struct_span_lint_hir(
360-
UNUSED_MUT,
361-
vsi[local_decl.source_info.scope].lint_root,
362-
span,
363-
"variable does not need to be mutable",
364-
)
365-
.span_suggestion_short(
366-
mut_span,
367-
"remove this `mut`",
368-
String::new(),
369-
Applicability::MachineApplicable,
370-
)
371-
.emit();
354+
let span = local_decl.source_info.span;
355+
if span.desugaring_kind().is_some() {
356+
// If the `mut` arises as part of a desugaring, we should ignore it.
357+
continue;
372358
}
359+
360+
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
361+
tcx.struct_span_lint_hir(
362+
UNUSED_MUT,
363+
lint_root,
364+
span,
365+
"variable does not need to be mutable",
366+
)
367+
.span_suggestion_short(
368+
mut_span,
369+
"remove this `mut`",
370+
String::new(),
371+
Applicability::MachineApplicable,
372+
)
373+
.emit();
373374
}
374375

375376
// Buffer any move errors that we collected and de-duplicated.

src/librustc_mir/build/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,6 @@ struct Builder<'a, 'tcx> {
309309
/// The vector of all scopes that we have created thus far;
310310
/// we track this for debuginfo later.
311311
source_scopes: IndexVec<SourceScope, SourceScopeData>,
312-
source_scope_local_data: IndexVec<SourceScope, SourceScopeLocalData>,
313312
source_scope: SourceScope,
314313

315314
/// The guard-context: each time we build the guard expression for
@@ -704,7 +703,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
704703
block_context: BlockContext::new(),
705704
source_scopes: IndexVec::new(),
706705
source_scope: OUTERMOST_SOURCE_SCOPE,
707-
source_scope_local_data: IndexVec::new(),
708706
guard_context: vec![],
709707
push_unsafe_count: 0,
710708
unpushed_unsafe: safety,
@@ -741,7 +739,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
741739
Body::new(
742740
self.cfg.basic_blocks,
743741
self.source_scopes,
744-
ClearCrossCrate::Set(self.source_scope_local_data),
745742
self.local_decls,
746743
self.canonical_user_type_annotations,
747744
self.arg_count,
@@ -941,7 +938,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
941938
self.hir.root_lint_level
942939
);
943940
let parent_root = tcx.maybe_lint_level_root_bounded(
944-
self.source_scope_local_data[original_source_scope].lint_root,
941+
self.source_scopes[original_source_scope]
942+
.local_data
943+
.as_ref()
944+
.assert_crate_local()
945+
.lint_root,
945946
self.hir.root_lint_level,
946947
);
947948
if current_root != parent_root {

src/librustc_mir/build/scope.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
430430
// We estimate the true lint roots here to avoid creating a lot of source scopes.
431431

432432
let parent_root = tcx.maybe_lint_level_root_bounded(
433-
self.source_scope_local_data[source_scope].lint_root,
433+
self.source_scopes[source_scope]
434+
.local_data
435+
.as_ref()
436+
.assert_crate_local()
437+
.lint_root,
434438
self.hir.root_lint_level,
435439
);
436440
let current_root = tcx.maybe_lint_level_root_bounded(
@@ -648,23 +652,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
648652
let parent = self.source_scope;
649653
debug!("new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}",
650654
span, lint_level, safety,
651-
parent, self.source_scope_local_data.get(parent));
652-
let scope = self.source_scopes.push(SourceScopeData {
653-
span,
654-
parent_scope: Some(parent),
655-
});
655+
parent, self.source_scopes.get(parent));
656656
let scope_local_data = SourceScopeLocalData {
657657
lint_root: if let LintLevel::Explicit(lint_root) = lint_level {
658658
lint_root
659659
} else {
660-
self.source_scope_local_data[parent].lint_root
660+
self.source_scopes[parent].local_data.as_ref().assert_crate_local().lint_root
661661
},
662662
safety: safety.unwrap_or_else(|| {
663-
self.source_scope_local_data[parent].safety
663+
self.source_scopes[parent].local_data.as_ref().assert_crate_local().safety
664664
})
665665
};
666-
self.source_scope_local_data.push(scope_local_data);
667-
scope
666+
self.source_scopes.push(SourceScopeData {
667+
span,
668+
parent_scope: Some(parent),
669+
local_data: ClearCrossCrate::Set(scope_local_data),
670+
})
668671
}
669672

670673
/// Given a span and the current source scope, make a SourceInfo.

src/librustc_mir/interpret/eval_context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -849,8 +849,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
849849
} else {
850850
block.terminator().source_info
851851
};
852-
match body.source_scope_local_data {
853-
mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root),
852+
match &body.source_scopes[source_info.scope].local_data {
853+
mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
854854
mir::ClearCrossCrate::Clear => None,
855855
}
856856
});

src/librustc_mir/shim.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
199199
let mut body = Body::new(
200200
blocks,
201201
IndexVec::from_elem_n(
202-
SourceScopeData { span: span, parent_scope: None }, 1
202+
SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear },
203+
1,
203204
),
204-
ClearCrossCrate::Clear,
205205
local_decls_for_sig(&sig, span),
206206
IndexVec::new(),
207207
sig.inputs().len(),
@@ -365,9 +365,13 @@ impl CloneShimBuilder<'tcx> {
365365
Body::new(
366366
self.blocks,
367367
IndexVec::from_elem_n(
368-
SourceScopeData { span: self.span, parent_scope: None }, 1
368+
SourceScopeData {
369+
span: self.span,
370+
parent_scope: None,
371+
local_data: ClearCrossCrate::Clear,
372+
},
373+
1,
369374
),
370-
ClearCrossCrate::Clear,
371375
self.local_decls,
372376
IndexVec::new(),
373377
self.sig.inputs().len(),
@@ -825,9 +829,9 @@ fn build_call_shim<'tcx>(
825829
let mut body = Body::new(
826830
blocks,
827831
IndexVec::from_elem_n(
828-
SourceScopeData { span: span, parent_scope: None }, 1
832+
SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear },
833+
1,
829834
),
830-
ClearCrossCrate::Clear,
831835
local_decls,
832836
IndexVec::new(),
833837
sig.inputs().len(),
@@ -911,9 +915,9 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> {
911915
let body = Body::new(
912916
IndexVec::from_elem_n(start_block, 1),
913917
IndexVec::from_elem_n(
914-
SourceScopeData { span: span, parent_scope: None }, 1
918+
SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear },
919+
1,
915920
),
916-
ClearCrossCrate::Clear,
917921
local_decls,
918922
IndexVec::new(),
919923
sig.inputs().len(),

src/librustc_mir/transform/check_unsafety.rs

+11-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
use rustc_data_structures::fx::FxHashSet;
2-
use rustc_index::vec::IndexVec;
3-
use rustc_data_structures::sync::Lrc;
42

53
use rustc::ty::query::Providers;
64
use rustc::ty::{self, TyCtxt};
@@ -24,7 +22,6 @@ pub struct UnsafetyChecker<'a, 'tcx> {
2422
body: &'a Body<'tcx>,
2523
const_context: bool,
2624
min_const_fn: bool,
27-
source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
2825
violations: Vec<UnsafetyViolation>,
2926
source_info: SourceInfo,
3027
tcx: TyCtxt<'tcx>,
@@ -39,7 +36,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
3936
const_context: bool,
4037
min_const_fn: bool,
4138
body: &'a Body<'tcx>,
42-
source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
4339
tcx: TyCtxt<'tcx>,
4440
param_env: ty::ParamEnv<'tcx>,
4541
) -> Self {
@@ -51,7 +47,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
5147
body,
5248
const_context,
5349
min_const_fn,
54-
source_scope_local_data,
5550
violations: vec![],
5651
source_info: SourceInfo {
5752
span: body.span,
@@ -219,8 +214,11 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
219214
if context.is_borrow() {
220215
if util::is_disaligned(self.tcx, self.body, self.param_env, place) {
221216
let source_info = self.source_info;
222-
let lint_root =
223-
self.source_scope_local_data[source_info.scope].lint_root;
217+
let lint_root = self.body.source_scopes[source_info.scope]
218+
.local_data
219+
.as_ref()
220+
.assert_crate_local()
221+
.lint_root;
224222
self.register_violations(&[UnsafetyViolation {
225223
source_info,
226224
description: Symbol::intern("borrow of packed field"),
@@ -346,7 +344,11 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
346344
fn register_violations(&mut self,
347345
violations: &[UnsafetyViolation],
348346
unsafe_blocks: &[(hir::HirId, bool)]) {
349-
let safety = self.source_scope_local_data[self.source_info.scope].safety;
347+
let safety = self.body.source_scopes[self.source_info.scope]
348+
.local_data
349+
.as_ref()
350+
.assert_crate_local()
351+
.safety;
350352
let within_unsafe = match safety {
351353
// `unsafe` blocks are required in safe code
352354
Safety::Safe => {
@@ -516,17 +518,6 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult
516518
// `mir_built` force this.
517519
let body = &tcx.mir_built(def_id).borrow();
518520

519-
let source_scope_local_data = match body.source_scope_local_data {
520-
ClearCrossCrate::Set(ref data) => data,
521-
ClearCrossCrate::Clear => {
522-
debug!("unsafety_violations: {:?} - remote, skipping", def_id);
523-
return UnsafetyCheckResult {
524-
violations: Lrc::new([]),
525-
unsafe_blocks: Lrc::new([])
526-
}
527-
}
528-
};
529-
530521
let param_env = tcx.param_env(def_id);
531522

532523
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -536,9 +527,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult
536527
hir::BodyOwnerKind::Const |
537528
hir::BodyOwnerKind::Static(_) => (true, false),
538529
};
539-
let mut checker = UnsafetyChecker::new(
540-
const_context, min_const_fn,
541-
body, source_scope_local_data, tcx, param_env);
530+
let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env);
542531
checker.visit_body(body);
543532

544533
check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks);

0 commit comments

Comments
 (0)