Skip to content

Commit 018b859

Browse files
committed
Add VarDebugInfo to Stable MIR
1 parent c5af061 commit 018b859

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, ScalarInt, 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
AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion,
2427
FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span,
@@ -444,10 +447,50 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
444447
})
445448
.collect(),
446449
self.arg_count,
450+
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
447451
)
448452
}
449453
}
450454

455+
impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
456+
type T = stable_mir::mir::VarDebugInfo;
457+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
458+
stable_mir::mir::VarDebugInfo {
459+
name: self.name.to_string(),
460+
source_info: stable_mir::mir::SourceInfo {
461+
span: self.source_info.span.stable(tables),
462+
scope: self.source_info.scope.into(),
463+
},
464+
composite: {
465+
if let Some(composite) = &self.composite {
466+
Some(VarDebugInfoFragment {
467+
ty: composite.ty.stable(tables),
468+
projection: composite.projection.iter().map(|e| e.stable(tables)).collect(),
469+
})
470+
} else {
471+
None
472+
}
473+
},
474+
value: {
475+
match self.value {
476+
mir::VarDebugInfoContents::Place(place) => {
477+
stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables))
478+
}
479+
mir::VarDebugInfoContents::Const(const_operand) => {
480+
let op = ConstOperand {
481+
span: const_operand.span.stable(tables),
482+
user_ty: const_operand.user_ty.map(|index| index.as_usize()),
483+
const_: const_operand.const_.stable(tables),
484+
};
485+
stable_mir::mir::VarDebugInfoContents::Const(op)
486+
}
487+
}
488+
},
489+
argument_index: self.argument_index,
490+
}
491+
}
492+
}
493+
451494
impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
452495
type T = stable_mir::mir::Statement;
453496
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
@@ -2,7 +2,7 @@ use crate::mir::pretty::{function_body, pretty_statement};
22
use crate::ty::{
33
AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind,
44
};
5-
use crate::{Error, Opaque, Span};
5+
use crate::{Error, Opaque, Span, Symbol};
66
use std::io;
77

88
/// The SMIR representation of a single function.
@@ -19,21 +19,29 @@ pub struct Body {
1919

2020
// The number of arguments this function takes.
2121
pub(super) arg_count: usize,
22+
23+
// Debug information pertaining to user variables, including captures.
24+
pub(super) var_debug_info: Vec<VarDebugInfo>,
2225
}
2326

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

3947
/// Return local that holds this function's return value.
@@ -427,6 +435,42 @@ pub struct Place {
427435
pub projection: Vec<ProjectionElem>,
428436
}
429437

438+
#[derive(Clone, Debug, Eq, PartialEq)]
439+
pub struct VarDebugInfo {
440+
pub name: Symbol,
441+
pub source_info: SourceInfo,
442+
pub composite: Option<VarDebugInfoFragment>,
443+
pub value: VarDebugInfoContents,
444+
pub argument_index: Option<u16>,
445+
}
446+
447+
pub type SourceScope = u32;
448+
449+
#[derive(Clone, Debug, Eq, PartialEq)]
450+
pub struct SourceInfo {
451+
pub span: Span,
452+
pub scope: SourceScope,
453+
}
454+
455+
#[derive(Clone, Debug, Eq, PartialEq)]
456+
pub struct VarDebugInfoFragment {
457+
pub ty: Ty,
458+
pub projection: Vec<ProjectionElem>,
459+
}
460+
461+
#[derive(Clone, Debug, Eq, PartialEq)]
462+
pub enum VarDebugInfoContents {
463+
Place(Place),
464+
Const(ConstOperand),
465+
}
466+
467+
#[derive(Clone, Debug, Eq, PartialEq)]
468+
pub struct ConstOperand {
469+
pub span: Span,
470+
pub user_ty: Option<UserTypeAnnotationIndex>,
471+
pub const_: Const,
472+
}
473+
430474
// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
431475
// is so it can be used for both Places (for which the projection elements are of type
432476
// 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.inner_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)