Skip to content

Commit fd09fad

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 a279ebb + a9976d8 commit fd09fad

File tree

11 files changed

+102
-129
lines changed

11 files changed

+102
-129
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

@@ -167,7 +163,6 @@ impl<'tcx> Body<'tcx> {
167163
pub fn new(
168164
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
169165
source_scopes: IndexVec<SourceScope, SourceScopeData>,
170-
source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
171166
local_decls: LocalDecls<'tcx>,
172167
user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
173168
arg_count: usize,
@@ -188,7 +183,6 @@ impl<'tcx> Body<'tcx> {
188183
phase: MirPhase::Build,
189184
basic_blocks,
190185
source_scopes,
191-
source_scope_local_data,
192186
yield_ty: None,
193187
generator_drop: None,
194188
generator_layout: None,
@@ -435,6 +429,13 @@ pub enum ClearCrossCrate<T> {
435429
}
436430

437431
impl<T> ClearCrossCrate<T> {
432+
pub fn as_ref(&'a self) -> ClearCrossCrate<&'a T> {
433+
match self {
434+
ClearCrossCrate::Clear => ClearCrossCrate::Clear,
435+
ClearCrossCrate::Set(v) => ClearCrossCrate::Set(v),
436+
}
437+
}
438+
438439
pub fn assert_crate_local(self) -> T {
439440
match self {
440441
ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
@@ -2027,6 +2028,10 @@ rustc_index::newtype_index! {
20272028
pub struct SourceScopeData {
20282029
pub span: Span,
20292030
pub parent_scope: Option<SourceScope>,
2031+
2032+
/// Crate-local information for this source scope, that can't (and
2033+
/// needn't) be tracked across crates.
2034+
pub local_data: ClearCrossCrate<SourceScopeLocalData>,
20302035
}
20312036

20322037
#[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,
@@ -942,7 +939,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
942939
self.hir.root_lint_level
943940
);
944941
let parent_root = tcx.maybe_lint_level_root_bounded(
945-
self.source_scope_local_data[original_source_scope].lint_root,
942+
self.source_scopes[original_source_scope]
943+
.local_data
944+
.as_ref()
945+
.assert_crate_local()
946+
.lint_root,
946947
self.hir.root_lint_level,
947948
);
948949
if current_root != parent_root {

src/librustc_mir/build/scope.rs

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

438438
let parent_root = tcx.maybe_lint_level_root_bounded(
439-
self.source_scope_local_data[source_scope].lint_root,
439+
self.source_scopes[source_scope]
440+
.local_data
441+
.as_ref()
442+
.assert_crate_local()
443+
.lint_root,
440444
self.hir.root_lint_level,
441445
);
442446
let current_root = tcx.maybe_lint_level_root_bounded(
@@ -654,23 +658,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
654658
let parent = self.source_scope;
655659
debug!("new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}",
656660
span, lint_level, safety,
657-
parent, self.source_scope_local_data.get(parent));
658-
let scope = self.source_scopes.push(SourceScopeData {
659-
span,
660-
parent_scope: Some(parent),
661-
});
661+
parent, self.source_scopes.get(parent));
662662
let scope_local_data = SourceScopeLocalData {
663663
lint_root: if let LintLevel::Explicit(lint_root) = lint_level {
664664
lint_root
665665
} else {
666-
self.source_scope_local_data[parent].lint_root
666+
self.source_scopes[parent].local_data.as_ref().assert_crate_local().lint_root
667667
},
668668
safety: safety.unwrap_or_else(|| {
669-
self.source_scope_local_data[parent].safety
669+
self.source_scopes[parent].local_data.as_ref().assert_crate_local().safety
670670
})
671671
};
672-
self.source_scope_local_data.push(scope_local_data);
673-
scope
672+
self.source_scopes.push(SourceScopeData {
673+
span,
674+
parent_scope: Some(parent),
675+
local_data: ClearCrossCrate::Set(scope_local_data),
676+
})
674677
}
675678

676679
/// 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

+4-15
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,6 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
198198

199199
let mut body = new_body(
200200
blocks,
201-
IndexVec::from_elem_n(
202-
SourceScopeData { span, parent_scope: None }, 1
203-
),
204201
local_decls_for_sig(&sig, span),
205202
sig.inputs().len(),
206203
span);
@@ -244,15 +241,16 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
244241

245242
fn new_body<'tcx>(
246243
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
247-
source_scopes: IndexVec<SourceScope, SourceScopeData>,
248244
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
249245
arg_count: usize,
250246
span: Span,
251247
) -> Body<'tcx> {
252248
Body::new(
253249
basic_blocks,
254-
source_scopes,
255-
ClearCrossCrate::Clear,
250+
IndexVec::from_elem_n(
251+
SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear },
252+
1,
253+
),
256254
local_decls,
257255
IndexVec::new(),
258256
arg_count,
@@ -380,9 +378,6 @@ impl CloneShimBuilder<'tcx> {
380378
fn into_mir(self) -> Body<'tcx> {
381379
new_body(
382380
self.blocks,
383-
IndexVec::from_elem_n(
384-
SourceScopeData { span: self.span, parent_scope: None }, 1
385-
),
386381
self.local_decls,
387382
self.sig.inputs().len(),
388383
self.span,
@@ -836,9 +831,6 @@ fn build_call_shim<'tcx>(
836831

837832
let mut body = new_body(
838833
blocks,
839-
IndexVec::from_elem_n(
840-
SourceScopeData { span, parent_scope: None }, 1
841-
),
842834
local_decls,
843835
sig.inputs().len(),
844836
span,
@@ -919,9 +911,6 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> {
919911

920912
let body = new_body(
921913
IndexVec::from_elem_n(start_block, 1),
922-
IndexVec::from_elem_n(
923-
SourceScopeData { span, parent_scope: None }, 1
924-
),
925914
local_decls,
926915
sig.inputs().len(),
927916
span,

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)