Skip to content

Commit 9381e5b

Browse files
authored
Rollup merge of rust-lang#115540 - cjgillot:custom-debuginfo, r=oli-obk
Support debuginfo for custom MIR.
2 parents 09974df + 905fd1b commit 9381e5b

File tree

9 files changed

+207
-14
lines changed

9 files changed

+207
-14
lines changed

compiler/rustc_mir_build/src/build/custom/parse.rs

+56-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rustc_index::IndexSlice;
2-
use rustc_middle::{mir::*, thir::*, ty::Ty};
2+
use rustc_middle::ty::{self, Ty};
3+
use rustc_middle::{mir::*, thir::*};
34
use rustc_span::Span;
45

56
use super::{PResult, ParseCtxt, ParseError};
@@ -159,6 +160,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
159160
);
160161
self.parse_local_decls(local_decls.iter().copied())?;
161162

163+
let (debuginfo, rest) = parse_by_kind!(self, rest, _, "body with debuginfo",
164+
ExprKind::Block { block } => {
165+
let block = &self.thir[*block];
166+
(&block.stmts, block.expr.unwrap())
167+
},
168+
);
169+
self.parse_debuginfo(debuginfo.iter().copied())?;
170+
162171
let block_defs = parse_by_kind!(self, rest, _, "body with block defs",
163172
ExprKind::Block { block } => &self.thir[*block].stmts,
164173
);
@@ -195,6 +204,52 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
195204
Ok(())
196205
}
197206

207+
fn parse_debuginfo(&mut self, stmts: impl Iterator<Item = StmtId>) -> PResult<()> {
208+
for stmt in stmts {
209+
let stmt = &self.thir[stmt];
210+
let expr = match stmt.kind {
211+
StmtKind::Let { span, .. } => {
212+
return Err(ParseError {
213+
span,
214+
item_description: format!("{:?}", stmt),
215+
expected: "debuginfo".to_string(),
216+
});
217+
}
218+
StmtKind::Expr { expr, .. } => expr,
219+
};
220+
let span = self.thir[expr].span;
221+
let (name, operand) = parse_by_kind!(self, expr, _, "debuginfo",
222+
@call("mir_debuginfo", args) => {
223+
(args[0], args[1])
224+
},
225+
);
226+
let name = parse_by_kind!(self, name, _, "debuginfo",
227+
ExprKind::Literal { lit, neg: false } => lit,
228+
);
229+
let Some(name) = name.node.str() else {
230+
return Err(ParseError {
231+
span,
232+
item_description: format!("{:?}", name),
233+
expected: "string".to_string(),
234+
});
235+
};
236+
let operand = self.parse_operand(operand)?;
237+
let value = match operand {
238+
Operand::Constant(c) => VarDebugInfoContents::Const(*c),
239+
Operand::Copy(p) | Operand::Move(p) => VarDebugInfoContents::Place(p),
240+
};
241+
let dbginfo = VarDebugInfo {
242+
name,
243+
source_info: SourceInfo { span, scope: self.source_scope },
244+
argument_index: None,
245+
value,
246+
};
247+
self.body.var_debug_info.push(dbginfo);
248+
}
249+
250+
Ok(())
251+
}
252+
198253
fn parse_let_statement(&mut self, stmt_id: StmtId) -> PResult<(LocalVarId, Ty<'tcx>, Span)> {
199254
let pattern = match &self.thir[stmt_id].kind {
200255
StmtKind::Let { pattern, .. } => pattern,

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
204204
)
205205
}
206206

207-
fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
207+
pub fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
208208
parse_by_kind!(self, expr_id, expr, "operand",
209209
@call("mir_move", args) => self.parse_place(args[0]).map(Operand::Move),
210210
@call("mir_static", args) => self.parse_static(args[0]),

library/core/src/intrinsics/mir.rs

+27-12
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
//!
1313
//! Typical usage will look like this:
1414
//!
15-
//! ```rust
15+
#![cfg_attr(bootstrap, doc = "```rust,ignore")]
16+
#![cfg_attr(not(bootstrap), doc = "```rust")]
1617
//! #![feature(core_intrinsics, custom_mir)]
1718
//! #![allow(internal_features)]
1819
//!
@@ -62,7 +63,8 @@
6263
//!
6364
//! # Examples
6465
//!
65-
//! ```rust
66+
#![cfg_attr(bootstrap, doc = "```rust,ignore")]
67+
#![cfg_attr(not(bootstrap), doc = "```rust")]
6668
//! #![feature(core_intrinsics, custom_mir)]
6769
//! #![allow(internal_features)]
6870
//!
@@ -317,7 +319,8 @@ define!(
317319
///
318320
/// # Examples
319321
///
320-
/// ```rust
322+
#[cfg_attr(bootstrap, doc = "```rust,ignore")]
323+
#[cfg_attr(not(bootstrap), doc = "```rust")]
321324
/// #![allow(internal_features)]
322325
/// #![feature(custom_mir, core_intrinsics)]
323326
///
@@ -361,6 +364,11 @@ define!(
361364
#[doc(hidden)]
362365
fn __internal_make_place<T>(place: T) -> *mut T
363366
);
367+
define!(
368+
"mir_debuginfo",
369+
#[doc(hidden)]
370+
fn __debuginfo<T>(name: &'static str, s: T)
371+
);
364372

365373
/// Macro for generating custom MIR.
366374
///
@@ -371,6 +379,7 @@ pub macro mir {
371379
(
372380
$(type RET = $ret_ty:ty ;)?
373381
$(let $local_decl:ident $(: $local_decl_ty:ty)? ;)*
382+
$(debug $dbg_name:ident => $dbg_data:expr ;)*
374383

375384
{
376385
$($entry:tt)*
@@ -394,26 +403,32 @@ pub macro mir {
394403
$(
395404
let $local_decl $(: $local_decl_ty)? ;
396405
)*
397-
398406
::core::intrinsics::mir::__internal_extract_let!($($entry)*);
399407
$(
400408
::core::intrinsics::mir::__internal_extract_let!($($block)*);
401409
)*
402410

403411
{
404-
// Finally, the contents of the basic blocks
405-
::core::intrinsics::mir::__internal_remove_let!({
406-
{}
407-
{ $($entry)* }
408-
});
412+
// Now debuginfo
409413
$(
414+
__debuginfo(stringify!($dbg_name), $dbg_data);
415+
)*
416+
417+
{
418+
// Finally, the contents of the basic blocks
410419
::core::intrinsics::mir::__internal_remove_let!({
411420
{}
412-
{ $($block)* }
421+
{ $($entry)* }
413422
});
414-
)*
423+
$(
424+
::core::intrinsics::mir::__internal_remove_let!({
425+
{}
426+
{ $($block)* }
427+
});
428+
)*
415429

416-
RET
430+
RET
431+
}
417432
}
418433
}
419434
}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// MIR for `numbered` after built
2+
3+
fn numbered(_1: (u32, i32)) -> () {
4+
debug first => (_1.0: u32);
5+
debug second => (_1.0: u32);
6+
let mut _0: ();
7+
8+
bb0: {
9+
return;
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `pointee` after built
2+
3+
fn pointee(_1: &mut Option<i32>) -> () {
4+
debug foo => (((*_1) as variant#1).0: i32);
5+
let mut _0: ();
6+
7+
bb0: {
8+
return;
9+
}
10+
}
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#![feature(custom_mir, core_intrinsics)]
2+
3+
extern crate core;
4+
use core::intrinsics::mir::*;
5+
6+
// EMIT_MIR debuginfo.pointee.built.after.mir
7+
#[custom_mir(dialect = "built")]
8+
fn pointee(opt: &mut Option<i32>) {
9+
mir!(
10+
debug foo => Field::<i32>(Variant(*opt, 1), 0);
11+
{
12+
Return()
13+
}
14+
)
15+
}
16+
17+
// EMIT_MIR debuginfo.numbered.built.after.mir
18+
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
19+
fn numbered(i: (u32, i32)) {
20+
mir!(
21+
debug first => i.0;
22+
debug second => i.0;
23+
{
24+
Return()
25+
}
26+
)
27+
}
28+
29+
struct S { x: f32 }
30+
31+
// EMIT_MIR debuginfo.structured.built.after.mir
32+
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
33+
fn structured(i: S) {
34+
mir!(
35+
debug x => i.x;
36+
{
37+
Return()
38+
}
39+
)
40+
}
41+
42+
// EMIT_MIR debuginfo.variant.built.after.mir
43+
#[custom_mir(dialect = "built")]
44+
fn variant(opt: Option<i32>) {
45+
mir!(
46+
debug inner => Field::<i32>(Variant(opt, 1), 0);
47+
{
48+
Return()
49+
}
50+
)
51+
}
52+
53+
// EMIT_MIR debuginfo.variant_deref.built.after.mir
54+
#[custom_mir(dialect = "built")]
55+
fn variant_deref(opt: Option<&i32>) {
56+
mir!(
57+
debug pointer => Field::<&i32>(Variant(opt, 1), 0);
58+
debug deref => *Field::<&i32>(Variant(opt, 1), 0);
59+
{
60+
Return()
61+
}
62+
)
63+
}
64+
65+
fn main() {
66+
numbered((5, 6));
67+
structured(S { x: 5. });
68+
variant(Some(5));
69+
variant_deref(Some(&5));
70+
pointee(&mut Some(5));
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `structured` after built
2+
3+
fn structured(_1: S) -> () {
4+
debug x => (_1.0: f32);
5+
let mut _0: ();
6+
7+
bb0: {
8+
return;
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `variant` after built
2+
3+
fn variant(_1: Option<i32>) -> () {
4+
debug inner => ((_1 as variant#1).0: i32);
5+
let mut _0: ();
6+
7+
bb0: {
8+
return;
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// MIR for `variant_deref` after built
2+
3+
fn variant_deref(_1: Option<&i32>) -> () {
4+
debug pointer => ((_1 as variant#1).0: &i32);
5+
debug deref => (*((_1 as variant#1).0: &i32));
6+
let mut _0: ();
7+
8+
bb0: {
9+
return;
10+
}
11+
}

0 commit comments

Comments
 (0)