diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index d39a7e8a19250..d6b6a516e8652 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -8,8 +8,9 @@ use rustc_span::source_map::Spanned; use rustc_span::{ErrorGuaranteed, Span, Symbol}; use super::InterpCx; -use crate::errors::{self, FrameNote, ReportErrorExt}; +use crate::errors::{self, FrameNote}; use crate::interpret::{ErrorHandled, InterpError, InterpErrorInfo, Machine, MachineStopType}; +use crate::InterpErrorExt; /// The CTFE machine has some custom error kinds. #[derive(Clone, Debug)] @@ -166,13 +167,13 @@ where let (our_span, frames) = get_span_and_frames(); let span = span.unwrap_or(our_span); let err = mk(span, frames); + let interp_err = InterpErrorExt { err: error, span, tcx }; + let mut err = tcx.sess.create_err(err); - let msg = error.diagnostic_message(); - error.add_args(&tcx.sess.parse_sess.span_diagnostic, &mut err); + err.subdiagnostic(interp_err); // Use *our* span to label the interp error - err.span_label(our_span, msg); ErrorHandled::Reported(err.emit().into()) } } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 4362cae7ed746..7e0c42db084de 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -1,14 +1,15 @@ use rustc_errors::{ - DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, - IntoDiagnostic, + AddToDiagnostic, Diagnostic, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, Handler, + IntoDiagnostic, IntoDiagnosticArg, SubdiagnosticMessage, }; use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::interpret::{ - CheckInAllocMsg, ExpectedKind, InterpError, InvalidMetaKind, InvalidProgramInfo, PointerKind, - ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, + CheckInAllocMsg, ExpectedKind, InterpError, InvalidMetaKind, InvalidProgramInfo, + MachineStopType, PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, + ValidationErrorInfo, }; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{Ty, TyCtxt}; use rustc_span::Span; use rustc_target::abi::call::AdjustForForeignAbiError; use rustc_target::abi::{Size, WrappingRange}; @@ -437,29 +438,22 @@ pub struct UndefinedBehavior { pub raw_bytes: RawBytesNote, } -pub trait ReportErrorExt { - /// Returns the diagnostic message for this error. - fn diagnostic_message(&self) -> DiagnosticMessage; - fn add_args( - self, - handler: &Handler, - builder: &mut DiagnosticBuilder<'_, G>, - ); - - fn debug(self) -> String - where - Self: Sized, - { - ty::tls::with(move |tcx| { - let mut builder = tcx.sess.struct_allow(DiagnosticMessage::Str(String::new().into())); - let handler = &tcx.sess.parse_sess.span_diagnostic; - let message = self.diagnostic_message(); - self.add_args(handler, &mut builder); - let s = handler.eagerly_translate_to_string(message, builder.args()); - builder.cancel(); - s - }) - } +/// args: eagerly_translate_with_args!( +/// handler: &Handler, +/// msg: DiagnosticMessage, +/// key: str, +/// value: impl IntoDiagnosticArg, +/// ) +macro_rules! eagerly_translate_with_args { + ($handler:expr,$msg:expr$(,$key:expr,$value:expr)*$(,)?) => { + $handler.eagerly_translate_to_string( + $msg, + [ + $(($key.into(), $value.into_diagnostic_arg()),)* + ].iter() + .map(|(a, b)| (a, b)) + ) + }; } fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String { @@ -476,236 +470,318 @@ fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String { handler.eagerly_translate_to_string(msg, [].into_iter()) } -impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { - fn diagnostic_message(&self) -> DiagnosticMessage { +struct UndefinedBehaviorInfoExt<'tcx> { + err: UndefinedBehaviorInfo<'tcx>, + span: Span, + tcx: TyCtxt<'tcx>, +} + +impl UndefinedBehaviorInfoExt<'_> { + fn eagerly_translate(self) -> String { use crate::fluent_generated::*; use UndefinedBehaviorInfo::*; - match self { - Ub(msg) => msg.clone().into(), - Unreachable => const_eval_unreachable, - BoundsCheckFailed { .. } => const_eval_bounds_check_failed, - DivisionByZero => const_eval_division_by_zero, - RemainderByZero => const_eval_remainder_by_zero, - DivisionOverflow => const_eval_division_overflow, - RemainderOverflow => const_eval_remainder_overflow, - PointerArithOverflow => const_eval_pointer_arithmetic_overflow, - InvalidMeta(InvalidMetaKind::SliceTooBig) => const_eval_invalid_meta_slice, - InvalidMeta(InvalidMetaKind::TooBig) => const_eval_invalid_meta, - UnterminatedCString(_) => const_eval_unterminated_c_string, - PointerUseAfterFree(_, _) => const_eval_pointer_use_after_free, - PointerOutOfBounds { ptr_size: Size::ZERO, .. } => const_eval_zst_pointer_out_of_bounds, - PointerOutOfBounds { .. } => const_eval_pointer_out_of_bounds, - DanglingIntPointer(0, _) => const_eval_dangling_null_pointer, - DanglingIntPointer(_, _) => const_eval_dangling_int_pointer, - AlignmentCheckFailed { .. } => const_eval_alignment_check_failed, - WriteToReadOnly(_) => const_eval_write_to_read_only, - DerefFunctionPointer(_) => const_eval_deref_function_pointer, - DerefVTablePointer(_) => const_eval_deref_vtable_pointer, - InvalidBool(_) => const_eval_invalid_bool, - InvalidChar(_) => const_eval_invalid_char, - InvalidTag(_) => const_eval_invalid_tag, - InvalidFunctionPointer(_) => const_eval_invalid_function_pointer, - InvalidVTablePointer(_) => const_eval_invalid_vtable_pointer, - InvalidStr(_) => const_eval_invalid_str, - InvalidUninitBytes(None) => const_eval_invalid_uninit_bytes_unknown, - InvalidUninitBytes(Some(_)) => const_eval_invalid_uninit_bytes, - DeadLocal => const_eval_dead_local, - ScalarSizeMismatch(_) => const_eval_scalar_size_mismatch, - UninhabitedEnumVariantWritten(_) => const_eval_uninhabited_enum_variant_written, - UninhabitedEnumVariantRead(_) => const_eval_uninhabited_enum_variant_read, - ValidationError(e) => e.diagnostic_message(), - Custom(x) => (x.msg)(), - } - } - fn add_args( - self, - handler: &Handler, - builder: &mut DiagnosticBuilder<'_, G>, - ) { - use UndefinedBehaviorInfo::*; - match self { - Ub(_) - | Unreachable - | DivisionByZero - | RemainderByZero - | DivisionOverflow - | RemainderOverflow - | PointerArithOverflow - | InvalidMeta(InvalidMetaKind::SliceTooBig) - | InvalidMeta(InvalidMetaKind::TooBig) - | InvalidUninitBytes(None) - | DeadLocal - | UninhabitedEnumVariantWritten(_) - | UninhabitedEnumVariantRead(_) => {} + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + + match self.err { + #[allow(rustc::untranslatable_diagnostic)] + Ub(str) => { + eagerly_translate_with_args!(handler, str.clone().into(),) + } + Unreachable => { + eagerly_translate_with_args!(handler, const_eval_unreachable,) + } BoundsCheckFailed { len, index } => { - builder.set_arg("len", len); - builder.set_arg("index", index); + eagerly_translate_with_args!( + handler, + const_eval_bounds_check_failed, + "len", + len, + "index", + index, + ) + } + DivisionByZero => { + eagerly_translate_with_args!(handler, const_eval_division_by_zero,) + } + RemainderByZero => { + eagerly_translate_with_args!(handler, const_eval_remainder_by_zero,) + } + DivisionOverflow => { + eagerly_translate_with_args!(handler, const_eval_division_overflow,) } - UnterminatedCString(ptr) | InvalidFunctionPointer(ptr) | InvalidVTablePointer(ptr) => { - builder.set_arg("pointer", ptr); + RemainderOverflow => { + eagerly_translate_with_args!(handler, const_eval_remainder_overflow,) + } + PointerArithOverflow => { + eagerly_translate_with_args!(handler, const_eval_pointer_arithmetic_overflow,) + } + InvalidMeta(InvalidMetaKind::SliceTooBig) => { + eagerly_translate_with_args!(handler, const_eval_invalid_meta_slice,) + } + InvalidMeta(InvalidMetaKind::TooBig) => { + eagerly_translate_with_args!(handler, const_eval_invalid_meta,) + } + UnterminatedCString(ptr) => { + eagerly_translate_with_args!( + handler, + const_eval_unterminated_c_string, + "pointer", + ptr, + ) } PointerUseAfterFree(alloc_id, msg) => { - builder - .set_arg("alloc_id", alloc_id) - .set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); + eagerly_translate_with_args!( + handler, + const_eval_pointer_use_after_free, + "alloc_id", + alloc_id, + "bad_pointer_message", + bad_pointer_message(msg, handler) + ) } PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => { - builder - .set_arg("alloc_id", alloc_id) - .set_arg("alloc_size", alloc_size.bytes()) - .set_arg("ptr_offset", ptr_offset) - .set_arg("ptr_size", ptr_size.bytes()) - .set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); + let diagnostic_message = if ptr_size == Size::ZERO { + const_eval_zst_pointer_out_of_bounds + } else { + const_eval_pointer_out_of_bounds + }; + + eagerly_translate_with_args!( + handler, + diagnostic_message, + "alloc_id", + alloc_id, + "alloc_size", + alloc_size.bytes(), + "ptr_offset", + ptr_offset, + "ptr_size", + ptr_size.bytes(), + "bad_pointer_message", + bad_pointer_message(msg, &self.tcx.sess.parse_sess.span_diagnostic), + ) } DanglingIntPointer(ptr, msg) => { + let diagnostic_message = if ptr == 0 { + const_eval_dangling_null_pointer + } else { + const_eval_dangling_int_pointer + }; + + let mut args = vec![( + "bad_pointer_message".into(), + bad_pointer_message(msg, &self.tcx.sess.parse_sess.span_diagnostic) + .into_diagnostic_arg(), + )]; + if ptr != 0 { - builder.set_arg("pointer", format!("{ptr:#x}[noalloc]")); + args.push(( + "pointer".into(), + format!("{ptr:#x}[noalloc]").into_diagnostic_arg(), + )); } - builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); + handler.eagerly_translate_to_string( + diagnostic_message, + args.iter().map(|(a, b)| (a, b)), + ) } AlignmentCheckFailed { required, has } => { - builder.set_arg("required", required.bytes()); - builder.set_arg("has", has.bytes()); + eagerly_translate_with_args!( + handler, + const_eval_alignment_check_failed, + "required", + required.bytes(), + "has", + has.bytes(), + ) + } + WriteToReadOnly(alloc) => { + eagerly_translate_with_args!( + handler, + const_eval_write_to_read_only, + "allocation", + alloc, + ) } - WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) => { - builder.set_arg("allocation", alloc); + DerefFunctionPointer(alloc) => { + eagerly_translate_with_args!( + handler, + const_eval_deref_function_pointer, + "allocation", + alloc, + ) + } + DerefVTablePointer(alloc) => { + eagerly_translate_with_args!( + handler, + const_eval_deref_vtable_pointer, + "allocation", + alloc, + ) } InvalidBool(b) => { - builder.set_arg("value", format!("{b:02x}")); + eagerly_translate_with_args!( + handler, + const_eval_invalid_bool, + "value", + format!("{b:02x}"), + ) } InvalidChar(c) => { - builder.set_arg("value", format!("{c:08x}")); + eagerly_translate_with_args!( + handler, + const_eval_invalid_char, + "value", + format!("{c:08x}"), + ) } InvalidTag(tag) => { - builder.set_arg("tag", format!("{tag:x}")); + eagerly_translate_with_args!( + handler, + const_eval_invalid_tag, + "tag", + format!("{tag:x}"), + ) + } + InvalidFunctionPointer(ptr) => { + eagerly_translate_with_args!( + handler, + const_eval_invalid_function_pointer, + "pointer", + ptr, + ) + } + InvalidVTablePointer(ptr) => { + eagerly_translate_with_args!( + handler, + const_eval_invalid_vtable_pointer, + "pointer", + ptr, + ) } InvalidStr(err) => { - builder.set_arg("err", format!("{err}")); + eagerly_translate_with_args!( + handler, + const_eval_invalid_str, + "err", + format!("{err}"), + ) + } + InvalidUninitBytes(None) => { + eagerly_translate_with_args!(handler, const_eval_invalid_uninit_bytes_unknown,) } InvalidUninitBytes(Some((alloc, info))) => { - builder.set_arg("alloc", alloc); - builder.set_arg("access", info.access); - builder.set_arg("uninit", info.bad); + eagerly_translate_with_args!( + handler, + const_eval_invalid_uninit_bytes, + "alloc", + alloc, + "access", + info.access, + "uninit", + info.bad, + ) + } + DeadLocal => { + eagerly_translate_with_args!(handler, const_eval_dead_local,) } ScalarSizeMismatch(info) => { - builder.set_arg("target_size", info.target_size); - builder.set_arg("data_size", info.data_size); + eagerly_translate_with_args!( + handler, + const_eval_scalar_size_mismatch, + "target_size", + info.target_size, + "data_size", + info.data_size, + ) } - ValidationError(e) => e.add_args(handler, builder), - Custom(custom) => { - (custom.add_args)(&mut |name, value| { - builder.set_arg(name, value); - }); + UninhabitedEnumVariantWritten(_) => { + eagerly_translate_with_args!(handler, const_eval_uninhabited_enum_variant_written,) } - } - } -} - -impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { - fn diagnostic_message(&self) -> DiagnosticMessage { - use crate::fluent_generated::*; - use rustc_middle::mir::interpret::ValidationErrorKind::*; - match self.kind { - PtrToUninhabited { ptr_kind: PointerKind::Box, .. } => { - const_eval_validation_box_to_uninhabited - } - PtrToUninhabited { ptr_kind: PointerKind::Ref, .. } => { - const_eval_validation_ref_to_uninhabited - } - - PtrToStatic { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_static, - PtrToStatic { ptr_kind: PointerKind::Ref } => const_eval_validation_ref_to_static, - - PtrToMut { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_mut, - PtrToMut { ptr_kind: PointerKind::Ref } => const_eval_validation_ref_to_mut, - - PointerAsInt { .. } => const_eval_validation_pointer_as_int, - PartialPointer => const_eval_validation_partial_pointer, - MutableRefInConst => const_eval_validation_mutable_ref_in_const, - NullFnPtr => const_eval_validation_null_fn_ptr, - NeverVal => const_eval_validation_never_val, - NullablePtrOutOfRange { .. } => const_eval_validation_nullable_ptr_out_of_range, - PtrOutOfRange { .. } => const_eval_validation_ptr_out_of_range, - OutOfRange { .. } => const_eval_validation_out_of_range, - UnsafeCell => const_eval_validation_unsafe_cell, - UninhabitedVal { .. } => const_eval_validation_uninhabited_val, - InvalidEnumTag { .. } => const_eval_validation_invalid_enum_tag, - UninhabitedEnumVariant => const_eval_validation_uninhabited_enum_variant, - Uninit { .. } => const_eval_validation_uninit, - InvalidVTablePtr { .. } => const_eval_validation_invalid_vtable_ptr, - InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => { - const_eval_validation_invalid_box_slice_meta + UninhabitedEnumVariantRead(_) => { + eagerly_translate_with_args!(handler, const_eval_uninhabited_enum_variant_read,) } - InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => { - const_eval_validation_invalid_ref_slice_meta + ValidationError(err) => { + ValidationErrorInfoExt { err, tcx: self.tcx, span: self.span }.eagerly_translate() } + Custom(x) => { + let mut args = Vec::new(); - InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => { - const_eval_validation_invalid_box_meta - } - InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => { - const_eval_validation_invalid_ref_meta - } - UnalignedPtr { ptr_kind: PointerKind::Ref, .. } => const_eval_validation_unaligned_ref, - UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box, + (x.add_args)(&mut |name, value| { + args.push((name, value)); + }); - NullPtr { ptr_kind: PointerKind::Box } => const_eval_validation_null_box, - NullPtr { ptr_kind: PointerKind::Ref } => const_eval_validation_null_ref, - DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => { - const_eval_validation_dangling_box_no_provenance - } - DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, .. } => { - const_eval_validation_dangling_ref_no_provenance - } - DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => { - const_eval_validation_dangling_box_out_of_bounds - } - DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => { - const_eval_validation_dangling_ref_out_of_bounds - } - DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => { - const_eval_validation_dangling_box_use_after_free - } - DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => { - const_eval_validation_dangling_ref_use_after_free + handler.eagerly_translate_to_string( + (x.msg.clone())(), + args.iter().map(|(a, b)| (a, b)), + ) } - InvalidBool { .. } => const_eval_validation_invalid_bool, - InvalidChar { .. } => const_eval_validation_invalid_char, - InvalidFnPtr { .. } => const_eval_validation_invalid_fn_ptr, } } +} - fn add_args(self, handler: &Handler, err: &mut DiagnosticBuilder<'_, G>) { - use crate::fluent_generated as fluent; - use rustc_middle::mir::interpret::ValidationErrorKind::*; +impl AddToDiagnostic for UndefinedBehaviorInfoExt<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + use UndefinedBehaviorInfo::*; - if let PointerAsInt { .. } | PartialPointer = self.kind { - err.help(fluent::const_eval_ptr_as_bytes_1); - err.help(fluent::const_eval_ptr_as_bytes_2); + match self.err { + Ub(_) + | Unreachable + | BoundsCheckFailed { .. } + | DivisionByZero + | RemainderByZero + | DivisionOverflow + | RemainderOverflow + | PointerArithOverflow + | InvalidMeta(_) + | UnterminatedCString(_) + | PointerUseAfterFree(_, _) + | PointerOutOfBounds { .. } + | DanglingIntPointer(_, _) + | AlignmentCheckFailed { .. } + | WriteToReadOnly(_) + | DerefFunctionPointer(_) + | DerefVTablePointer(_) + | InvalidBool(_) + | InvalidChar(_) + | InvalidTag(_) + | InvalidFunctionPointer(_) + | InvalidVTablePointer(_) + | InvalidStr(_) + | InvalidUninitBytes(_) + | DeadLocal + | ScalarSizeMismatch(_) + | UninhabitedEnumVariantWritten(_) + | UninhabitedEnumVariantRead(_) + | Custom(_) => { + #[allow(rustc::untranslatable_diagnostic)] + diag.span_label(self.span, self.eagerly_translate()); + } + ValidationError(err) => { + ValidationErrorInfoExt { err, tcx: self.tcx, span: self.span } + .add_to_diagnostic(diag); + } } + } +} - let message = if let Some(path) = self.path { - handler.eagerly_translate_to_string( - fluent::const_eval_validation_front_matter_invalid_value_with_path, - [("path".into(), DiagnosticArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)), - ) - } else { - handler.eagerly_translate_to_string( - fluent::const_eval_validation_front_matter_invalid_value, - [].into_iter(), - ) - }; +struct ValidationErrorInfoExt<'tcx> { + err: ValidationErrorInfo<'tcx>, + span: Span, + tcx: TyCtxt<'tcx>, +} - err.set_arg("front_matter", message); +impl ValidationErrorInfoExt<'_> { + fn eagerly_translate(self) -> String { + use crate::fluent_generated::*; + use crate::interpret::ValidationErrorKind::*; - fn add_range_arg( - r: WrappingRange, - max_hi: u128, - handler: &Handler, - err: &mut DiagnosticBuilder<'_, G>, - ) { + fn get_range_arg(r: WrappingRange, max_hi: u128, handler: &Handler) -> String { let WrappingRange { start: lo, end: hi } = r; assert!(hi <= max_hi); let msg = if lo > hi { @@ -727,16 +803,80 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { ("hi".into(), DiagnosticArgValue::Str(hi.to_string().into())), ]; let args = args.iter().map(|(a, b)| (a, b)); - let message = handler.eagerly_translate_to_string(msg, args); - err.set_arg("in_range", message); + handler.eagerly_translate_to_string(msg, args) } - match self.kind { - PtrToUninhabited { ty, .. } | UninhabitedVal { ty } => { - err.set_arg("ty", ty); + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + + use crate::fluent_generated as fluent; + + let front_matter = if let Some(path) = self.err.path { + handler.eagerly_translate_to_string( + fluent::const_eval_validation_front_matter_invalid_value_with_path, + [("path".into(), DiagnosticArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)), + ) + } else { + handler.eagerly_translate_to_string( + fluent::const_eval_validation_front_matter_invalid_value, + [].into_iter(), + ) + }; + + match self.err.kind { + PtrToUninhabited { ptr_kind: PointerKind::Box, ty } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_box_to_uninhabited, + "ty", + ty.to_string(), + "front_matter", + front_matter, + ) } - PointerAsInt { expected } | Uninit { expected } => { - let msg = match expected { + PtrToUninhabited { ptr_kind: PointerKind::Ref, ty } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_ref_to_uninhabited, + "ty", + ty.to_string(), + "front_matter", + front_matter, + ) + } + PtrToStatic { ptr_kind: PointerKind::Box, .. } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_box_to_static, + "front_matter", + front_matter, + ) + } + PtrToStatic { ptr_kind: PointerKind::Ref, .. } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_ref_to_static, + "front_matter", + front_matter, + ) + } + PtrToMut { ptr_kind: PointerKind::Box, .. } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_box_to_mut, + "front_matter", + front_matter, + ) + } + PtrToMut { ptr_kind: PointerKind::Ref, .. } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_ref_to_mut, + "front_matter", + front_matter, + ) + } + PointerAsInt { expected } => { + let expected = match expected { ExpectedKind::Reference => fluent::const_eval_validation_expected_ref, ExpectedKind::Box => fluent::const_eval_validation_expected_box, ExpectedKind::RawPtr => fluent::const_eval_validation_expected_raw_ptr, @@ -749,158 +889,620 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { ExpectedKind::EnumTag => fluent::const_eval_validation_expected_enum_tag, ExpectedKind::Str => fluent::const_eval_validation_expected_str, }; - let msg = handler.eagerly_translate_to_string(msg, [].into_iter()); - err.set_arg("expected", msg); + let expected = handler.eagerly_translate_to_string(expected, [].into_iter()); + + eagerly_translate_with_args!( + handler, + const_eval_validation_pointer_as_int, + "expected", + expected, + "front_matter", + front_matter, + ) + } + PartialPointer => { + eagerly_translate_with_args!( + handler, + const_eval_validation_partial_pointer, + "front_matter", + front_matter, + ) + } + MutableRefInConst => { + eagerly_translate_with_args!( + handler, + const_eval_validation_mutable_ref_in_const, + "front_matter", + front_matter, + ) + } + NullFnPtr => { + eagerly_translate_with_args!( + handler, + const_eval_validation_null_fn_ptr, + "front_matter", + front_matter, + ) } - InvalidEnumTag { value } - | InvalidVTablePtr { value } - | InvalidBool { value } - | InvalidChar { value } - | InvalidFnPtr { value } => { - err.set_arg("value", value); + NeverVal => { + eagerly_translate_with_args!( + handler, + const_eval_validation_never_val, + "front_matter", + front_matter, + ) } - NullablePtrOutOfRange { range, max_value } | PtrOutOfRange { range, max_value } => { - add_range_arg(range, max_value, handler, err) + NullablePtrOutOfRange { range, max_value } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_nullable_ptr_out_of_range, + "front_matter", + front_matter, + "in_range", + get_range_arg(range, max_value, &handler), + ) + } + PtrOutOfRange { range, max_value } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_ptr_out_of_range, + "front_matter", + front_matter, + "in_range", + get_range_arg(range, max_value, &handler), + ) } OutOfRange { range, max_value, value } => { - err.set_arg("value", value); - add_range_arg(range, max_value, handler, err); + eagerly_translate_with_args!( + handler, + const_eval_validation_out_of_range, + "front_matter", + front_matter, + "in_range", + get_range_arg(range, max_value, &handler), + "value", + value, + ) + } + UnsafeCell => { + eagerly_translate_with_args!( + handler, + const_eval_validation_unsafe_cell, + "front_matter", + front_matter, + ) + } + UninhabitedVal { ty } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_uninhabited_val, + "front_matter", + front_matter, + "ty", + ty.to_string(), + ) + } + InvalidEnumTag { value } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_enum_tag, + "front_matter", + front_matter, + "value", + value, + ) + } + UninhabitedEnumVariant => { + eagerly_translate_with_args!( + handler, + const_eval_validation_uninhabited_enum_variant, + "front_matter", + front_matter, + ) + } + Uninit { expected } => { + let expected = match expected { + ExpectedKind::Reference => fluent::const_eval_validation_expected_ref, + ExpectedKind::Box => fluent::const_eval_validation_expected_box, + ExpectedKind::RawPtr => fluent::const_eval_validation_expected_raw_ptr, + ExpectedKind::InitScalar => fluent::const_eval_validation_expected_init_scalar, + ExpectedKind::Bool => fluent::const_eval_validation_expected_bool, + ExpectedKind::Char => fluent::const_eval_validation_expected_char, + ExpectedKind::Float => fluent::const_eval_validation_expected_float, + ExpectedKind::Int => fluent::const_eval_validation_expected_int, + ExpectedKind::FnPtr => fluent::const_eval_validation_expected_fn_ptr, + ExpectedKind::EnumTag => fluent::const_eval_validation_expected_enum_tag, + ExpectedKind::Str => fluent::const_eval_validation_expected_str, + }; + let expected = handler.eagerly_translate_to_string(expected, [].into_iter()); + + eagerly_translate_with_args!( + handler, + const_eval_validation_uninit, + "expected", + expected, + "front_matter", + front_matter, + ) } - UnalignedPtr { required_bytes, found_bytes, .. } => { - err.set_arg("required_bytes", required_bytes); - err.set_arg("found_bytes", found_bytes); + InvalidVTablePtr { value } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_vtable_ptr, + "front_matter", + front_matter, + "value", + value, + ) } - DanglingPtrNoProvenance { pointer, .. } => { - err.set_arg("pointer", pointer); + InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_box_slice_meta, + "front_matter", + front_matter, + ) + } + InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_ref_slice_meta, + "front_matter", + front_matter, + ) + } + InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_box_meta, + "front_matter", + front_matter, + ) + } + InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_ref_meta, + "front_matter", + front_matter, + ) } - NullPtr { .. } + UnalignedPtr { ptr_kind: PointerKind::Ref, required_bytes, found_bytes } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_unaligned_ref, + "front_matter", + front_matter, + "required_bytes", + required_bytes.to_string(), + "found_bytes", + found_bytes.to_string(), + ) + } + UnalignedPtr { ptr_kind: PointerKind::Box, required_bytes, found_bytes } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_unaligned_box, + "front_matter", + front_matter, + "required_bytes", + required_bytes.to_string(), + "found_bytes", + found_bytes.to_string(), + ) + } + + NullPtr { ptr_kind: PointerKind::Box } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_null_box, + "front_matter", + front_matter, + ) + } + NullPtr { ptr_kind: PointerKind::Ref } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_null_ref, + "front_matter", + front_matter, + ) + } + DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, pointer } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_box_no_provenance, + "front_matter", + front_matter, + "pointer", + pointer, + ) + } + DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, pointer } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_ref_no_provenance, + "front_matter", + front_matter, + "pointer", + pointer, + ) + } + DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_box_out_of_bounds, + "front_matter", + front_matter, + ) + } + DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_ref_out_of_bounds, + "front_matter", + front_matter, + ) + } + DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_box_use_after_free, + "front_matter", + front_matter, + ) + } + DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_ref_use_after_free, + "front_matter", + front_matter, + ) + } + InvalidBool { value } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_bool, + "front_matter", + front_matter, + "value", + value, + ) + } + InvalidChar { value } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_char, + "front_matter", + front_matter, + "value", + value, + ) + } + InvalidFnPtr { value } => { + eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_fn_ptr, + "front_matter", + front_matter, + "value", + value, + ) + } + } + } +} + +impl AddToDiagnostic for ValidationErrorInfoExt<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + use crate::fluent_generated::*; + use crate::interpret::ValidationErrorKind::*; + + match self.err.kind { + PtrToUninhabited { .. } | PtrToStatic { .. } | PtrToMut { .. } | MutableRefInConst | NullFnPtr | NeverVal + | NullablePtrOutOfRange { .. } + | PtrOutOfRange { .. } + | OutOfRange { .. } | UnsafeCell + | UninhabitedVal { .. } + | InvalidEnumTag { .. } + | UninhabitedEnumVariant + | Uninit { .. } + | InvalidVTablePtr { .. } | InvalidMetaSliceTooLarge { .. } | InvalidMetaTooLarge { .. } - | DanglingPtrUseAfterFree { .. } + | UnalignedPtr { .. } + | NullPtr { .. } + | DanglingPtrNoProvenance { .. } | DanglingPtrOutOfBounds { .. } - | UninhabitedEnumVariant - | PartialPointer => {} + | DanglingPtrUseAfterFree { .. } + | InvalidBool { .. } + | InvalidChar { .. } + | InvalidFnPtr { .. } => {} + PointerAsInt { .. } | PartialPointer => { + diag.help(const_eval_ptr_as_bytes_1); + diag.help(const_eval_ptr_as_bytes_2); + } } + + #[allow(rustc::untranslatable_diagnostic)] + diag.span_label(self.span, self.eagerly_translate()); } } -impl ReportErrorExt for UnsupportedOpInfo { - fn diagnostic_message(&self) -> DiagnosticMessage { - use crate::fluent_generated::*; - match self { - UnsupportedOpInfo::Unsupported(s) => s.clone().into(), - UnsupportedOpInfo::OverwritePartialPointer(_) => const_eval_partial_pointer_overwrite, - UnsupportedOpInfo::ReadPartialPointer(_) => const_eval_partial_pointer_copy, - UnsupportedOpInfo::ReadPointerAsInt(_) => const_eval_read_pointer_as_int, - UnsupportedOpInfo::ThreadLocalStatic(_) => const_eval_thread_local_static, - UnsupportedOpInfo::ReadExternStatic(_) => const_eval_read_extern_static, - } - } - fn add_args(self, _: &Handler, builder: &mut DiagnosticBuilder<'_, G>) { - use crate::fluent_generated::*; +struct UnsupportedOpExt<'tcx> { + err: UnsupportedOpInfo, + span: Span, + tcx: TyCtxt<'tcx>, +} +impl UnsupportedOpExt<'_> { + fn eagerly_translate(self) -> String { + use crate::fluent_generated::*; use UnsupportedOpInfo::*; - if let ReadPointerAsInt(_) | OverwritePartialPointer(_) | ReadPartialPointer(_) = self { - builder.help(const_eval_ptr_as_bytes_1); - builder.help(const_eval_ptr_as_bytes_2); - } - match self { + + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + + match self.err { + Unsupported(s) => { + eagerly_translate_with_args!( + handler, + >::into(s.clone()), + ) + } + OverwritePartialPointer(ptr) => { + eagerly_translate_with_args!( + handler, + const_eval_partial_pointer_overwrite, + "ptr", + ptr, + ) + } + ReadPartialPointer(ptr) => { + eagerly_translate_with_args!(handler, const_eval_partial_pointer_copy, "ptr", ptr,) + } // `ReadPointerAsInt(Some(info))` is never printed anyway, it only serves as an error to // be further processed by validity checking which then turns it into something nice to // print. So it's not worth the effort of having diagnostics that can print the `info`. - Unsupported(_) | ReadPointerAsInt(_) => {} - OverwritePartialPointer(ptr) | ReadPartialPointer(ptr) => { - builder.set_arg("ptr", ptr); + ReadPointerAsInt(_) => { + eagerly_translate_with_args!(handler, const_eval_read_pointer_as_int,) } - ThreadLocalStatic(did) | ReadExternStatic(did) => { - builder.set_arg("did", format!("{did:?}")); + ThreadLocalStatic(did) => { + eagerly_translate_with_args!( + handler, + const_eval_thread_local_static, + "did", + format!("{did:?}"), + ) + } + ReadExternStatic(did) => { + eagerly_translate_with_args!( + handler, + const_eval_read_extern_static, + "did", + format!("{did:?}"), + ) + } + } + } +} + +impl AddToDiagnostic for UnsupportedOpExt<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + use crate::fluent_generated::*; + use UnsupportedOpInfo::*; + + match self.err { + Unsupported(_) | ThreadLocalStatic(_) | ReadExternStatic(_) => {} + OverwritePartialPointer(_) | ReadPartialPointer(_) | ReadPointerAsInt(_) => { + diag.help(const_eval_ptr_as_bytes_1); + diag.help(const_eval_ptr_as_bytes_2); } } + + #[allow(rustc::untranslatable_diagnostic)] + diag.span_label(self.span, self.eagerly_translate()); } } -impl<'tcx> ReportErrorExt for InterpError<'tcx> { - fn diagnostic_message(&self) -> DiagnosticMessage { - match self { - InterpError::UndefinedBehavior(ub) => ub.diagnostic_message(), - InterpError::Unsupported(e) => e.diagnostic_message(), - InterpError::InvalidProgram(e) => e.diagnostic_message(), - InterpError::ResourceExhaustion(e) => e.diagnostic_message(), - InterpError::MachineStop(e) => e.diagnostic_message(), +pub struct InterpErrorExt<'tcx> { + pub err: InterpError<'tcx>, + pub span: Span, + pub tcx: TyCtxt<'tcx>, +} + +impl AddToDiagnostic for InterpErrorExt<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + match self.err { + InterpError::UndefinedBehavior(ub) => { + UndefinedBehaviorInfoExt { err: ub, span: self.span, tcx: self.tcx } + .add_to_diagnostic(diag); + } + InterpError::Unsupported(e) => { + UnsupportedOpExt { err: e, span: self.span, tcx: self.tcx }.add_to_diagnostic(diag); + } + InterpError::InvalidProgram(e) => { + InvalidProgramInfoExt { err: e, span: self.span, tcx: self.tcx } + .add_to_diagnostic(diag); + } + InterpError::ResourceExhaustion(e) => { + ResourceExhaustionExt { err: e, span: self.span, tcx: self.tcx } + .add_to_diagnostic(diag); + } + InterpError::MachineStop(e) => { + MachineStopExt { err: e, span: self.span, tcx: self.tcx }.add_to_diagnostic(diag); + } } } - fn add_args( - self, - handler: &Handler, - builder: &mut DiagnosticBuilder<'_, G>, - ) { - match self { - InterpError::UndefinedBehavior(ub) => ub.add_args(handler, builder), - InterpError::Unsupported(e) => e.add_args(handler, builder), - InterpError::InvalidProgram(e) => e.add_args(handler, builder), - InterpError::ResourceExhaustion(e) => e.add_args(handler, builder), - InterpError::MachineStop(e) => e.add_args(&mut |name, value| { - builder.set_arg(name, value); - }), +} + +impl InterpErrorExt<'_> { + /// Translate InterpError to String. + /// + /// This should not be used for any user-facing diagnostics, + /// only for debug messages in the docs. + pub fn to_string(self) -> String { + // FIXME(victor-timofei): implement this + match self.err { + InterpError::UndefinedBehavior(ub) => { + UndefinedBehaviorInfoExt { err: ub, span: self.span, tcx: self.tcx } + .eagerly_translate() + } + InterpError::Unsupported(e) => { + UnsupportedOpExt { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() + } + InterpError::InvalidProgram(e) => { + InvalidProgramInfoExt { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() + } + InterpError::ResourceExhaustion(e) => { + ResourceExhaustionExt { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() + } + InterpError::MachineStop(e) => { + MachineStopExt { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() + } } } } -impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { - fn diagnostic_message(&self) -> DiagnosticMessage { +struct MachineStopExt<'tcx> { + err: Box, + span: Span, + tcx: TyCtxt<'tcx>, +} + +impl MachineStopExt<'_> { + fn eagerly_translate(self) -> String { + let mut args = Vec::new(); + let msg = self.err.diagnostic_message().clone(); + self.err.add_args(&mut |name, value| { + args.push((name, value)); + }); + + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + + handler.eagerly_translate_to_string(msg, args.iter().map(|(a, b)| (a, b))) + } +} + +impl AddToDiagnostic for MachineStopExt<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + #[allow(rustc::untranslatable_diagnostic)] + diag.span_label(self.span, self.eagerly_translate()); + } +} + +struct InvalidProgramInfoExt<'tcx> { + err: InvalidProgramInfo<'tcx>, + span: Span, + tcx: TyCtxt<'tcx>, +} + +impl InvalidProgramInfoExt<'_> { + fn eagerly_translate(self) -> String { use crate::fluent_generated::*; - match self { - InvalidProgramInfo::TooGeneric => const_eval_too_generic, - InvalidProgramInfo::AlreadyReported(_) => const_eval_already_reported, - InvalidProgramInfo::Layout(e) => e.diagnostic_message(), - InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => { - rustc_middle::error::middle_adjust_for_foreign_abi_error + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + + match self.err { + InvalidProgramInfo::TooGeneric => { + eagerly_translate_with_args!(handler, const_eval_too_generic,) + } + InvalidProgramInfo::AlreadyReported(_) => { + eagerly_translate_with_args!(handler, const_eval_already_reported,) + } + InvalidProgramInfo::Layout(e) => { + let builder: DiagnosticBuilder<'_, ()> = + e.into_diagnostic().into_diagnostic(handler); + + let msg = + handler.eagerly_translate_to_string(e.diagnostic_message(), builder.args()); + builder.cancel(); + + msg + } + InvalidProgramInfo::FnAbiAdjustForForeignAbi( + AdjustForForeignAbiError::Unsupported { arch, abi }, + ) => { + eagerly_translate_with_args!( + handler, + rustc_middle::error::middle_adjust_for_foreign_abi_error, + "arch", + arch.to_ident_string(), + "abi", + abi.name(), + ) } InvalidProgramInfo::ConstPropNonsense => { panic!("We had const-prop nonsense, this should never be printed") } } } - fn add_args( - self, - handler: &Handler, - builder: &mut DiagnosticBuilder<'_, G>, - ) { - match self { +} + +impl AddToDiagnostic for InvalidProgramInfoExt<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + match self.err { InvalidProgramInfo::TooGeneric | InvalidProgramInfo::AlreadyReported(_) - | InvalidProgramInfo::ConstPropNonsense => {} - InvalidProgramInfo::Layout(e) => { - let diag: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(handler); - for (name, val) in diag.args() { - builder.set_arg(name.clone(), val.clone()); - } - diag.cancel(); - } - InvalidProgramInfo::FnAbiAdjustForForeignAbi( - AdjustForForeignAbiError::Unsupported { arch, abi }, - ) => { - builder.set_arg("arch", arch); - builder.set_arg("abi", abi.name()); + | InvalidProgramInfo::Layout(_) + | InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => {} + InvalidProgramInfo::ConstPropNonsense => { + panic!("We had const-prop nonsense, this should never be printed") } } + + #[allow(rustc::untranslatable_diagnostic)] + diag.span_label(self.span, self.eagerly_translate()); } } -impl ReportErrorExt for ResourceExhaustionInfo { - fn diagnostic_message(&self) -> DiagnosticMessage { +struct ResourceExhaustionExt<'tcx> { + err: ResourceExhaustionInfo, + span: Span, + tcx: TyCtxt<'tcx>, +} + +impl ResourceExhaustionExt<'_> { + fn eagerly_translate(self) -> String { + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + use crate::fluent_generated::*; - match self { + let msg = match self.err { ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached, ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted, ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full, - } + }; + + eagerly_translate_with_args!(handler, msg) + } +} + +impl AddToDiagnostic for ResourceExhaustionExt<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + #[allow(rustc::untranslatable_diagnostic)] + diag.span_label(self.span, self.eagerly_translate()); } - fn add_args(self, _: &Handler, _: &mut DiagnosticBuilder<'_, G>) {} } diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index c126f749bf328..de47453f33222 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -34,7 +34,7 @@ pub mod interpret; pub mod transform; pub mod util; -pub use errors::ReportErrorExt; +pub use errors::InterpErrorExt; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 7529ed8186bd7..eed2262accaed 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -4,7 +4,7 @@ use either::Right; use rustc_const_eval::const_eval::CheckAlignment; -use rustc_const_eval::ReportErrorExt; +use rustc_const_eval::InterpErrorExt; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; @@ -385,7 +385,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { op } Err(e) => { - trace!("get_const failed: {:?}", e.into_kind().debug()); + let err = InterpErrorExt { + err: e.into_kind(), + span: self.ecx.cur_span(), + tcx: *self.ecx.tcx, + }; + trace!("get_const failed: {}", err.to_string()); return None; } }; diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index ac07c25763bac..c5427399717af 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -9,7 +9,7 @@ use rustc_const_eval::interpret::Immediate; use rustc_const_eval::interpret::{ self, InterpCx, InterpResult, LocalValue, MemoryKind, OpTy, Scalar, StackPopCleanup, }; -use rustc_const_eval::ReportErrorExt; +use rustc_const_eval::InterpErrorExt; use rustc_hir::def::DefKind; use rustc_hir::HirId; use rustc_index::bit_set::BitSet; @@ -233,7 +233,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { op } Err(e) => { - trace!("get_const failed: {:?}", e.into_kind().debug()); + let err = InterpErrorExt { + err: e.into_kind(), + span: self.ecx.cur_span(), + tcx: *self.ecx.tcx, + }; + trace!("get_const failed: {}", err.to_string()); return None; } }; diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 6bd4be91e516b..0b28bc6d16cd7 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -3,7 +3,7 @@ use std::num::NonZeroU64; use log::trace; -use rustc_const_eval::ReportErrorExt; +use rustc_const_eval::InterpErrorExt; use rustc_errors::DiagnosticMessage; use rustc_span::{source_map::DUMMY_SP, SpanData, Symbol}; use rustc_target::abi::{Align, Size}; @@ -336,15 +336,11 @@ pub fn report_error<'tcx, 'mir>( // FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the // label and arguments from the InterpError. - let e = { - let handler = &ecx.tcx.sess.parse_sess.span_diagnostic; - let mut diag = ecx.tcx.sess.struct_allow(""); - let msg = e.diagnostic_message(); - e.add_args(handler, &mut diag); - let s = handler.eagerly_translate_to_string(msg, diag.args()); - diag.cancel(); - s - }; + let e = InterpErrorExt{ + err: e, + span: ecx.cur_span(), + tcx: *ecx.tcx, + }.to_string(); msg.insert(0, e);