Repository: rust-lang/rust
Pull request: interpreter error reporting: remove arguments that are always the same

This `report` function is called twice and both callers use the same `span` and `get_span_and_frames`... so let's just fix those arguments inside the function, no need to be more generic than this.

Changed files:
filename: compiler/rustc_const_eval/src/const_eval/error.rs
patch: @@ -1,14 +1,14 @@
 use std::{fmt, mem};
 
-use rustc_errors::Diag;
+use rustc_errors::{Diag, E0080};
 use rustc_middle::mir::AssertKind;
 use rustc_middle::mir::interpret::{
     AllocId, Provenance, ReportedErrorInfo, UndefinedBehaviorInfo, UnsupportedOpInfo,
 };
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::ConstInt;
 use rustc_middle::ty::layout::LayoutError;
-use rustc_span::{Span, Symbol};
+use rustc_span::{DUMMY_SP, Span, Symbol};
 
 use super::CompileTimeMachine;
 use crate::errors::{self, FrameNote};
@@ -164,36 +164,30 @@ pub fn get_span_and_frames<'tcx>(
 /// This will use the `mk` function for adding more information to the error.
 /// You can use it to add a stacktrace of current execution according to
 /// `get_span_and_frames` or just give context on where the const eval error happened.
-pub(super) fn report<'tcx, C, F>(
+pub(super) fn report<'tcx>(
     ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
     error: InterpErrorKind<'tcx>,
-    span: Span,
-    get_span_and_frames: C,
-    mk: F,
-) -> ErrorHandled
-where
-    C: FnOnce() -> (Span, Vec<FrameNote>),
-    F: FnOnce(&mut Diag<'_>, Span, Vec<FrameNote>),
-{
+    mk: impl FnOnce(&mut Diag<'_>, Span, Vec<FrameNote>),
+) -> ErrorHandled {
     let tcx = ecx.tcx.tcx;
     // Special handling for certain errors
     match error {
         // Don't emit a new diagnostic for these errors, they are already reported elsewhere or
         // should remain silent.
-        err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span),
+        err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, DUMMY_SP),
         err_inval!(Layout(LayoutError::TooGeneric(_))) | err_inval!(TooGeneric) => {
-            ErrorHandled::TooGeneric(span)
+            ErrorHandled::TooGeneric(DUMMY_SP)
         }
         err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
             // This can occur in infallible promoteds e.g. when a non-existent type or field is
             // encountered.
-            ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), span)
+            ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), DUMMY_SP)
         }
         // Report remaining errors.
         _ => {
-            let (our_span, frames) = get_span_and_frames();
-            let span = span.substitute_dummy(our_span);
-            let mut err = tcx.dcx().struct_span_err(our_span, error.to_string());
+            let (span, frames) = super::get_span_and_frames(ecx.tcx, ecx.stack());
+            let mut err = tcx.dcx().struct_span_err(span, error.to_string());
+            err.code(E0080);
             if matches!(
                 error,
                 InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError {

filename: compiler/rustc_const_eval/src/const_eval/eval_queries.rs
patch: @@ -2,7 +2,6 @@ use std::sync::atomic::Ordering::Relaxed;
 
 use either::{Left, Right};
 use rustc_abi::{self as abi, BackendRepr};
-use rustc_errors::{E0080, msg};
 use rustc_hir::def::DefKind;
 use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo, ReportedErrorInfo};
 use rustc_middle::mir::{self, ConstAlloc, ConstValue};
@@ -11,8 +10,8 @@ use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::{bug, throw_inval};
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument, trace};
 
 use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
@@ -458,32 +457,20 @@ fn report_eval_error<'tcx>(
     let (error, backtrace) = error.into_parts();
     backtrace.print_backtrace();
 
-    super::report(
-        ecx,
-        error,
-        DUMMY_SP,
-        || super::get_span_and_frames(ecx.tcx, ecx.stack()),
-        |diag, span, frames| {
-            let num_frames = frames.len();
-            // FIXME(oli-obk): figure out how to use structured diagnostics again.
-            diag.code(E0080);
-            diag.span_label(
-                span,
-                msg!(
-                    "evaluation of `{$instance}` failed {$num_frames ->
-                        [0] here
-                        *[other] inside this call
-                    }"
-                ),
-            );
-            for frame in frames {
-                diag.subdiagnostic(frame);
-            }
-            // Add after the frame rendering above, as it adds its own `instance` args.
-            diag.arg("instance", with_no_trimmed_paths!(cid.instance.to_string()));
-            diag.arg("num_frames", num_frames);
-        },
-    )
+    super::report(ecx, error, |diag, span, frames| {
+        let num_frames = frames.len();
+        diag.span_label(
+            span,
+            format!(
+                "evaluation of `{instance}` failed {where_}",
+                instance = with_no_trimmed_paths!(cid.instance.to_string()),
+                where_ = if num_frames == 0 { "here" } else { "inside this call" },
+            ),
+        );
+        for frame in frames {
+            diag.subdiagnostic(frame);
+        }
+    })
 }
 
 #[inline(never)]
@@ -506,20 +493,10 @@ fn report_validation_error<'tcx>(
     let raw_bytes =
         errors::RawBytesNote { size: info.size.bytes(), align: info.align.bytes(), bytes };
 
-    crate::const_eval::report(
-        ecx,
-        error,
-        DUMMY_SP,
-        || crate::const_eval::get_span_and_frames(ecx.tcx, ecx.stack()),
-        move |diag, span, frames| {
-            // FIXME(oli-obk): figure out how to use structured diagnostics again.
-            diag.code(E0080);
-            diag.span_label(span, "it is undefined behavior to use this value");
-            diag.note("the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.");
-            for frame in frames {
-                diag.subdiagnostic(frame);
-            }
-            diag.subdiagnostic(raw_bytes);
-        },
-    )
+    crate::const_eval::report(ecx, error, move |diag, span, frames| {
+        diag.span_label(span, "it is undefined behavior to use this value");
+        diag.note("the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.");
+        assert!(frames.is_empty()); // we just report validation errors for the final const here
+        diag.subdiagnostic(raw_bytes);
+    })
 }