Skip to content

Commit

Permalink
Rollup merge of rust-lang#117972 - ouz-a:stable_debuginfo, r=celinval
Browse files Browse the repository at this point in the history
Add VarDebugInfo to Stable MIR

Previously we omitted `VarDebugInfo` because we didn't have `Projection` now that rust-lang#117517 is merged it's possible to add `VarDebugInfo` information in `Body`. This PR adds stable version of the `VarDebugInfo` to `Body`

r? `@celinval`
  • Loading branch information
matthiaskrgr committed Nov 21, 2023
2 parents 0ff8610 + d0dd19a commit 6e65a08
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 5 deletions.
55 changes: 54 additions & 1 deletion compiler/rustc_smir/src/rustc_smir/mod.rs
Expand Up @@ -18,7 +18,10 @@ use rustc_middle::ty::{self, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, Variance
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_target::abi::FieldIdx;
use stable_mir::mir::mono::InstanceDef;
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
use stable_mir::mir::{
Body, ConstOperand, CopyNonOverlapping, Statement, UserTypeProjection, VarDebugInfoFragment,
VariantIdx,
};
use stable_mir::ty::{
AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion,
FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span,
Expand Down Expand Up @@ -444,17 +447,67 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
})
.collect(),
self.arg_count,
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
)
}
}

impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
type T = stable_mir::mir::VarDebugInfo;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
stable_mir::mir::VarDebugInfo {
name: self.name.to_string(),
source_info: self.source_info.stable(tables),
composite: self.composite.as_ref().map(|composite| composite.stable(tables)),
value: self.value.stable(tables),
argument_index: self.argument_index,
}
}
}

impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
type T = stable_mir::mir::Statement;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
}
}

impl<'tcx> Stable<'tcx> for mir::SourceInfo {
type T = stable_mir::mir::SourceInfo;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() }
}
}

impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> {
type T = stable_mir::mir::VarDebugInfoFragment;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
VarDebugInfoFragment {
ty: self.ty.stable(tables),
projection: self.projection.iter().map(|e| e.stable(tables)).collect(),
}
}
}

impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
type T = stable_mir::mir::VarDebugInfoContents;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
match self {
mir::VarDebugInfoContents::Place(place) => {
stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables))
}
mir::VarDebugInfoContents::Const(const_operand) => {
let op = ConstOperand {
span: const_operand.span.stable(tables),
user_ty: const_operand.user_ty.map(|index| index.as_usize()),
const_: const_operand.const_.stable(tables),
};
stable_mir::mir::VarDebugInfoContents::Const(op)
}
}
}
}

impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
type T = stable_mir::mir::StatementKind;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
Expand Down
50 changes: 47 additions & 3 deletions compiler/stable_mir/src/mir/body.rs
Expand Up @@ -2,7 +2,7 @@ use crate::mir::pretty::{function_body, pretty_statement};
use crate::ty::{
AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind,
};
use crate::{Error, Opaque, Span};
use crate::{Error, Opaque, Span, Symbol};
use std::io;

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

// The number of arguments this function takes.
pub(super) arg_count: usize,

// Debug information pertaining to user variables, including captures.
pub(super) var_debug_info: Vec<VarDebugInfo>,
}

impl Body {
/// Constructs a `Body`.
///
/// A constructor is required to build a `Body` from outside the crate
/// because the `arg_count` and `locals` fields are private.
pub fn new(blocks: Vec<BasicBlock>, locals: LocalDecls, arg_count: usize) -> Self {
pub fn new(
blocks: Vec<BasicBlock>,
locals: LocalDecls,
arg_count: usize,
var_debug_info: Vec<VarDebugInfo>,
) -> Self {
// If locals doesn't contain enough entries, it can lead to panics in
// `ret_local`, `arg_locals`, and `inner_locals`.
assert!(
locals.len() > arg_count,
"A Body must contain at least a local for the return value and each of the function's arguments"
);
Self { blocks, locals, arg_count }
Self { blocks, locals, arg_count, var_debug_info }
}

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

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VarDebugInfo {
pub name: Symbol,
pub source_info: SourceInfo,
pub composite: Option<VarDebugInfoFragment>,
pub value: VarDebugInfoContents,
pub argument_index: Option<u16>,
}

pub type SourceScope = u32;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SourceInfo {
pub span: Span,
pub scope: SourceScope,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VarDebugInfoFragment {
pub ty: Ty,
pub projection: Vec<ProjectionElem>,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum VarDebugInfoContents {
Place(Place),
Const(ConstOperand),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ConstOperand {
pub span: Span,
pub user_ty: Option<UserTypeAnnotationIndex>,
pub const_: Const,
}

// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
// is so it can be used for both Places (for which the projection elements are of type
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
Expand Down
28 changes: 27 additions & 1 deletion compiler/stable_mir/src/mir/visit.rs
Expand Up @@ -128,8 +128,12 @@ pub trait MirVisitor {
self.super_assert_msg(msg, location)
}

fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) {
self.super_var_debug_info(var_debug_info);
}

fn super_body(&mut self, body: &Body) {
let Body { blocks, locals: _, arg_count } = body;
let Body { blocks, locals: _, arg_count, var_debug_info } = body;

for bb in blocks {
self.visit_basic_block(bb);
Expand All @@ -145,6 +149,10 @@ pub trait MirVisitor {
for (idx, arg) in body.inner_locals().iter().enumerate() {
self.visit_local_decl(idx + local_start, arg)
}

for info in var_debug_info.iter() {
self.visit_var_debug_info(info);
}
}

fn super_basic_block(&mut self, bb: &BasicBlock) {
Expand Down Expand Up @@ -382,6 +390,24 @@ pub trait MirVisitor {
let _ = args;
}

fn super_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) {
let VarDebugInfo { source_info, composite, value, name: _, argument_index: _ } =
var_debug_info;
self.visit_span(&source_info.span);
let location = Location(source_info.span);
if let Some(composite) = composite {
self.visit_ty(&composite.ty, location);
}
match value {
VarDebugInfoContents::Place(place) => {
self.visit_place(place, PlaceContext::NON_USE, location);
}
VarDebugInfoContents::Const(constant) => {
self.visit_const(&constant.const_, location);
}
}
}

fn super_assert_msg(&mut self, msg: &AssertMessage, location: Location) {
match msg {
AssertMessage::BoundsCheck { len, index } => {
Expand Down

0 comments on commit 6e65a08

Please sign in to comment.