Skip to content

Commit 6f568bf

Browse files
committed
Skip redundant frames in const recursion errors
``` error[E0080]: evaluation of constant value failed --> $DIR/infinite-recursion-const-fn.rs:4:5 | LL | b() | ^^^ reached the configured maximum number of stack frames | note: inside `a` --> $DIR/infinite-recursion-const-fn.rs:4:5 | LL | b() | ^^^ note: inside `b` --> $DIR/infinite-recursion-const-fn.rs:7:5 | LL | a() | ^^^ note: [... 125 additional calls ...] inside `b` --> $DIR/infinite-recursion-const-fn.rs:7:5 | LL | a() | ^^^ note: inside `ARR::{constant#0}` --> $DIR/infinite-recursion-const-fn.rs:9:18 | LL | const ARR: [i32; a()] = [5; 6]; | ^^^ ```
1 parent 2f92f05 commit 6f568bf

File tree

7 files changed

+16
-1252
lines changed

7 files changed

+16
-1252
lines changed

compiler/rustc_const_eval/messages.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const_eval_fn_ptr_call =
100100
function pointers need an RFC before allowed to be called in {const_eval_const_context}s
101101
const_eval_frame_note = {$times ->
102102
[0] {const_eval_frame_note_inner}
103-
*[other] [... {$times} additional calls {const_eval_frame_note_inner} ...]
103+
*[other] [... {$times} additional calls ...] {const_eval_frame_note_inner}
104104
}
105105
106106
const_eval_frame_note_inner = inside {$where_ ->

compiler/rustc_const_eval/src/const_eval/error.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::mem;
22

3+
use rustc_data_structures::fx::FxHashSet;
34
use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, Diagnostic, IntoDiagArg};
45
use rustc_middle::mir::AssertKind;
56
use rustc_middle::mir::interpret::{Provenance, ReportedErrorInfo};
@@ -9,7 +10,7 @@ use rustc_middle::ty::{ConstInt, TyCtxt};
910
use rustc_span::{Span, Symbol};
1011

1112
use super::CompileTimeMachine;
12-
use crate::errors::{self, FrameNote, ReportErrorExt};
13+
use crate::errors::{FrameNote, ReportErrorExt};
1314
use crate::interpret::{
1415
ErrorHandled, Frame, InterpErrorInfo, InterpErrorKind, MachineStopType, err_inval,
1516
err_machine_stop,
@@ -68,7 +69,7 @@ impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
6869
pub fn get_span_and_frames<'tcx>(
6970
tcx: TyCtxtAt<'tcx>,
7071
stack: &[Frame<'tcx, impl Provenance, impl Sized>],
71-
) -> (Span, Vec<errors::FrameNote>) {
72+
) -> (Span, Vec<FrameNote>) {
7273
let mut stacktrace = Frame::generate_stacktrace_from_stack(stack);
7374
// Filter out `requires_caller_location` frames.
7475
stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx));
@@ -79,8 +80,8 @@ pub fn get_span_and_frames<'tcx>(
7980
// Add notes to the backtrace. Don't print a single-line backtrace though.
8081
if stacktrace.len() > 1 {
8182
// Helper closure to print duplicated lines.
82-
let mut add_frame = |mut frame: errors::FrameNote| {
83-
frames.push(errors::FrameNote { times: 0, ..frame.clone() });
83+
let mut add_frame = |mut frame: FrameNote| {
84+
frames.push(FrameNote { times: 0, ..frame.clone() });
8485
// Don't print [... additional calls ...] if the number of lines is small
8586
if frame.times < 3 {
8687
let times = frame.times;
@@ -91,21 +92,19 @@ pub fn get_span_and_frames<'tcx>(
9192
}
9293
};
9394

94-
let mut last_frame: Option<errors::FrameNote> = None;
95+
let mut last_frame: Option<FrameNote> = None;
96+
let mut seen = FxHashSet::default();
9597
for frame_info in &stacktrace {
9698
let frame = frame_info.as_note(*tcx);
9799
match last_frame.as_mut() {
98-
Some(last_frame)
99-
if last_frame.span == frame.span
100-
&& last_frame.where_ == frame.where_
101-
&& last_frame.instance == frame.instance =>
102-
{
100+
Some(last_frame) if !seen.insert(frame.clone()) => {
103101
last_frame.times += 1;
104102
}
105103
Some(last_frame) => {
106104
add_frame(mem::replace(last_frame, frame));
107105
}
108106
None => {
107+
seen.insert(frame.clone());
109108
last_frame = Some(frame);
110109
}
111110
}
@@ -184,7 +183,7 @@ pub(super) fn lint<'tcx, L>(
184183
tcx: TyCtxtAt<'tcx>,
185184
machine: &CompileTimeMachine<'tcx>,
186185
lint: &'static rustc_session::lint::Lint,
187-
decorator: impl FnOnce(Vec<errors::FrameNote>) -> L,
186+
decorator: impl FnOnce(Vec<FrameNote>) -> L,
188187
) where
189188
L: for<'a> rustc_errors::LintDiagnostic<'a, ()>,
190189
{

compiler/rustc_const_eval/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ pub(crate) struct NonConstImplNote {
279279
pub span: Span,
280280
}
281281

282-
#[derive(Subdiagnostic, Clone)]
282+
#[derive(Subdiagnostic, Clone, PartialEq, Eq, Hash)]
283283
#[note(const_eval_frame_note)]
284284
pub struct FrameNote {
285285
#[primary_span]

tests/ui/consts/recursive.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ note: inside `f::<i32>`
2020
|
2121
LL | f(x);
2222
| ^^^^
23-
note: [... 126 additional calls inside `f::<i32>` ...]
23+
note: [... 126 additional calls ...] inside `f::<i32>`
2424
--> $DIR/recursive.rs:4:5
2525
|
2626
LL | f(x);

0 commit comments

Comments
 (0)