Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 6bc5eaf

Browse files
committed
rustc_mir: track inlined callees in SourceScopeData.
1 parent 708fc0b commit 6bc5eaf

File tree

41 files changed

+124
-74
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+124
-74
lines changed

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub struct Body<'tcx> {
161161

162162
/// A list of source scopes; these are referenced by statements
163163
/// and used for debuginfo. Indexed by a `SourceScope`.
164-
pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
164+
pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
165165

166166
/// The yield type of the function, if it is a generator.
167167
pub yield_ty: Option<Ty<'tcx>>,
@@ -244,7 +244,7 @@ impl<'tcx> Body<'tcx> {
244244
pub fn new(
245245
source: MirSource<'tcx>,
246246
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
247-
source_scopes: IndexVec<SourceScope, SourceScopeData>,
247+
source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
248248
local_decls: LocalDecls<'tcx>,
249249
user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
250250
arg_count: usize,
@@ -1868,11 +1868,16 @@ rustc_index::newtype_index! {
18681868
}
18691869
}
18701870

1871-
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
1872-
pub struct SourceScopeData {
1871+
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1872+
pub struct SourceScopeData<'tcx> {
18731873
pub span: Span,
18741874
pub parent_scope: Option<SourceScope>,
18751875

1876+
/// Whether this scope is the root of a scope tree of another body,
1877+
/// inlined into this body by the MIR inliner.
1878+
/// `ty::Instance` is the callee, and the `Span` is the call site.
1879+
pub inlined: Option<(ty::Instance<'tcx>, Span)>,
1880+
18761881
/// Crate-local information for this source scope, that can't (and
18771882
/// needn't) be tracked across crates.
18781883
pub local_data: ClearCrossCrate<SourceScopeLocalData>,

compiler/rustc_middle/src/mir/type_foldable.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ CloneTypeFoldableAndLiftImpls! {
1010
FakeReadCause,
1111
RetagKind,
1212
SourceScope,
13-
SourceScopeData,
1413
SourceScopeLocalData,
1514
UserTypeAnnotationIndex,
1615
}

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ macro_rules! make_mir_visitor {
8585
}
8686

8787
fn visit_source_scope_data(&mut self,
88-
scope_data: & $($mutability)? SourceScopeData) {
88+
scope_data: & $($mutability)? SourceScopeData<'tcx>) {
8989
self.super_source_scope_data(scope_data);
9090
}
9191

@@ -317,17 +317,46 @@ macro_rules! make_mir_visitor {
317317
}
318318
}
319319

320-
fn super_source_scope_data(&mut self, scope_data: & $($mutability)? SourceScopeData) {
320+
fn super_source_scope_data(
321+
&mut self,
322+
scope_data: & $($mutability)? SourceScopeData<'tcx>,
323+
) {
321324
let SourceScopeData {
322325
span,
323326
parent_scope,
327+
inlined,
324328
local_data: _,
325329
} = scope_data;
326330

327331
self.visit_span(span);
328332
if let Some(parent_scope) = parent_scope {
329333
self.visit_source_scope(parent_scope);
330334
}
335+
if let Some((callee, callsite_span)) = inlined {
336+
let location = START_BLOCK.start_location();
337+
338+
self.visit_span(callsite_span);
339+
340+
let ty::Instance { def: callee_def, substs: callee_substs } = callee;
341+
match callee_def {
342+
ty::InstanceDef::Item(_def_id) => {}
343+
344+
ty::InstanceDef::Intrinsic(_def_id) |
345+
ty::InstanceDef::VtableShim(_def_id) |
346+
ty::InstanceDef::ReifyShim(_def_id) |
347+
ty::InstanceDef::Virtual(_def_id, _) |
348+
ty::InstanceDef::ClosureOnceShim { call_once: _def_id } |
349+
ty::InstanceDef::DropGlue(_def_id, None) => {}
350+
351+
ty::InstanceDef::FnPtrShim(_def_id, ty) |
352+
ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
353+
ty::InstanceDef::CloneShim(_def_id, ty) => {
354+
// FIXME(eddyb) use a better `TyContext` here.
355+
self.visit_ty(ty, TyContext::Location(location));
356+
}
357+
}
358+
self.visit_substs(callee_substs, location);
359+
}
331360
}
332361

333362
fn super_statement(&mut self,

compiler/rustc_mir/src/shim.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,12 @@ fn new_body<'tcx>(
212212
source,
213213
basic_blocks,
214214
IndexVec::from_elem_n(
215-
SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear },
215+
SourceScopeData {
216+
span,
217+
parent_scope: None,
218+
inlined: None,
219+
local_data: ClearCrossCrate::Clear,
220+
},
216221
1,
217222
),
218223
local_decls,

compiler/rustc_mir/src/transform/const_prop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ struct ConstPropagator<'mir, 'tcx> {
313313
param_env: ParamEnv<'tcx>,
314314
// FIXME(eddyb) avoid cloning these two fields more than once,
315315
// by accessing them through `ecx` instead.
316-
source_scopes: IndexVec<SourceScope, SourceScopeData>,
316+
source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
317317
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
318318
// Because we have `MutVisitor` we can't obtain the `SourceInfo` from a `Location`. So we store
319319
// the last known `SourceInfo` here and just keep revisiting it.

compiler/rustc_mir/src/transform/inline.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl Inliner<'tcx> {
112112

113113
let callee_body = if let Some(callee_def_id) = callsite.callee.def_id().as_local() {
114114
let callee_hir_id = self.tcx.hir().local_def_id_to_hir_id(callee_def_id);
115-
// Avoid a cycle here by only using `optimized_mir` only if we have
115+
// Avoid a cycle here by only using `instance_mir` only if we have
116116
// a lower `HirId` than the callee. This ensures that the callee will
117117
// not inline us. This trick only works without incremental compilation.
118118
// So don't do it if that is enabled. Also avoid inlining into generators,
@@ -442,15 +442,11 @@ impl Inliner<'tcx> {
442442
for mut scope in callee_body.source_scopes.iter().cloned() {
443443
if scope.parent_scope.is_none() {
444444
scope.parent_scope = Some(callsite.source_info.scope);
445-
// FIXME(eddyb) is this really needed?
446-
// (also note that it's always overwritten below)
447-
scope.span = callee_body.span;
448-
}
449445

450-
// FIXME(eddyb) this doesn't seem right at all.
451-
// The inlined source scopes should probably be annotated as
452-
// such, but also contain all of the original information.
453-
scope.span = callsite.source_info.span;
446+
// Mark the outermost callee scope as an inlined one.
447+
assert_eq!(scope.inlined, None);
448+
scope.inlined = Some((callsite.callee, callsite.source_info.span));
449+
}
454450

455451
let idx = caller_body.source_scopes.push(scope);
456452
scope_map.push(idx);

compiler/rustc_mir/src/util/pretty.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,8 +548,23 @@ fn write_scope_tree(
548548
};
549549

550550
for &child in children {
551-
assert_eq!(body.source_scopes[child].parent_scope, Some(parent));
552-
writeln!(w, "{0:1$}scope {2} {{", "", indent, child.index())?;
551+
let child_data = &body.source_scopes[child];
552+
assert_eq!(child_data.parent_scope, Some(parent));
553+
554+
if let Some((callee, callsite_span)) = child_data.inlined {
555+
let indented_header =
556+
format!("{0:1$}scope {2} (inlined {3}) {{", "", indent, child.index(), callee);
557+
writeln!(
558+
w,
559+
"{0:1$} // at {2}",
560+
indented_header,
561+
ALIGN,
562+
tcx.sess.source_map().span_to_string(callsite_span),
563+
)?;
564+
} else {
565+
writeln!(w, "{0:1$}scope {2} {{", "", indent, child.index())?;
566+
}
567+
553568
write_scope_tree(tcx, body, scope_tree, w, child, depth + 1)?;
554569
writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?;
555570
}

compiler/rustc_mir_build/src/build/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ struct Builder<'a, 'tcx> {
334334

335335
/// The vector of all scopes that we have created thus far;
336336
/// we track this for debuginfo later.
337-
source_scopes: IndexVec<SourceScope, SourceScopeData>,
337+
source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
338338
source_scope: SourceScope,
339339

340340
/// The guard-context: each time we build the guard expression for

compiler/rustc_mir_build/src/build/scope.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
705705
self.source_scopes.push(SourceScopeData {
706706
span,
707707
parent_scope: Some(parent),
708+
inlined: None,
708709
local_data: ClearCrossCrate::Set(scope_local_data),
709710
})
710711
}

src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
scope 3 {
1919
- debug z => _3; // in scope 3 at $DIR/cycle.rs:11:9: 11:10
2020
+ debug z => _4; // in scope 3 at $DIR/cycle.rs:11:9: 11:10
21-
scope 4 {
21+
scope 4 (inlined std::mem::drop::<i32>) { // at $DIR/cycle.rs:14:5: 14:12
2222
debug _x => _6; // in scope 4 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
2323
}
2424
}

0 commit comments

Comments
 (0)