Skip to content

Tweak output of const panic diagnostic #136503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ const_eval_frame_note_inner = inside {$where_ ->
*[other] {""}
}

const_eval_frame_note_last = the failure occurred here

const_eval_in_bounds_test = out-of-bounds pointer use
const_eval_incompatible_calling_conventions =
calling a function with calling convention {$callee_conv} using calling convention {$caller_conv}
Expand Down Expand Up @@ -300,8 +302,7 @@ const_eval_overflow_arith =
const_eval_overflow_shift =
overflowing shift by {$shift_amount} in `{$intrinsic}`

const_eval_panic =
the evaluated program panicked at '{$msg}', {$file}:{$line}:{$col}
const_eval_panic = evaluation panicked: {$msg}

const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str`

Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ impl MachineStopType for ConstEvalErrKind {
| ModifiedGlobal
| WriteThroughImmutablePointer => {}
AssertFailure(kind) => kind.add_args(adder),
Panic { msg, line, col, file } => {
Panic { msg, .. } => {
adder("msg".into(), msg.into_diag_arg(&mut None));
adder("file".into(), file.into_diag_arg(&mut None));
adder("line".into(), line.into_diag_arg(&mut None));
adder("col".into(), col.into_diag_arg(&mut None));
}
}
}
Expand All @@ -72,7 +69,7 @@ pub fn get_span_and_frames<'tcx>(
let mut stacktrace = Frame::generate_stacktrace_from_stack(stack);
// Filter out `requires_caller_location` frames.
stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx));
let span = stacktrace.first().map(|f| f.span).unwrap_or(tcx.span);
let span = stacktrace.last().map(|f| f.span).unwrap_or(tcx.span);

let mut frames = Vec::new();

Expand Down Expand Up @@ -115,6 +112,20 @@ pub fn get_span_and_frames<'tcx>(
}
}

// In `rustc`, we present const-eval errors from the outer-most place first to the inner-most.
// So we reverse the frames here. The first frame will be the same as the span from the current
// `TyCtxtAt<'_>`, so we remove it as it would be redundant.
frames.reverse();
if frames.len() > 0 {
frames.remove(0);
}
if let Some(last) = frames.last_mut()
// If the span is not going to be printed, we don't want the span label for `is_last`.
&& tcx.sess.source_map().span_to_snippet(last.span.source_callsite()).is_ok()
{
last.has_label = true;
}

(span, frames)
}

Expand Down
25 changes: 22 additions & 3 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_abi::WrappingRange;
use rustc_errors::codes::*;
use rustc_errors::{
Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level,
MultiSpan, SubdiagMessageOp, Subdiagnostic,
};
use rustc_hir::ConstContext;
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
Expand All @@ -17,6 +18,7 @@ use rustc_middle::mir::interpret::{
use rustc_middle::ty::{self, Mutability, Ty};
use rustc_span::{Span, Symbol};

use crate::fluent_generated as fluent;
use crate::interpret::InternKind;

#[derive(Diagnostic)]
Expand Down Expand Up @@ -278,14 +280,31 @@ pub(crate) struct NonConstImplNote {
pub span: Span,
}

#[derive(Subdiagnostic, Clone)]
#[note(const_eval_frame_note)]
#[derive(Clone)]
pub struct FrameNote {
#[primary_span]
pub span: Span,
pub times: i32,
pub where_: &'static str,
pub instance: String,
pub has_label: bool,
}

impl Subdiagnostic for FrameNote {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
f: &F,
) {
diag.arg("times", self.times);
diag.arg("where_", self.where_);
diag.arg("instance", self.instance);
let mut span: MultiSpan = self.span.into();
if self.has_label && !self.span.is_dummy() {
span.push_span_label(self.span, fluent::const_eval_frame_note_last);
}
let msg = f(diag, fluent::const_eval_frame_note.into());
diag.span_note(span, msg);
}
}

#[derive(Subdiagnostic)]
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_const_eval/src/interpret/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,19 @@ impl<'tcx> FrameInfo<'tcx> {
pub fn as_note(&self, tcx: TyCtxt<'tcx>) -> errors::FrameNote {
let span = self.span;
if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::Closure {
errors::FrameNote { where_: "closure", span, instance: String::new(), times: 0 }
errors::FrameNote {
where_: "closure",
span,
instance: String::new(),
times: 0,
has_label: false,
}
} else {
let instance = format!("{}", self.instance);
// Note: this triggers a `must_produce_diag` state, which means that if we ever get
// here we must emit a diagnostic. We should never display a `FrameInfo` unless we
// actually want to emit a warning or error to the user.
errors::FrameNote { where_: "instance", span, instance, times: 0 }
errors::FrameNote { where_: "instance", span, instance, times: 0, has_label: false }
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/erroneous_const.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
--> tests/fail/erroneous_const.rs:LL:CC
|
LL | const VOID: ! = panic!();
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', tests/fail/erroneous_const.rs:LL:CC
| ^^^^^^^^ evaluation panicked: explicit panic
|
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

Expand Down
5 changes: 2 additions & 3 deletions tests/ui/borrowck/issue-81899.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
// Regression test for #81899.
// The `panic!()` below is important to trigger the fixed ICE.

const _CONST: &[u8] = &f(&[], |_| {});
const _CONST: &[u8] = &f(&[], |_| {}); //~ ERROR evaluation of constant value failed
//~^ constant

const fn f<F>(_: &[u8], _: F) -> &[u8]
where
F: FnMut(&u8),
{
panic!() //~ ERROR evaluation of constant value failed
//~^ panic
panic!() //~ inside `f
}

fn main() {}
13 changes: 4 additions & 9 deletions tests/ui/borrowck/issue-81899.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-81899.rs:11:5
--> $DIR/issue-81899.rs:4:24
|
LL | panic!()
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-81899.rs:11:5
LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^ evaluation panicked: explicit panic
|
note: inside `f::<{closure@$DIR/issue-81899.rs:4:31: 4:34}>`
--> $DIR/issue-81899.rs:11:5
|
LL | panic!()
| ^^^^^^^^
note: inside `_CONST`
--> $DIR/issue-81899.rs:4:24
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^
| ^^^^^^^^ the failure occurred here
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant encountered
Expand Down
5 changes: 2 additions & 3 deletions tests/ui/borrowck/issue-88434-minimal-example.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// Regression test related to issue 88434

const _CONST: &() = &f(&|_| {});
const _CONST: &() = &f(&|_| {}); //~ ERROR evaluation of constant value failed
//~^ constant

const fn f<F>(_: &F)
where
F: FnMut(&u8),
{
panic!() //~ ERROR evaluation of constant value failed
//~^ panic
panic!() //~ inside `f
}

fn main() { }
13 changes: 4 additions & 9 deletions tests/ui/borrowck/issue-88434-minimal-example.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-minimal-example.rs:10:5
--> $DIR/issue-88434-minimal-example.rs:3:22
|
LL | panic!()
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5
LL | const _CONST: &() = &f(&|_| {});
| ^^^^^^^^^^ evaluation panicked: explicit panic
|
note: inside `f::<{closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28}>`
--> $DIR/issue-88434-minimal-example.rs:10:5
|
LL | panic!()
| ^^^^^^^^
note: inside `_CONST`
--> $DIR/issue-88434-minimal-example.rs:3:22
|
LL | const _CONST: &() = &f(&|_| {});
| ^^^^^^^^^^
| ^^^^^^^^ the failure occurred here
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant encountered
Expand Down
5 changes: 2 additions & 3 deletions tests/ui/borrowck/issue-88434-removal-index-should-be-less.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// Regression test for issue 88434

const _CONST: &[u8] = &f(&[], |_| {});
const _CONST: &[u8] = &f(&[], |_| {}); //~ ERROR evaluation of constant value failed
//~^ constant

const fn f<F>(_: &[u8], _: F) -> &[u8]
where
F: FnMut(&u8),
{
panic!() //~ ERROR evaluation of constant value failed
//~^ panic
panic!() //~ inside `f
}

fn main() { }
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
--> $DIR/issue-88434-removal-index-should-be-less.rs:3:24
|
LL | panic!()
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5
LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^ evaluation panicked: explicit panic
|
note: inside `f::<{closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34}>`
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
|
LL | panic!()
| ^^^^^^^^
note: inside `_CONST`
--> $DIR/issue-88434-removal-index-should-be-less.rs:3:24
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^
| ^^^^^^^^ the failure occurred here
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant encountered
Expand Down
7 changes: 3 additions & 4 deletions tests/ui/coherence/const-errs-dont-conflict-103369.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

pub trait ConstGenericTrait<const N: u32> {}

impl ConstGenericTrait<{my_fn(1)}> for () {}
impl ConstGenericTrait<{my_fn(1)}> for () {} //~ ERROR E0080

impl ConstGenericTrait<{my_fn(2)}> for () {}
impl ConstGenericTrait<{my_fn(2)}> for () {} //~ ERROR E0080

const fn my_fn(v: u32) -> u32 {
panic!("Some error occurred"); //~ ERROR E0080
//~| ERROR E0080
panic!("Some error occurred");
}

fn main() {}
26 changes: 8 additions & 18 deletions tests/ui/coherence/const-errs-dont-conflict-103369.stderr
Original file line number Diff line number Diff line change
@@ -1,37 +1,27 @@
error[E0080]: evaluation of constant value failed
--> $DIR/const-errs-dont-conflict-103369.rs:10:5
--> $DIR/const-errs-dont-conflict-103369.rs:5:25
|
LL | panic!("Some error occurred");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'Some error occurred', $DIR/const-errs-dont-conflict-103369.rs:10:5
LL | impl ConstGenericTrait<{my_fn(1)}> for () {}
| ^^^^^^^^ evaluation panicked: Some error occurred
|
note: inside `my_fn`
--> $DIR/const-errs-dont-conflict-103369.rs:10:5
|
LL | panic!("Some error occurred");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<() as ConstGenericTrait<{my_fn(1)}>>::{constant#0}`
--> $DIR/const-errs-dont-conflict-103369.rs:5:25
|
LL | impl ConstGenericTrait<{my_fn(1)}> for () {}
| ^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0080]: evaluation of constant value failed
--> $DIR/const-errs-dont-conflict-103369.rs:10:5
--> $DIR/const-errs-dont-conflict-103369.rs:7:25
|
LL | panic!("Some error occurred");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'Some error occurred', $DIR/const-errs-dont-conflict-103369.rs:10:5
LL | impl ConstGenericTrait<{my_fn(2)}> for () {}
| ^^^^^^^^ evaluation panicked: Some error occurred
|
note: inside `my_fn`
--> $DIR/const-errs-dont-conflict-103369.rs:10:5
|
LL | panic!("Some error occurred");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<() as ConstGenericTrait<{my_fn(2)}>>::{constant#0}`
--> $DIR/const-errs-dont-conflict-103369.rs:7:25
|
LL | impl ConstGenericTrait<{my_fn(2)}> for () {}
| ^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors
Expand Down
5 changes: 2 additions & 3 deletions tests/ui/const-generics/issues/issue-100313.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ struct T<const B: &'static bool>;
impl<const B: &'static bool> T<B> {
const fn set_false(&self) {
unsafe {
*(B as *const bool as *mut bool) = false;
//~^ ERROR evaluation of constant value failed [E0080]
*(B as *const bool as *mut bool) = false; //~ inside `T
}
}
}

const _: () = {
let x = T::<{ &true }>;
x.set_false();
x.set_false(); //~ ERROR evaluation of constant value failed [E0080]
};

fn main() {}
13 changes: 4 additions & 9 deletions tests/ui/const-generics/issues/issue-100313.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-100313.rs:9:13
--> $DIR/issue-100313.rs:16:5
|
LL | *(B as *const bool as *mut bool) = false;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to ALLOC0 which is read-only
LL | x.set_false();
| ^^^^^^^^^^^^^ writing to ALLOC0 which is read-only
|
note: inside `T::<&true>::set_false`
--> $DIR/issue-100313.rs:9:13
|
LL | *(B as *const bool as *mut bool) = false;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `_`
--> $DIR/issue-100313.rs:17:5
|
LL | x.set_false();
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the failure occurred here

error: aborting due to 1 previous error

Expand Down
Loading
Loading