Skip to content

Commit c703af3

Browse files
committed
Add VarDebugInfo to Stable MIR
1 parent e6dade9 commit c703af3

File tree

3 files changed

+116
-6
lines changed

3 files changed

+116
-6
lines changed

compiler/rustc_smir/src/rustc_smir/mod.rs

+44-1
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
AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion,
2427
FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span,
@@ -412,10 +415,50 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
412415
})
413416
.collect(),
414417
self.arg_count,
418+
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
415419
)
416420
}
417421
}
418422

423+
impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
424+
type T = stable_mir::mir::VarDebugInfo;
425+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
426+
stable_mir::mir::VarDebugInfo {
427+
name: self.name.to_string(),
428+
source_info: stable_mir::mir::SourceInfo {
429+
span: self.source_info.span.stable(tables),
430+
scope: self.source_info.scope.into(),
431+
},
432+
composite: {
433+
if let Some(composite) = &self.composite {
434+
Some(VarDebugInfoFragment {
435+
ty: composite.ty.stable(tables),
436+
projection: composite.projection.iter().map(|e| e.stable(tables)).collect(),
437+
})
438+
} else {
439+
None
440+
}
441+
},
442+
value: {
443+
match self.value {
444+
mir::VarDebugInfoContents::Place(place) => {
445+
stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables))
446+
}
447+
mir::VarDebugInfoContents::Const(const_operand) => {
448+
let op = ConstOperand {
449+
span: const_operand.span.stable(tables),
450+
user_ty: const_operand.user_ty.map(|index| index.as_usize()),
451+
const_: const_operand.const_.stable(tables),
452+
};
453+
stable_mir::mir::VarDebugInfoContents::Const(op)
454+
}
455+
}
456+
},
457+
argument_index: self.argument_index,
458+
}
459+
}
460+
}
461+
419462
impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
420463
type T = stable_mir::mir::Statement;
421464
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {

compiler/stable_mir/src/mir/body.rs

+47-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::mir::pretty::{function_body, pretty_statement};
22
use crate::ty::{AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, Ty};
3-
use crate::Opaque;
4-
use crate::Span;
3+
use crate::{Opaque, Span, Symbol};
54
use std::io;
65
/// The SMIR representation of a single function.
76
#[derive(Clone, Debug)]
@@ -17,21 +16,29 @@ pub struct Body {
1716

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

2224
impl Body {
2325
/// Constructs a `Body`.
2426
///
2527
/// A constructor is required to build a `Body` from outside the crate
2628
/// because the `arg_count` and `locals` fields are private.
27-
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 {
2835
// If locals doesn't contain enough entries, it can lead to panics in
2936
// `ret_local`, `arg_locals`, and `inner_locals`.
3037
assert!(
3138
locals.len() > arg_count,
3239
"A Body must contain at least a local for the return value and each of the function's arguments"
3340
);
34-
Self { blocks, locals, arg_count }
41+
Self { blocks, locals, arg_count, var_debug_info }
3542
}
3643

3744
/// Return local that holds this function's return value.
@@ -425,6 +432,42 @@ pub struct Place {
425432
pub projection: Vec<ProjectionElem>,
426433
}
427434

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

compiler/stable_mir/src/mir/visit.rs

+25-1
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)