Skip to content

Commit 09d1265

Browse files
committed
Auto merge of rust-lang#14843 - HKalbasi:mir3, r=HKalbasi
Partially support panic message in `MirEvalError` And bring the metrics back, by using `::core` instead of `$crate` in `format_args!` (it looks like eager macros don't support them).
2 parents 9ce9567 + 4adfbbf commit 09d1265

File tree

11 files changed

+199
-45
lines changed

11 files changed

+199
-45
lines changed

crates/hir-def/src/body.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ impl Body {
187187
pretty::print_body_hir(db, self, owner)
188188
}
189189

190+
pub fn pretty_print_expr(
191+
&self,
192+
db: &dyn DefDatabase,
193+
owner: DefWithBodyId,
194+
expr: ExprId,
195+
) -> String {
196+
pretty::print_expr_hir(db, self, owner, expr)
197+
}
198+
190199
fn new(
191200
db: &dyn DefDatabase,
192201
owner: DefWithBodyId,

crates/hir-def/src/body/pretty.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
6161
p.buf
6262
}
6363

64+
pub(super) fn print_expr_hir(
65+
_db: &dyn DefDatabase,
66+
body: &Body,
67+
_owner: DefWithBodyId,
68+
expr: ExprId,
69+
) -> String {
70+
let mut p = Printer { body, buf: String::new(), indent_level: 0, needs_indent: false };
71+
p.print_expr(expr);
72+
p.buf
73+
}
74+
6475
macro_rules! w {
6576
($dst:expr, $($arg:tt)*) => {
6677
{ let _ = write!($dst, $($arg)*); }

crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ macro_rules! format_args {
201201
}
202202
203203
fn main() {
204-
$crate::fmt::Arguments::new_v1(&["", " ", ], &[$crate::fmt::ArgumentV1::new(&(arg1(a, b, c)), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(arg2), $crate::fmt::Debug::fmt), ]);
204+
::core::fmt::Arguments::new_v1(&["", " ", ], &[::core::fmt::ArgumentV1::new(&(arg1(a, b, c)), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(arg2), ::core::fmt::Debug::fmt), ]);
205205
}
206206
"##]],
207207
);
@@ -229,7 +229,7 @@ macro_rules! format_args {
229229
}
230230
231231
fn main() {
232-
$crate::fmt::Arguments::new_v1(&["", " ", ], &[$crate::fmt::ArgumentV1::new(&(a::<A, B>()), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(b), $crate::fmt::Debug::fmt), ]);
232+
::core::fmt::Arguments::new_v1(&["", " ", ], &[::core::fmt::ArgumentV1::new(&(a::<A, B>()), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(b), ::core::fmt::Debug::fmt), ]);
233233
}
234234
"##]],
235235
);
@@ -262,7 +262,7 @@ macro_rules! format_args {
262262
}
263263
264264
fn main() {
265-
$crate::fmt::Arguments::new_v1(&[r#""#, r#",mismatch,""#, r#"",""#, r#"""#, ], &[$crate::fmt::ArgumentV1::new(&(location_csv_pat(db, &analysis, vfs, &sm, pat_id)), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(mismatch.expected.display(db)), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(mismatch.actual.display(db)), $crate::fmt::Display::fmt), ]);
265+
::core::fmt::Arguments::new_v1(&[r#""#, r#",mismatch,""#, r#"",""#, r#"""#, ], &[::core::fmt::ArgumentV1::new(&(location_csv_pat(db, &analysis, vfs, &sm, pat_id)), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(mismatch.expected.display(db)), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(mismatch.actual.display(db)), ::core::fmt::Display::fmt), ]);
266266
}
267267
"##]],
268268
);
@@ -296,7 +296,7 @@ macro_rules! format_args {
296296
}
297297
298298
fn main() {
299-
$crate::fmt::Arguments::new_v1(&["xxx", "y", "zzz", ], &[$crate::fmt::ArgumentV1::new(&(2), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(b), $crate::fmt::Debug::fmt), ]);
299+
::core::fmt::Arguments::new_v1(&["xxx", "y", "zzz", ], &[::core::fmt::ArgumentV1::new(&(2), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(b), ::core::fmt::Debug::fmt), ]);
300300
}
301301
"##]],
302302
);
@@ -327,7 +327,7 @@ macro_rules! format_args {
327327
fn main() {
328328
let _ =
329329
/* error: no rule matches input tokens *//* parse error: expected field name or number */
330-
$crate::fmt::Arguments::new_v1(&["", " ", ], &[$crate::fmt::ArgumentV1::new(&(a.), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(), $crate::fmt::Debug::fmt), ]);
330+
::core::fmt::Arguments::new_v1(&["", " ", ], &[::core::fmt::ArgumentV1::new(&(a.), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(), ::core::fmt::Debug::fmt), ]);
331331
}
332332
"##]],
333333
);

crates/hir-expand/src/builtin_fn_macro.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -363,16 +363,14 @@ fn format_args_expand_general(
363363
quote!(#ident)
364364
};
365365
let formatter = match &*format_spec {
366-
"?" => quote!(#DOLLAR_CRATE::fmt::Debug::fmt),
367-
"" => quote!(#DOLLAR_CRATE::fmt::Display::fmt),
366+
"?" => quote!(::core::fmt::Debug::fmt),
367+
"" => quote!(::core::fmt::Display::fmt),
368368
_ => {
369369
// FIXME: implement the rest and return expand error here
370-
quote!(#DOLLAR_CRATE::fmt::Display::fmt)
370+
quote!(::core::fmt::Display::fmt)
371371
}
372372
};
373-
arg_tts.push(
374-
quote! { #DOLLAR_CRATE::fmt::ArgumentV1::new(&(#arg_tree), #formatter), },
375-
);
373+
arg_tts.push(quote! { ::core::fmt::ArgumentV1::new(&(#arg_tree), #formatter), });
376374
}
377375
'}' => {
378376
if format_iter.peek() == Some(&'}') {
@@ -400,7 +398,7 @@ fn format_args_expand_general(
400398
});
401399
let arg_tts = arg_tts.into_iter().flat_map(|arg| arg.token_trees);
402400
let expanded = quote! {
403-
#DOLLAR_CRATE::fmt::Arguments::new_v1(&[##part_tts], &[##arg_tts])
401+
::core::fmt::Arguments::new_v1(&[##part_tts], &[##arg_tts])
404402
};
405403
ExpandResult { value: expanded, err }
406404
}

crates/hir-expand/src/name.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ pub mod known {
362362
gt,
363363
le,
364364
lt,
365+
// known fields of lang items
366+
pieces,
365367
// lang items
366368
add_assign,
367369
add,

crates/hir-ty/src/consteval/tests.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ fn simplify(e: ConstEvalError) -> ConstEvalError {
2626
#[track_caller]
2727
fn check_fail(ra_fixture: &str, error: impl FnOnce(ConstEvalError) -> bool) {
2828
let (db, file_id) = TestDB::with_single_file(ra_fixture);
29-
match eval_goal(&db, file_id).map_err(simplify) {
29+
match eval_goal(&db, file_id) {
3030
Ok(_) => panic!("Expected fail, but it succeeded"),
31-
Err(e) => assert!(error(e)),
31+
Err(e) => {
32+
assert!(error(simplify(e.clone())), "Actual error was: {}", pretty_print_err(e, db))
33+
}
3234
}
3335
}
3436

@@ -38,13 +40,7 @@ fn check_number(ra_fixture: &str, answer: i128) {
3840
let r = match eval_goal(&db, file_id) {
3941
Ok(t) => t,
4042
Err(e) => {
41-
let mut err = String::new();
42-
let span_formatter = |file, range| format!("{:?} {:?}", file, range);
43-
match e {
44-
ConstEvalError::MirLowerError(e) => e.pretty_print(&mut err, &db, span_formatter),
45-
ConstEvalError::MirEvalError(e) => e.pretty_print(&mut err, &db, span_formatter),
46-
}
47-
.unwrap();
43+
let err = pretty_print_err(e, db);
4844
panic!("Error in evaluating goal: {}", err);
4945
}
5046
};
@@ -64,6 +60,17 @@ fn check_number(ra_fixture: &str, answer: i128) {
6460
}
6561
}
6662

63+
fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String {
64+
let mut err = String::new();
65+
let span_formatter = |file, range| format!("{:?} {:?}", file, range);
66+
match e {
67+
ConstEvalError::MirLowerError(e) => e.pretty_print(&mut err, &db, span_formatter),
68+
ConstEvalError::MirEvalError(e) => e.pretty_print(&mut err, &db, span_formatter),
69+
}
70+
.unwrap();
71+
err
72+
}
73+
6774
fn eval_goal(db: &TestDB, file_id: FileId) -> Result<Const, ConstEvalError> {
6875
let module_id = db.module_for_file(file_id);
6976
let def_map = module_id.def_map(db);
@@ -2187,6 +2194,20 @@ fn const_trait_assoc() {
21872194
);
21882195
}
21892196

2197+
#[test]
2198+
fn panic_messages() {
2199+
check_fail(
2200+
r#"
2201+
//- minicore: panic
2202+
const GOAL: u8 = {
2203+
let x: u16 = 2;
2204+
panic!("hello");
2205+
};
2206+
"#,
2207+
|e| e == ConstEvalError::MirEvalError(MirEvalError::Panic("hello".to_string())),
2208+
);
2209+
}
2210+
21902211
#[test]
21912212
fn exec_limits() {
21922213
check_fail(

crates/hir-ty/src/mir/eval/shim.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,49 @@ impl Evaluator<'_> {
153153
use LangItem::*;
154154
let mut args = args.iter();
155155
match x {
156-
// FIXME: we want to find the panic message from arguments, but it wouldn't work
157-
// currently even if we do that, since macro expansion of panic related macros
158-
// is dummy.
159-
PanicFmt | BeginPanic => Err(MirEvalError::Panic("<format-args>".to_string())),
156+
BeginPanic => Err(MirEvalError::Panic("<unknown-panic-payload>".to_string())),
157+
PanicFmt => {
158+
let message = (|| {
159+
let arguments_struct =
160+
self.db.lang_item(self.crate_id, LangItem::FormatArguments)?.as_struct()?;
161+
let arguments_layout = self
162+
.layout_adt(arguments_struct.into(), Substitution::empty(Interner))
163+
.ok()?;
164+
let arguments_field_pieces =
165+
self.db.struct_data(arguments_struct).variant_data.field(&name![pieces])?;
166+
let pieces_offset = arguments_layout
167+
.fields
168+
.offset(u32::from(arguments_field_pieces.into_raw()) as usize)
169+
.bytes_usize();
170+
let ptr_size = self.ptr_size();
171+
let arg = args.next()?;
172+
let pieces_array_addr =
173+
Address::from_bytes(&arg[pieces_offset..pieces_offset + ptr_size]).ok()?;
174+
let pieces_array_len = usize::from_le_bytes(
175+
(&arg[pieces_offset + ptr_size..pieces_offset + 2 * ptr_size])
176+
.try_into()
177+
.ok()?,
178+
);
179+
let mut message = "".to_string();
180+
for i in 0..pieces_array_len {
181+
let piece_ptr_addr = pieces_array_addr.offset(2 * i * ptr_size);
182+
let piece_addr =
183+
Address::from_bytes(self.read_memory(piece_ptr_addr, ptr_size).ok()?)
184+
.ok()?;
185+
let piece_len = usize::from_le_bytes(
186+
self.read_memory(piece_ptr_addr.offset(ptr_size), ptr_size)
187+
.ok()?
188+
.try_into()
189+
.ok()?,
190+
);
191+
let piece_data = self.read_memory(piece_addr, piece_len).ok()?;
192+
message += &std::string::String::from_utf8_lossy(piece_data);
193+
}
194+
Some(message)
195+
})()
196+
.unwrap_or_else(|| "<format-args-evaluation-failed>".to_string());
197+
Err(MirEvalError::Panic(message))
198+
}
160199
SliceLen => {
161200
let arg = args
162201
.next()

crates/hir-ty/src/mir/lower.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub enum MirLowerError {
8181
UnresolvedMethod(String),
8282
UnresolvedField,
8383
UnsizedTemporary(Ty),
84-
MissingFunctionDefinition,
84+
MissingFunctionDefinition(DefWithBodyId, ExprId),
8585
TypeMismatch(TypeMismatch),
8686
/// This should be never happen. Type mismatch should catch everything.
8787
TypeError(&'static str),
@@ -113,6 +113,22 @@ impl MirLowerError {
113113
ConstEvalError::MirEvalError(e) => e.pretty_print(f, db, span_formatter)?,
114114
}
115115
}
116+
MirLowerError::MissingFunctionDefinition(owner, x) => {
117+
let body = db.body(*owner);
118+
writeln!(
119+
f,
120+
"Missing function definition for {}",
121+
body.pretty_print_expr(db.upcast(), *owner, *x)
122+
)?;
123+
}
124+
MirLowerError::TypeMismatch(e) => {
125+
writeln!(
126+
f,
127+
"Type mismatch: Expected {}, found {}",
128+
e.expected.display(db),
129+
e.actual.display(db),
130+
)?;
131+
}
116132
MirLowerError::LayoutError(_)
117133
| MirLowerError::UnsizedTemporary(_)
118134
| MirLowerError::IncompleteExpr
@@ -122,8 +138,6 @@ impl MirLowerError {
122138
| MirLowerError::RecordLiteralWithoutPath
123139
| MirLowerError::UnresolvedMethod(_)
124140
| MirLowerError::UnresolvedField
125-
| MirLowerError::MissingFunctionDefinition
126-
| MirLowerError::TypeMismatch(_)
127141
| MirLowerError::TypeError(_)
128142
| MirLowerError::NotSupported(_)
129143
| MirLowerError::ContinueWithoutLoop
@@ -599,7 +613,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
599613
};
600614
self.lower_call_and_args(func, args.iter().copied(), place, current, self.is_uninhabited(expr_id), expr_id.into())
601615
}
602-
TyKind::Error => return Err(MirLowerError::MissingFunctionDefinition),
616+
TyKind::Error => return Err(MirLowerError::MissingFunctionDefinition(self.owner, expr_id)),
603617
_ => return Err(MirLowerError::TypeError("function call on bad type")),
604618
}
605619
}

crates/hir-ty/src/tests/regression.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,13 +1475,12 @@ fn regression_11688_3() {
14751475
struct Ar<T, const N: u8>(T);
14761476
fn f<const LEN: usize, T, const BASE: u8>(
14771477
num_zeros: usize,
1478-
) -> dyn Iterator<Item = [Ar<T, BASE>; LEN]> {
1478+
) -> &dyn Iterator<Item = [Ar<T, BASE>; LEN]> {
14791479
loop {}
14801480
}
14811481
fn dynamic_programming() {
1482-
for board in f::<9, u8, 7>(1) {
1483-
//^^^^^ [Ar<u8, 7>; 9]
1484-
}
1482+
let board = f::<9, u8, 7>(1).next();
1483+
//^^^^^ Option<[Ar<u8, 7>; 9]>
14851484
}
14861485
"#,
14871486
);

crates/ide/src/inlay_hints/chaining.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ fn main() {
474474
file_id: FileId(
475475
1,
476476
),
477-
range: 5769..5777,
477+
range: 9164..9172,
478478
},
479479
),
480480
tooltip: "",
@@ -487,7 +487,7 @@ fn main() {
487487
file_id: FileId(
488488
1,
489489
),
490-
range: 5801..5805,
490+
range: 9196..9200,
491491
},
492492
),
493493
tooltip: "",
@@ -511,7 +511,7 @@ fn main() {
511511
file_id: FileId(
512512
1,
513513
),
514-
range: 5769..5777,
514+
range: 9164..9172,
515515
},
516516
),
517517
tooltip: "",
@@ -524,7 +524,7 @@ fn main() {
524524
file_id: FileId(
525525
1,
526526
),
527-
range: 5801..5805,
527+
range: 9196..9200,
528528
},
529529
),
530530
tooltip: "",
@@ -548,7 +548,7 @@ fn main() {
548548
file_id: FileId(
549549
1,
550550
),
551-
range: 5769..5777,
551+
range: 9164..9172,
552552
},
553553
),
554554
tooltip: "",
@@ -561,7 +561,7 @@ fn main() {
561561
file_id: FileId(
562562
1,
563563
),
564-
range: 5801..5805,
564+
range: 9196..9200,
565565
},
566566
),
567567
tooltip: "",

0 commit comments

Comments
 (0)