Skip to content

Commit 6a73ad5

Browse files
committed
Add VarDebugInfo to Stable MIR
1 parent 48d8100 commit 6a73ad5

File tree

3 files changed

+116
-5
lines changed

3 files changed

+116
-5
lines changed

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt, Variance};
1818
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
1919
use rustc_target::abi::FieldIdx;
2020
use stable_mir::mir::mono::InstanceDef;
21-
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
21+
use stable_mir::mir::{
22+
Body, ConstOperand, CopyNonOverlapping, Statement, UserTypeProjection, VarDebugInfoFragment,
23+
VariantIdx,
24+
};
2225
use stable_mir::ty::{
2326
Const, ConstId, ConstantKind, FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy,
2427
Span, TyKind, UintTy,
@@ -313,10 +316,50 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
313316
})
314317
.collect(),
315318
self.arg_count,
319+
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
316320
)
317321
}
318322
}
319323

324+
impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
325+
type T = stable_mir::mir::VarDebugInfo;
326+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
327+
stable_mir::mir::VarDebugInfo {
328+
name: self.name.to_string(),
329+
source_info: stable_mir::mir::SourceInfo {
330+
span: self.source_info.span.stable(tables),
331+
scope: self.source_info.scope.into(),
332+
},
333+
composite: {
334+
if let Some(composite) = &self.composite {
335+
Some(VarDebugInfoFragment {
336+
ty: composite.ty.stable(tables),
337+
projection: composite.projection.iter().map(|e| e.stable(tables)).collect(),
338+
})
339+
} else {
340+
None
341+
}
342+
},
343+
value: {
344+
match self.value {
345+
mir::VarDebugInfoContents::Place(place) => {
346+
stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables))
347+
}
348+
mir::VarDebugInfoContents::Const(const_operand) => {
349+
let op = ConstOperand {
350+
span: const_operand.span.stable(tables),
351+
user_ty: const_operand.user_ty.map(|index| index.as_usize()),
352+
const_: const_operand.const_.stable(tables),
353+
};
354+
stable_mir::mir::VarDebugInfoContents::Const(op)
355+
}
356+
}
357+
},
358+
argument_index: self.argument_index,
359+
}
360+
}
361+
}
362+
320363
impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
321364
type T = stable_mir::mir::Statement;
322365
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {

compiler/stable_mir/src/mir/body.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::ty::{AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, Ty};
2-
use crate::Opaque;
32
use crate::Span;
3+
use crate::{Opaque, Symbol};
44

55
/// The SMIR representation of a single function.
66
#[derive(Clone, Debug)]
@@ -16,21 +16,29 @@ pub struct Body {
1616

1717
// The number of arguments this function takes.
1818
pub(super) arg_count: usize,
19+
20+
// Debug information pertaining to user variables, including captures.
21+
pub(super) var_debug_info: Vec<VarDebugInfo>,
1922
}
2023

2124
impl Body {
2225
/// Constructs a `Body`.
2326
///
2427
/// A constructor is required to build a `Body` from outside the crate
2528
/// because the `arg_count` and `locals` fields are private.
26-
pub fn new(blocks: Vec<BasicBlock>, locals: LocalDecls, arg_count: usize) -> Self {
29+
pub fn new(
30+
blocks: Vec<BasicBlock>,
31+
locals: LocalDecls,
32+
arg_count: usize,
33+
var_debug_info: Vec<VarDebugInfo>,
34+
) -> Self {
2735
// If locals doesn't contain enough entries, it can lead to panics in
2836
// `ret_local`, `arg_locals`, and `inner_locals`.
2937
assert!(
3038
locals.len() > arg_count,
3139
"A Body must contain at least a local for the return value and each of the function's arguments"
3240
);
33-
Self { blocks, locals, arg_count }
41+
Self { blocks, locals, arg_count, var_debug_info }
3442
}
3543

3644
/// Return local that holds this function's return value.
@@ -401,6 +409,42 @@ pub struct Place {
401409
pub projection: Vec<ProjectionElem>,
402410
}
403411

412+
#[derive(Clone, Debug, Eq, PartialEq)]
413+
pub struct VarDebugInfo {
414+
pub name: Symbol,
415+
pub source_info: SourceInfo,
416+
pub composite: Option<VarDebugInfoFragment>,
417+
pub value: VarDebugInfoContents,
418+
pub argument_index: Option<u16>,
419+
}
420+
421+
pub type SourceScope = u32;
422+
423+
#[derive(Clone, Debug, Eq, PartialEq)]
424+
pub struct SourceInfo {
425+
pub span: Span,
426+
pub scope: SourceScope,
427+
}
428+
429+
#[derive(Clone, Debug, Eq, PartialEq)]
430+
pub struct VarDebugInfoFragment {
431+
pub ty: Ty,
432+
pub projection: Vec<ProjectionElem>,
433+
}
434+
435+
#[derive(Clone, Debug, Eq, PartialEq)]
436+
pub enum VarDebugInfoContents {
437+
Place(Place),
438+
Const(ConstOperand),
439+
}
440+
441+
#[derive(Clone, Debug, Eq, PartialEq)]
442+
pub struct ConstOperand {
443+
pub span: Span,
444+
pub user_ty: Option<UserTypeAnnotationIndex>,
445+
pub const_: Const,
446+
}
447+
404448
// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
405449
// is so it can be used for both Places (for which the projection elements are of type
406450
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements

compiler/stable_mir/src/mir/visit.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,12 @@ pub trait MirVisitor {
128128
self.super_assert_msg(msg, location)
129129
}
130130

131+
fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) {
132+
self.super_var_debug_info(var_debug_info);
133+
}
134+
131135
fn super_body(&mut self, body: &Body) {
132-
let Body { blocks, locals: _, arg_count } = body;
136+
let Body { blocks, locals: _, arg_count, var_debug_info } = body;
133137

134138
for bb in blocks {
135139
self.visit_basic_block(bb);
@@ -145,6 +149,10 @@ pub trait MirVisitor {
145149
for (idx, arg) in body.arg_locals().iter().enumerate() {
146150
self.visit_local_decl(idx + local_start, arg)
147151
}
152+
153+
for info in var_debug_info.iter() {
154+
self.visit_var_debug_info(info);
155+
}
148156
}
149157

150158
fn super_basic_block(&mut self, bb: &BasicBlock) {
@@ -382,6 +390,22 @@ pub trait MirVisitor {
382390
let _ = args;
383391
}
384392

393+
fn super_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) {
394+
self.visit_span(&var_debug_info.source_info.span);
395+
let location = Location(var_debug_info.source_info.span);
396+
if let Some(composite) = &var_debug_info.composite {
397+
self.visit_ty(&composite.ty, location);
398+
}
399+
match &var_debug_info.value {
400+
VarDebugInfoContents::Place(place) => {
401+
self.visit_place(place, PlaceContext::NON_USE, location);
402+
}
403+
VarDebugInfoContents::Const(constant) => {
404+
self.visit_const(&constant.const_, location);
405+
}
406+
}
407+
}
408+
385409
fn super_assert_msg(&mut self, msg: &AssertMessage, location: Location) {
386410
match msg {
387411
AssertMessage::BoundsCheck { len, index } => {

0 commit comments

Comments
 (0)