From 6c2223299830128a5a01ac05de857cdd91e2ddb0 Mon Sep 17 00:00:00 2001 From: Victor Timofei Date: Mon, 3 Jul 2023 20:37:36 +0300 Subject: [PATCH 1/5] const-eval: implement IntoDiagnostic for errors --- .../rustc_const_eval/src/const_eval/error.rs | 16 +- compiler/rustc_const_eval/src/errors.rs | 759 +++++++++++------- compiler/rustc_const_eval/src/lib.rs | 2 +- .../rustc_mir_transform/src/const_prop.rs | 4 +- .../src/const_prop_lint.rs | 4 +- src/tools/miri/src/diagnostics.rs | 12 +- 6 files changed, 477 insertions(+), 320 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index d39a7e8a19250..870e6a8439ec5 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)] @@ -125,7 +126,7 @@ pub(super) fn report<'tcx, C, F, E>( error: InterpError<'tcx>, span: Option, get_span_and_frames: C, - mk: F, + _mk: F, ) -> ErrorHandled where C: FnOnce() -> (Span, Vec), @@ -165,14 +166,15 @@ where // Report as hard error. let (our_span, frames) = get_span_and_frames(); let span = span.unwrap_or(our_span); - let err = mk(span, frames); - let mut err = tcx.sess.create_err(err); - let msg = error.diagnostic_message(); - error.add_args(&tcx.sess.parse_sess.span_diagnostic, &mut err); + let handler = &tcx.sess.parse_sess.span_diagnostic; + let mut err = handler.create_err(Spanned { span, node: InterpErrorExt(error) }); + + for frame in frames { + err.eager_subdiagnostic(handler, frame); + } // 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..6c16bc6e68827 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -5,11 +5,12 @@ use rustc_errors::{ 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_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::abi::call::AdjustForForeignAbiError; use rustc_target::abi::{Size, WrappingRange}; @@ -437,31 +438,6 @@ 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 - }) - } -} - fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String { use crate::fluent_generated::*; @@ -476,229 +452,201 @@ 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 { - 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)(), - } - } +pub struct UndefinedBehaviorInfoExt<'a>(UndefinedBehaviorInfo<'a>); - fn add_args( - self, - handler: &Handler, - builder: &mut DiagnosticBuilder<'_, G>, - ) { +impl IntoDiagnostic<'_> for UndefinedBehaviorInfoExt<'_> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + use crate::fluent_generated::*; use UndefinedBehaviorInfo::*; - match self { - Ub(_) - | Unreachable - | DivisionByZero - | RemainderByZero - | DivisionOverflow - | RemainderOverflow - | PointerArithOverflow - | InvalidMeta(InvalidMetaKind::SliceTooBig) - | InvalidMeta(InvalidMetaKind::TooBig) - | InvalidUninitBytes(None) - | DeadLocal - | UninhabitedEnumVariantWritten(_) - | UninhabitedEnumVariantRead(_) => {} + match self.0 { + #[allow(rustc::untranslatable_diagnostic)] + Ub(str) => handler.struct_diagnostic(str.clone()), + Unreachable => handler.struct_diagnostic(const_eval_unreachable), BoundsCheckFailed { len, index } => { + let mut builder = handler.struct_diagnostic(const_eval_bounds_check_failed); + builder.set_arg("len", len); builder.set_arg("index", index); + + builder + } + DivisionByZero => handler.struct_diagnostic(const_eval_division_by_zero), + RemainderByZero => handler.struct_diagnostic(const_eval_remainder_by_zero), + DivisionOverflow => handler.struct_diagnostic(const_eval_division_overflow), + RemainderOverflow => handler.struct_diagnostic(const_eval_remainder_overflow), + PointerArithOverflow => { + handler.struct_diagnostic(const_eval_pointer_arithmetic_overflow) + } + InvalidMeta(InvalidMetaKind::SliceTooBig) => { + handler.struct_diagnostic(const_eval_invalid_meta_slice) } - UnterminatedCString(ptr) | InvalidFunctionPointer(ptr) | InvalidVTablePointer(ptr) => { + InvalidMeta(InvalidMetaKind::TooBig) => { + handler.struct_diagnostic(const_eval_invalid_meta) + } + UnterminatedCString(ptr) => { + let mut builder = handler.struct_diagnostic(const_eval_unterminated_c_string); + builder.set_arg("pointer", ptr); + + builder } PointerUseAfterFree(alloc_id, msg) => { + let mut builder = handler.struct_diagnostic(const_eval_pointer_use_after_free); + + builder.set_arg("allocation", alloc_id); + builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); + builder - .set_arg("alloc_id", alloc_id) - .set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); } PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => { + let mut builder = if ptr_size == Size::ZERO { + handler.struct_diagnostic(const_eval_zst_pointer_out_of_bounds) + } else { + handler.struct_diagnostic(const_eval_pointer_out_of_bounds) + }; + 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)); + + builder } DanglingIntPointer(ptr, msg) => { + let mut builder = if ptr == 0 { + handler.struct_diagnostic(const_eval_dangling_null_pointer) + } else { + handler.struct_diagnostic(const_eval_dangling_int_pointer) + }; + if ptr != 0 { builder.set_arg("pointer", format!("{ptr:#x}[noalloc]")); } builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); + + builder } AlignmentCheckFailed { required, has } => { + let mut builder = handler.struct_diagnostic(const_eval_alignment_check_failed); + builder.set_arg("required", required.bytes()); builder.set_arg("has", has.bytes()); + + builder + } + WriteToReadOnly(alloc) => { + let mut builder = handler.struct_diagnostic(const_eval_write_to_read_only); + + builder.set_arg("allocation", alloc); + + builder } - WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) => { + DerefFunctionPointer(alloc) => { + let mut builder = handler.struct_diagnostic(const_eval_deref_function_pointer); + builder.set_arg("allocation", alloc); + + builder + } + DerefVTablePointer(alloc) => { + let mut builder = handler.struct_diagnostic(const_eval_deref_vtable_pointer); + + builder.set_arg("allocation", alloc); + + builder } InvalidBool(b) => { + let mut builder = handler.struct_diagnostic(const_eval_invalid_bool); + builder.set_arg("value", format!("{b:02x}")); + + builder } InvalidChar(c) => { + let mut builder = handler.struct_diagnostic(const_eval_invalid_char); + builder.set_arg("value", format!("{c:08x}")); + + builder } InvalidTag(tag) => { + let mut builder = handler.struct_diagnostic(const_eval_invalid_tag); + builder.set_arg("tag", format!("{tag:x}")); + + builder + } + InvalidFunctionPointer(ptr) => { + let mut builder = handler.struct_diagnostic(const_eval_invalid_function_pointer); + + builder.set_arg("pointer", ptr); + + builder + } + InvalidVTablePointer(ptr) => { + let mut builder = handler.struct_diagnostic(const_eval_invalid_vtable_pointer); + + builder.set_arg("pointer", ptr); + + builder } InvalidStr(err) => { + let mut builder = handler.struct_diagnostic(const_eval_invalid_str); + builder.set_arg("err", format!("{err}")); + + builder + } + InvalidUninitBytes(None) => { + handler.struct_diagnostic(const_eval_invalid_uninit_bytes_unknown) } InvalidUninitBytes(Some((alloc, info))) => { + let mut builder = handler.struct_diagnostic(const_eval_invalid_uninit_bytes); + builder.set_arg("alloc", alloc); builder.set_arg("access", info.access); builder.set_arg("uninit", info.bad); + + builder } + DeadLocal => handler.struct_diagnostic(const_eval_dead_local), ScalarSizeMismatch(info) => { + let mut builder = handler.struct_diagnostic(const_eval_scalar_size_mismatch); + builder.set_arg("target_size", info.target_size); builder.set_arg("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); - }); - } - } - } -} -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 + builder } - InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => { - const_eval_validation_invalid_ref_slice_meta + UninhabitedEnumVariantWritten(_) => { + handler.struct_diagnostic(const_eval_uninhabited_enum_variant_written) } - - InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => { - const_eval_validation_invalid_box_meta - } - InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => { - const_eval_validation_invalid_ref_meta + UninhabitedEnumVariantRead(_) => { + handler.struct_diagnostic(const_eval_uninhabited_enum_variant_read) } - UnalignedPtr { ptr_kind: PointerKind::Ref, .. } => const_eval_validation_unaligned_ref, - UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box, + ValidationError(e) => ValidationErrorInfoExt(e).into_diagnostic(handler), + Custom(x) => { + let mut builder = handler.struct_diagnostic((x.msg.clone())()); - 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 + (x.add_args)(&mut |name, value| { + builder.set_arg(name, value); + }); + + builder } - 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::*; +pub struct ValidationErrorInfoExt<'tcx>(ValidationErrorInfo<'tcx>); - if let PointerAsInt { .. } | PartialPointer = self.kind { - err.help(fluent::const_eval_ptr_as_bytes_1); - err.help(fluent::const_eval_ptr_as_bytes_2); - } - - 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(), - ) - }; - - err.set_arg("front_matter", message); +impl IntoDiagnostic<'_> for ValidationErrorInfoExt<'_> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + use crate::fluent_generated::*; + use crate::interpret::ValidationErrorKind::*; fn add_range_arg( r: WrappingRange, @@ -731,11 +679,39 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { err.set_arg("in_range", message); } - match self.kind { - PtrToUninhabited { ty, .. } | UninhabitedVal { ty } => { - err.set_arg("ty", ty); + let mut builder = match self.0.kind { + PtrToUninhabited { ptr_kind: PointerKind::Box, ty } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_box_to_uninhabited); + + builder.set_arg("ty", ty); + + builder } - PointerAsInt { expected } | Uninit { expected } => { + PtrToUninhabited { ptr_kind: PointerKind::Ref, ty } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_ref_to_uninhabited); + + builder.set_arg("ty", ty); + + builder + } + PtrToStatic { ptr_kind: PointerKind::Box, .. } => { + handler.struct_diagnostic(const_eval_validation_box_to_static) + } + PtrToStatic { ptr_kind: PointerKind::Ref, .. } => { + handler.struct_diagnostic(const_eval_validation_ref_to_static) + } + PtrToMut { ptr_kind: PointerKind::Box, .. } => { + handler.struct_diagnostic(const_eval_validation_box_to_mut) + } + PtrToMut { ptr_kind: PointerKind::Ref, .. } => { + handler.struct_diagnostic(const_eval_validation_ref_to_mut) + } + PointerAsInt { expected } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_pointer_as_int); + + builder.help(const_eval_ptr_as_bytes_1); + builder.help(const_eval_ptr_as_bytes_2); + let msg = match expected { ExpectedKind::Reference => fluent::const_eval_validation_expected_ref, ExpectedKind::Box => fluent::const_eval_validation_expected_box, @@ -750,157 +726,344 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { ExpectedKind::Str => fluent::const_eval_validation_expected_str, }; let msg = handler.eagerly_translate_to_string(msg, [].into_iter()); - err.set_arg("expected", msg); + builder.set_arg("expected", msg); + + builder } - InvalidEnumTag { value } - | InvalidVTablePtr { value } - | InvalidBool { value } - | InvalidChar { value } - | InvalidFnPtr { value } => { - err.set_arg("value", value); + PartialPointer => { + let mut builder = handler.struct_diagnostic(const_eval_validation_partial_pointer); + + builder.help(const_eval_ptr_as_bytes_1); + builder.help(const_eval_ptr_as_bytes_2); + + builder + } + MutableRefInConst => handler.struct_diagnostic(const_eval_validation_mutable_ref_in_const), + NullFnPtr => handler.struct_diagnostic(const_eval_validation_null_fn_ptr), + NeverVal => handler.struct_diagnostic(const_eval_validation_never_val), + NullablePtrOutOfRange { range, max_value } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_nullable_ptr_out_of_range); + + add_range_arg(range, max_value, handler, &mut builder); + + builder } - NullablePtrOutOfRange { range, max_value } | PtrOutOfRange { range, max_value } => { - add_range_arg(range, max_value, handler, err) + PtrOutOfRange { range, max_value } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_ptr_out_of_range); + + add_range_arg(range, max_value, handler, &mut builder); + + builder } OutOfRange { range, max_value, value } => { - err.set_arg("value", value); - add_range_arg(range, max_value, handler, err); - } - UnalignedPtr { required_bytes, found_bytes, .. } => { - err.set_arg("required_bytes", required_bytes); - err.set_arg("found_bytes", found_bytes); - } - DanglingPtrNoProvenance { pointer, .. } => { - err.set_arg("pointer", pointer); - } - NullPtr { .. } - | PtrToStatic { .. } - | PtrToMut { .. } - | MutableRefInConst - | NullFnPtr - | NeverVal - | UnsafeCell - | InvalidMetaSliceTooLarge { .. } - | InvalidMetaTooLarge { .. } - | DanglingPtrUseAfterFree { .. } - | DanglingPtrOutOfBounds { .. } - | UninhabitedEnumVariant - | PartialPointer => {} - } + let mut builder = handler.struct_diagnostic(const_eval_validation_out_of_range); + + builder.set_arg("value", value); + add_range_arg(range, max_value, handler, &mut builder); + + builder + } + UnsafeCell => handler.struct_diagnostic(const_eval_validation_unsafe_cell), + UninhabitedVal { ty } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_uninhabited_val); + + builder.set_arg("ty", ty); + + builder + } + InvalidEnumTag { value } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_enum_tag); + + builder.set_arg("value", value); + + builder + } + UninhabitedEnumVariant => { + handler.struct_diagnostic(const_eval_validation_uninhabited_enum_variant) + } + Uninit { expected } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_uninit); + + let msg = 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 msg = handler.eagerly_translate_to_string(msg, [].into_iter()); + builder.set_arg("expected", msg); + + builder + } + InvalidVTablePtr { value } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_vtable_ptr); + + builder.set_arg("value", value); + + builder + } + InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => { + handler.struct_diagnostic(const_eval_validation_invalid_box_slice_meta) + } + InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => { + handler.struct_diagnostic(const_eval_validation_invalid_ref_slice_meta) + } + InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => { + handler.struct_diagnostic(const_eval_validation_invalid_box_meta) + } + InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => { + handler.struct_diagnostic(const_eval_validation_invalid_ref_meta) + } + UnalignedPtr { ptr_kind: PointerKind::Ref, required_bytes, found_bytes } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_unaligned_ref); + + builder.set_arg("required_bytes", required_bytes); + builder.set_arg("found_bytes", found_bytes); + + builder + } + UnalignedPtr { ptr_kind: PointerKind::Box, required_bytes, found_bytes } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_unaligned_box); + + builder.set_arg("required_bytes", required_bytes); + builder.set_arg("found_bytes", found_bytes); + + builder + } + + NullPtr { ptr_kind: PointerKind::Box } => { + handler.struct_diagnostic(const_eval_validation_null_box) + } + NullPtr { ptr_kind: PointerKind::Ref } => { + handler.struct_diagnostic(const_eval_validation_null_ref) + } + DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, pointer } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_dangling_box_no_provenance); + + builder.set_arg("pointer", pointer); + + builder + } + DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, pointer } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_dangling_ref_no_provenance); + + builder.set_arg("pointer", pointer); + + builder + } + DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => { + handler.struct_diagnostic(const_eval_validation_dangling_box_out_of_bounds) + } + DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => { + handler.struct_diagnostic(const_eval_validation_dangling_ref_out_of_bounds) + } + DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => { + handler.struct_diagnostic(const_eval_validation_dangling_box_use_after_free) + } + DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => { + handler.struct_diagnostic(const_eval_validation_dangling_ref_use_after_free) + } + InvalidBool { value } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_bool); + + builder.set_arg("value", value); + + builder + } + InvalidChar { value } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_char); + + builder.set_arg("value", value); + + builder + } + InvalidFnPtr { value } => { + let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_fn_ptr); + + builder.set_arg("value", value); + + builder + } + }; + + use crate::fluent_generated as fluent; + + let message = if let Some(path) = self.0.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()) + }; + + builder.set_arg("front_matter", message); + + builder } } -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::*; +pub struct UnsupportedExt(UnsupportedOpInfo); +impl IntoDiagnostic<'_> for UnsupportedExt { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + 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 { + match self.0 { + Unsupported(s) => handler.struct_diagnostic(>::into(s.clone())), + OverwritePartialPointer(ptr) => { + let mut builder = handler.struct_diagnostic(const_eval_partial_pointer_overwrite); + + builder.help(const_eval_ptr_as_bytes_1); + builder.help(const_eval_ptr_as_bytes_2); + builder.set_arg("ptr", ptr); + + builder + } + ReadPartialPointer(ptr) => { + let mut builder = handler.struct_diagnostic(const_eval_partial_pointer_copy); + + builder.help(const_eval_ptr_as_bytes_1); + builder.help(const_eval_ptr_as_bytes_2); + builder.set_arg("ptr", ptr); + + builder + } // `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(_) => { + let mut builder = handler.struct_diagnostic(const_eval_read_pointer_as_int); + + builder.help(const_eval_ptr_as_bytes_1); + builder.help(const_eval_ptr_as_bytes_2); + + builder } - ThreadLocalStatic(did) | ReadExternStatic(did) => { + ThreadLocalStatic(did) => { + let mut builder = handler.struct_diagnostic(const_eval_thread_local_static); + builder.set_arg("did", format!("{did:?}")); + + builder + } + ReadExternStatic(did) => { + let mut builder = handler.struct_diagnostic(const_eval_read_extern_static); + + builder.set_arg("did", format!("{did:?}")); + + builder } } } } -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<'a>(pub InterpError<'a>); + +impl IntoDiagnostic<'_> for InterpErrorExt<'_> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + match self.0 { + InterpError::UndefinedBehavior(ub) => { + UndefinedBehaviorInfoExt(ub).into_diagnostic(handler) + } + InterpError::Unsupported(e) => UnsupportedExt(e).into_diagnostic(handler), + InterpError::InvalidProgram(e) => InvalidProgramInfoExt(e).into_diagnostic(handler), + InterpError::ResourceExhaustion(e) => ResourceExhaustionExt(e).into_diagnostic(handler), + InterpError::MachineStop(e) => MachineStopExt(e).into_diagnostic(handler), } } - 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 { + ty::tls::with(move |tcx| { + let handler = &tcx.sess.parse_sess.span_diagnostic; + let builder = self.into_diagnostic(handler); + let s = handler.eagerly_translate_to_string( + builder.message.first().unwrap().0.to_owned(), + builder.args(), + ); + builder.cancel(); + s + }) + } +} + +pub struct MachineStopExt(Box); + +impl IntoDiagnostic<'_> for MachineStopExt { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut builder = handler.struct_diagnostic(self.0.diagnostic_message().clone()); + + self.0.add_args(&mut |name, value| { + builder.set_arg(name, value); + }); + builder } } -impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { - fn diagnostic_message(&self) -> DiagnosticMessage { +pub struct InvalidProgramInfoExt<'a>(InvalidProgramInfo<'a>); + +impl IntoDiagnostic<'_> for InvalidProgramInfoExt<'_> { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { 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 + match self.0 { + InvalidProgramInfo::TooGeneric => handler.struct_diagnostic(const_eval_too_generic), + InvalidProgramInfo::AlreadyReported(_) => { + handler.struct_diagnostic(const_eval_already_reported) } - 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 { - InvalidProgramInfo::TooGeneric - | InvalidProgramInfo::AlreadyReported(_) - | InvalidProgramInfo::ConstPropNonsense => {} InvalidProgramInfo::Layout(e) => { + let mut builder = handler.struct_diagnostic(e.diagnostic_message()); + let diag: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(handler); for (name, val) in diag.args() { builder.set_arg(name.clone(), val.clone()); } diag.cancel(); + + builder } InvalidProgramInfo::FnAbiAdjustForForeignAbi( AdjustForForeignAbiError::Unsupported { arch, abi }, ) => { + let mut builder = handler + .struct_diagnostic(rustc_middle::error::middle_adjust_for_foreign_abi_error); + builder.set_arg("arch", arch); builder.set_arg("abi", abi.name()); + + builder + } + InvalidProgramInfo::ConstPropNonsense => { + panic!("We had const-prop nonsense, this should never be printed") } } } } -impl ReportErrorExt for ResourceExhaustionInfo { - fn diagnostic_message(&self) -> DiagnosticMessage { +pub struct ResourceExhaustionExt(ResourceExhaustionInfo); + +impl IntoDiagnostic<'_> for ResourceExhaustionExt { + fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { use crate::fluent_generated::*; - match self { + let msg = match self.0 { ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached, ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted, ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full, - } + }; + handler.struct_diagnostic(msg) } - 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..232d12d2a55d7 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,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { op } Err(e) => { - trace!("get_const failed: {:?}", e.into_kind().debug()); + trace!("get_const failed: {}", InterpErrorExt(e.into_kind()).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..ae0f3be90a3b1 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,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { op } Err(e) => { - trace!("get_const failed: {:?}", e.into_kind().debug()); + trace!("get_const failed: {}", InterpErrorExt(e.into_kind()).to_string()); return None; } }; diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 6bd4be91e516b..6eba84fa06736 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,7 @@ 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(e).to_string(); msg.insert(0, e); From 70a4247f57269c47362f390f3ac1c945d79059f2 Mon Sep 17 00:00:00 2001 From: Victor Timofei Date: Thu, 10 Aug 2023 14:52:15 +0300 Subject: [PATCH 2/5] Implement AddToDiagnostic for newtypes --- .../rustc_const_eval/src/const_eval/error.rs | 13 +- compiler/rustc_const_eval/src/errors.rs | 1061 ++++++++++++++++- compiler/rustc_const_eval/src/lib.rs | 2 +- .../rustc_mir_transform/src/const_prop.rs | 9 +- .../src/const_prop_lint.rs | 9 +- src/tools/miri/src/diagnostics.rs | 8 +- 6 files changed, 1077 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 870e6a8439ec5..41ffcbc4f7b82 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -10,7 +10,7 @@ use rustc_span::{ErrorGuaranteed, Span, Symbol}; use super::InterpCx; use crate::errors::{self, FrameNote}; use crate::interpret::{ErrorHandled, InterpError, InterpErrorInfo, Machine, MachineStopType}; -use crate::InterpErrorExt; +use crate::InterpErrorExt2; /// The CTFE machine has some custom error kinds. #[derive(Clone, Debug)] @@ -126,7 +126,7 @@ pub(super) fn report<'tcx, C, F, E>( error: InterpError<'tcx>, span: Option, get_span_and_frames: C, - _mk: F, + mk: F, ) -> ErrorHandled where C: FnOnce() -> (Span, Vec), @@ -166,13 +166,12 @@ where // Report as hard error. let (our_span, frames) = get_span_and_frames(); let span = span.unwrap_or(our_span); + let err = mk(span, frames); + let interp_err = InterpErrorExt2 { err: error, span, tcx }; - let handler = &tcx.sess.parse_sess.span_diagnostic; - let mut err = handler.create_err(Spanned { span, node: InterpErrorExt(error) }); + let mut err = tcx.sess.create_err(err); - for frame in frames { - err.eager_subdiagnostic(handler, frame); - } + err.subdiagnostic(interp_err); // Use *our* span to label the interp error ErrorHandled::Reported(err.emit().into()) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 6c16bc6e68827..91cba269bec5c 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -1,6 +1,6 @@ use rustc_errors::{ - DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, - IntoDiagnostic, + AddToDiagnostic, Diagnostic, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, + EmissionGuarantee, Handler, IntoDiagnostic, IntoDiagnosticArg, SubdiagnosticMessage, }; use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -9,7 +9,7 @@ use rustc_middle::mir::interpret::{ MachineStopType, PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, }; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::abi::call::AdjustForForeignAbiError; use rustc_target::abi::{Size, WrappingRange}; @@ -438,6 +438,24 @@ pub struct UndefinedBehavior { pub raw_bytes: RawBytesNote, } +/// 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 { use crate::fluent_generated::*; @@ -454,6 +472,285 @@ fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String { pub struct UndefinedBehaviorInfoExt<'a>(UndefinedBehaviorInfo<'a>); +pub struct UndefinedBehaviorInfoExt2<'tcx> { + err: UndefinedBehaviorInfo<'tcx>, + span: Span, + tcx: TyCtxt<'tcx>, +} + +impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + use crate::fluent_generated::*; + use UndefinedBehaviorInfo::*; + + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + + // Allow untranslatable_diagnostic lint, since we + // eagerly translate our subdiagnostics by using the + // eagerly_translate_with_args!() macro. + #[allow(rustc::untranslatable_diagnostic)] + match self.err { + #[allow(rustc::untranslatable_diagnostic)] + Ub(str) => { + diag.span_label(self.span, str.clone()); + } + Unreachable => { + diag.span_label(self.span, const_eval_unreachable); + } + BoundsCheckFailed { len, index } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_bounds_check_failed, + "len", + len, + "index", + index, + ); + diag.span_label(self.span, msg); + } + DivisionByZero => { + diag.span_label(self.span, const_eval_division_by_zero); + } + RemainderByZero => { + diag.span_label(self.span, const_eval_remainder_by_zero); + } + DivisionOverflow => { + diag.span_label(self.span, const_eval_division_overflow); + } + RemainderOverflow => { + diag.span_label(self.span, const_eval_remainder_overflow); + } + PointerArithOverflow => { + diag.span_label(self.span, const_eval_pointer_arithmetic_overflow); + } + InvalidMeta(InvalidMetaKind::SliceTooBig) => { + diag.span_label(self.span, const_eval_invalid_meta_slice); + } + InvalidMeta(InvalidMetaKind::TooBig) => { + diag.span_label(self.span, const_eval_invalid_meta); + } + UnterminatedCString(ptr) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_unterminated_c_string, + "pointer", + ptr, + ); + diag.span_label(self.span, msg); + } + PointerUseAfterFree(alloc_id, msg) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_pointer_use_after_free, + "alloc_id", + alloc_id, + "bad_pointer_message", + bad_pointer_message(msg, handler) + ); + diag.span_label(self.span, msg); + } + PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => { + let diagnostic_message = if ptr_size == Size::ZERO { + const_eval_zst_pointer_out_of_bounds + } else { + const_eval_pointer_out_of_bounds + }; + + let translated_msg = 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), + ); + diag.span_label(self.span, translated_msg); + } + 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 { + args.push(( + "pointer".into(), + format!("{ptr:#x}[noalloc]").into_diagnostic_arg(), + )); + } + + let msg = handler.eagerly_translate_to_string( + diagnostic_message, + args.iter().map(|(a, b)| (a, b)), + ); + diag.span_label(self.span, msg); + } + AlignmentCheckFailed { required, has } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_alignment_check_failed, + "required", + required.bytes(), + "has", + has.bytes(), + ); + diag.span_label(self.span, msg); + } + WriteToReadOnly(alloc) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_write_to_read_only, + "allocation", + alloc, + ); + diag.span_label(self.span, msg); + } + DerefFunctionPointer(alloc) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_deref_function_pointer, + "allocation", + alloc, + ); + diag.span_label(self.span, msg); + } + DerefVTablePointer(alloc) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_deref_vtable_pointer, + "allocation", + alloc, + ); + diag.span_label(self.span, msg); + } + InvalidBool(b) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_invalid_bool, + "value", + format!("{b:02x}"), + ); + diag.span_label(self.span, msg); + } + InvalidChar(c) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_invalid_char, + "value", + format!("{c:08x}"), + ); + diag.span_label(self.span, msg); + } + InvalidTag(tag) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_invalid_tag, + "value", + format!("{tag:x}"), + ); + diag.span_label(self.span, msg); + } + InvalidFunctionPointer(ptr) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_invalid_function_pointer, + "pointer", + ptr, + ); + diag.span_label(self.span, msg); + } + InvalidVTablePointer(ptr) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_invalid_vtable_pointer, + "pointer", + ptr, + ); + diag.span_label(self.span, msg); + } + InvalidStr(err) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_invalid_str, + "err", + format!("{err}"), + ); + diag.span_label(self.span, msg); + } + InvalidUninitBytes(None) => { + diag.span_label(self.span, const_eval_invalid_uninit_bytes_unknown); + } + InvalidUninitBytes(Some((alloc, info))) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_invalid_uninit_bytes, + "alloc", + alloc, + "access", + info.access, + "uninit", + info.bad, + ); + diag.span_label(self.span, msg); + } + DeadLocal => { + diag.span_label(self.span, const_eval_dead_local); + } + ScalarSizeMismatch(info) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_scalar_size_mismatch, + "target_size", + info.target_size, + "data_size", + info.data_size, + ); + diag.span_label(self.span, msg); + } + UninhabitedEnumVariantWritten(_) => { + diag.span_label(self.span, const_eval_uninhabited_enum_variant_written); + } + UninhabitedEnumVariantRead(_) => { + diag.span_label(self.span, const_eval_uninhabited_enum_variant_read); + } + ValidationError(err) => { + ValidationErrorInfoExt2 { err, tcx: self.tcx, span: self.span } + .add_to_diagnostic(diag); + } + Custom(x) => { + let mut args = Vec::new(); + + (x.add_args)(&mut |name, value| { + args.push((name, value)); + }); + + let msg = handler.eagerly_translate_to_string( + (x.msg.clone())(), + args.iter().map(|(a, b)| (a, b)), + ); + + diag.span_label(self.span, msg); + } + } + } +} + impl IntoDiagnostic<'_> for UndefinedBehaviorInfoExt<'_> { fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { use crate::fluent_generated::*; @@ -643,6 +940,518 @@ impl IntoDiagnostic<'_> for UndefinedBehaviorInfoExt<'_> { pub struct ValidationErrorInfoExt<'tcx>(ValidationErrorInfo<'tcx>); +pub struct ValidationErrorInfoExt2<'tcx> { + err: ValidationErrorInfo<'tcx>, + span: Span, + tcx: TyCtxt<'tcx>, +} + +impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { + 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::*; + + 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 { + fluent::const_eval_range_wrapping + } else if lo == hi { + fluent::const_eval_range_singular + } else if lo == 0 { + assert!(hi < max_hi, "should not be printing if the range covers everything"); + fluent::const_eval_range_upper + } else if hi == max_hi { + assert!(lo > 0, "should not be printing if the range covers everything"); + fluent::const_eval_range_lower + } else { + fluent::const_eval_range + }; + + let args = [ + ("lo".into(), DiagnosticArgValue::Str(lo.to_string().into())), + ("hi".into(), DiagnosticArgValue::Str(hi.to_string().into())), + ]; + let args = args.iter().map(|(a, b)| (a, b)); + handler.eagerly_translate_to_string(msg, args) + } + + 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(), + ) + }; + + // Allow untranslatable_diagnostic lint, since we + // eagerly translate our subdiagnostics by using the + // eagerly_translate_with_args!() macro. + #[allow(rustc::untranslatable_diagnostic)] + match self.err.kind { + PtrToUninhabited { ptr_kind: PointerKind::Box, ty } => { + // FIXME(victor-timofei): maybe it would be a good idea to add a + // span_label_eagerly_translated!() macro + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_box_to_uninhabited, + "ty", + ty.to_string(), + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + PtrToUninhabited { ptr_kind: PointerKind::Ref, ty } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_ref_to_uninhabited, + "ty", + ty.to_string(), + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + PtrToStatic { ptr_kind: PointerKind::Box, .. } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_box_to_static, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + PtrToStatic { ptr_kind: PointerKind::Ref, .. } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_ref_to_static, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + PtrToMut { ptr_kind: PointerKind::Box, .. } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_box_to_mut, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + PtrToMut { ptr_kind: PointerKind::Ref, .. } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_ref_to_mut, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + PointerAsInt { expected } => { + diag.help(const_eval_ptr_as_bytes_1); + diag.help(const_eval_ptr_as_bytes_2); + + 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()); + + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_pointer_as_int, + "expected", + expected, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + PartialPointer => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_partial_pointer, + "front_matter", + front_matter, + ); + diag.span_label(self.span, msg); + + diag.help(const_eval_ptr_as_bytes_1); + diag.help(const_eval_ptr_as_bytes_2); + } + MutableRefInConst => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_mutable_ref_in_const, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + NullFnPtr => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_null_fn_ptr, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + NeverVal => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_never_val, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + NullablePtrOutOfRange { range, max_value } => { + let msg = 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), + ); + + diag.span_label(self.span, msg); + } + PtrOutOfRange { range, max_value } => { + let msg = 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), + ); + + diag.span_label(self.span, msg); + } + OutOfRange { range, max_value, value } => { + let msg = 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, + ); + + diag.span_label(self.span, msg); + } + UnsafeCell => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_unsafe_cell, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + UninhabitedVal { ty } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_uninhabited_val, + "front_matter", + front_matter, + "ty", + ty.to_string(), + ); + + diag.span_label(self.span, msg); + } + InvalidEnumTag { value } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_enum_tag, + "front_matter", + front_matter, + "value", + value, + ); + + diag.span_label(self.span, msg); + } + UninhabitedEnumVariant => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_uninhabited_enum_variant, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + 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()); + + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_uninit, + "expected", + expected, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + InvalidVTablePtr { value } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_vtable_ptr, + "front_matter", + front_matter, + "value", + value, + ); + + diag.span_label(self.span, msg); + } + InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_box_slice_meta, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_ref_slice_meta, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_box_meta, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_ref_meta, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + UnalignedPtr { ptr_kind: PointerKind::Ref, required_bytes, found_bytes } => { + let msg = 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(), + ); + + diag.span_label(self.span, msg); + } + UnalignedPtr { ptr_kind: PointerKind::Box, required_bytes, found_bytes } => { + let msg = 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(), + ); + + diag.span_label(self.span, msg); + } + + NullPtr { ptr_kind: PointerKind::Box } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_null_box, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + NullPtr { ptr_kind: PointerKind::Ref } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_null_ref, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, pointer } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_box_no_provenance, + "front_matter", + front_matter, + "pointer", + pointer, + ); + + diag.span_label(self.span, msg); + } + DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, pointer } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_ref_no_provenance, + "front_matter", + front_matter, + "pointer", + pointer, + ); + + diag.span_label(self.span, msg); + } + DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_box_out_of_bounds, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_ref_out_of_bounds, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_box_use_after_free, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_dangling_ref_use_after_free, + "front_matter", + front_matter, + ); + + diag.span_label(self.span, msg); + } + InvalidBool { value } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_bool, + "front_matter", + front_matter, + "value", + value, + ); + + diag.span_label(self.span, msg); + } + InvalidChar { value } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_char, + "front_matter", + front_matter, + "value", + value, + ); + + diag.span_label(self.span, msg); + } + InvalidFnPtr { value } => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_validation_invalid_fn_ptr, + "front_matter", + front_matter, + "value", + value, + ); + + diag.span_label(self.span, msg); + } + } + } +} + impl IntoDiagnostic<'_> for ValidationErrorInfoExt<'_> { fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { use crate::fluent_generated::*; @@ -681,14 +1490,16 @@ impl IntoDiagnostic<'_> for ValidationErrorInfoExt<'_> { let mut builder = match self.0.kind { PtrToUninhabited { ptr_kind: PointerKind::Box, ty } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_box_to_uninhabited); + let mut builder = + handler.struct_diagnostic(const_eval_validation_box_to_uninhabited); builder.set_arg("ty", ty); builder } PtrToUninhabited { ptr_kind: PointerKind::Ref, ty } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_ref_to_uninhabited); + let mut builder = + handler.struct_diagnostic(const_eval_validation_ref_to_uninhabited); builder.set_arg("ty", ty); @@ -738,11 +1549,14 @@ impl IntoDiagnostic<'_> for ValidationErrorInfoExt<'_> { builder } - MutableRefInConst => handler.struct_diagnostic(const_eval_validation_mutable_ref_in_const), + MutableRefInConst => { + handler.struct_diagnostic(const_eval_validation_mutable_ref_in_const) + } NullFnPtr => handler.struct_diagnostic(const_eval_validation_null_fn_ptr), NeverVal => handler.struct_diagnostic(const_eval_validation_never_val), NullablePtrOutOfRange { range, max_value } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_nullable_ptr_out_of_range); + let mut builder = + handler.struct_diagnostic(const_eval_validation_nullable_ptr_out_of_range); add_range_arg(range, max_value, handler, &mut builder); @@ -803,7 +1617,8 @@ impl IntoDiagnostic<'_> for ValidationErrorInfoExt<'_> { builder } InvalidVTablePtr { value } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_vtable_ptr); + let mut builder = + handler.struct_diagnostic(const_eval_validation_invalid_vtable_ptr); builder.set_arg("value", value); @@ -845,14 +1660,16 @@ impl IntoDiagnostic<'_> for ValidationErrorInfoExt<'_> { handler.struct_diagnostic(const_eval_validation_null_ref) } DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, pointer } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_dangling_box_no_provenance); + let mut builder = + handler.struct_diagnostic(const_eval_validation_dangling_box_no_provenance); builder.set_arg("pointer", pointer); builder } DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, pointer } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_dangling_ref_no_provenance); + let mut builder = + handler.struct_diagnostic(const_eval_validation_dangling_ref_no_provenance); builder.set_arg("pointer", pointer); @@ -901,7 +1718,10 @@ impl IntoDiagnostic<'_> for ValidationErrorInfoExt<'_> { [("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()) + handler.eagerly_translate_to_string( + fluent::const_eval_validation_front_matter_invalid_value, + [].into_iter(), + ) }; builder.set_arg("front_matter", message); @@ -967,6 +1787,129 @@ impl IntoDiagnostic<'_> for UnsupportedExt { } } +pub struct UnsupportedOpExt2<'tcx> { + err: UnsupportedOpInfo, + span: Span, + tcx: TyCtxt<'tcx>, +} + +impl AddToDiagnostic for UnsupportedOpExt2<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + use crate::fluent_generated::*; + use UnsupportedOpInfo::*; + + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + + // Allow untranslatable_diagnostic lint, since we + // eagerly translate our subdiagnostics by using the + // eagerly_translate_with_args!() macro. + #[allow(rustc::untranslatable_diagnostic)] + match self.err { + Unsupported(s) => { + diag.span_label( + self.span, + >::into(s.clone()), + ); + } + OverwritePartialPointer(ptr) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_partial_pointer_overwrite, + "ptr", + ptr, + ); + diag.span_label(self.span, msg); + + diag.help(const_eval_ptr_as_bytes_1); + diag.help(const_eval_ptr_as_bytes_2); + } + ReadPartialPointer(ptr) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_partial_pointer_copy, + "ptr", + ptr, + ); + diag.span_label(self.span, msg); + + diag.help(const_eval_ptr_as_bytes_1); + diag.help(const_eval_ptr_as_bytes_2); + } + // `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`. + ReadPointerAsInt(_) => { + diag.span_label(self.span, const_eval_read_pointer_as_int); + + diag.help(const_eval_ptr_as_bytes_1); + diag.help(const_eval_ptr_as_bytes_2); + } + ThreadLocalStatic(did) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_thread_local_static, + "did", + format!("{did:?}"), + ); + diag.span_label(self.span, msg); + } + ReadExternStatic(did) => { + let msg = eagerly_translate_with_args!( + handler, + const_eval_read_extern_static, + "did", + format!("{did:?}"), + ); + diag.span_label(self.span, msg); + } + } + } +} + +pub struct InterpErrorExt2<'tcx> { + pub err: InterpError<'tcx>, + pub span: Span, + pub tcx: TyCtxt<'tcx>, +} + +impl AddToDiagnostic for InterpErrorExt2<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + match self.err { + InterpError::UndefinedBehavior(ub) => { + UndefinedBehaviorInfoExt2 { err: ub, span: self.span, tcx: self.tcx } + .add_to_diagnostic(diag); + } + InterpError::Unsupported(e) => { + UnsupportedOpExt2 { err: e, span: self.span, tcx: self.tcx } + .add_to_diagnostic(diag); + } + InterpError::InvalidProgram(e) => { + InvalidProgramInfoExt2 { err: e, span: self.span, tcx: self.tcx } + .add_to_diagnostic(diag); + } + InterpError::ResourceExhaustion(e) => { + ResourceExhaustionExt2 { err: e, span: self.span }.add_to_diagnostic(diag); + } + InterpError::MachineStop(e) => { + MachineStopExt2 { err: e, span: self.span }.add_to_diagnostic(diag); + } + } + } +} + +impl InterpErrorExt2<'_> { + pub fn to_string(&self) -> String { + // FIXME(victor-timofei): implement this + todo!("InterpErrorExt2::to_string"); + } +} + pub struct InterpErrorExt<'a>(pub InterpError<'a>); impl IntoDiagnostic<'_> for InterpErrorExt<'_> { @@ -1002,6 +1945,24 @@ impl InterpErrorExt<'_> { } } +pub struct MachineStopExt2 { + err: Box, + span: Span, +} + +impl AddToDiagnostic for MachineStopExt2 { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + diag.span_label(self.span, self.err.diagnostic_message().clone()); + + self.err.add_args(&mut |name, value| { + diag.set_arg(name, value); + }); + } +} + pub struct MachineStopExt(Box); impl IntoDiagnostic<'_> for MachineStopExt { @@ -1015,6 +1976,64 @@ impl IntoDiagnostic<'_> for MachineStopExt { } } +pub struct InvalidProgramInfoExt2<'tcx> { + err: InvalidProgramInfo<'tcx>, + span: Span, + tcx: TyCtxt<'tcx>, +} + +impl AddToDiagnostic for InvalidProgramInfoExt2<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + use crate::fluent_generated::*; + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + + // Allow untranslatable_diagnostic lint, since we + // eagerly translate our subdiagnostics by using the + // eagerly_translate_with_args!() macro. + #[allow(rustc::untranslatable_diagnostic)] + match self.err { + InvalidProgramInfo::TooGeneric => { + diag.span_label(self.span, const_eval_too_generic); + } + InvalidProgramInfo::AlreadyReported(_) => { + diag.span_label(self.span, const_eval_already_reported); + } + InvalidProgramInfo::Layout(e) => { + let builder: DiagnosticBuilder<'_, ()> = + e.into_diagnostic().into_diagnostic(handler); + for (name, val) in builder.args() { + diag.set_arg(name.clone(), val.clone()); + } + let msg = + handler.eagerly_translate_to_string(e.diagnostic_message(), builder.args()); + builder.cancel(); + + diag.span_label(self.span, msg); + } + InvalidProgramInfo::FnAbiAdjustForForeignAbi( + AdjustForForeignAbiError::Unsupported { arch, abi }, + ) => { + let msg = eagerly_translate_with_args!( + handler, + rustc_middle::error::middle_adjust_for_foreign_abi_error, + "arch", + arch.to_ident_string(), + "abi", + abi.name(), + ); + + diag.span_label(self.span, msg); + } + InvalidProgramInfo::ConstPropNonsense => { + panic!("We had const-prop nonsense, this should never be printed") + } + } + } +} + pub struct InvalidProgramInfoExt<'a>(InvalidProgramInfo<'a>); impl IntoDiagnostic<'_> for InvalidProgramInfoExt<'_> { @@ -1054,6 +2073,26 @@ impl IntoDiagnostic<'_> for InvalidProgramInfoExt<'_> { } } +pub struct ResourceExhaustionExt2 { + err: ResourceExhaustionInfo, + span: Span, +} + +impl AddToDiagnostic for ResourceExhaustionExt2 { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + use crate::fluent_generated::*; + 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, + }; + diag.span_label(self.span, msg); + } +} + pub struct ResourceExhaustionExt(ResourceExhaustionInfo); impl IntoDiagnostic<'_> for ResourceExhaustionExt { diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index de47453f33222..6acb338ddef6e 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::InterpErrorExt; +pub use errors::InterpErrorExt2; 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 232d12d2a55d7..82a7a1aeac3ee 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::InterpErrorExt; +use rustc_const_eval::InterpErrorExt2; 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: {}", InterpErrorExt(e.into_kind()).to_string()); + let err = InterpErrorExt2 { + 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 ae0f3be90a3b1..d70cb7dc00779 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::InterpErrorExt; +use rustc_const_eval::InterpErrorExt2; 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: {}", InterpErrorExt(e.into_kind()).to_string()); + let err = InterpErrorExt2 { + 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 6eba84fa06736..16c78785dba5f 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::InterpErrorExt; +use rustc_const_eval::InterpErrorExt2; use rustc_errors::DiagnosticMessage; use rustc_span::{source_map::DUMMY_SP, SpanData, Symbol}; use rustc_target::abi::{Align, Size}; @@ -336,7 +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 = InterpErrorExt(e).to_string(); + let e = InterpErrorExt2{ + err: e, + span: ecx.cur_span(), + tcx: *ecx.tcx, + }.to_string(); msg.insert(0, e); From ee6c6f6dc646b13b4e1588553931cf47dfd012b1 Mon Sep 17 00:00:00 2001 From: Victor Timofei Date: Fri, 11 Aug 2023 19:40:58 +0300 Subject: [PATCH 3/5] Implement InterpErrorExt2::to_string --- compiler/rustc_const_eval/src/errors.rs | 664 +++++++++++++----------- 1 file changed, 347 insertions(+), 317 deletions(-) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 91cba269bec5c..00b6bf0eca531 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -478,79 +478,69 @@ pub struct UndefinedBehaviorInfoExt2<'tcx> { tcx: TyCtxt<'tcx>, } -impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) - where - F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, - { +impl UndefinedBehaviorInfoExt2<'_> { + fn eagerly_translate(self) -> String { use crate::fluent_generated::*; use UndefinedBehaviorInfo::*; let handler = &self.tcx.sess.parse_sess.span_diagnostic; - // Allow untranslatable_diagnostic lint, since we - // eagerly translate our subdiagnostics by using the - // eagerly_translate_with_args!() macro. - #[allow(rustc::untranslatable_diagnostic)] match self.err { #[allow(rustc::untranslatable_diagnostic)] Ub(str) => { - diag.span_label(self.span, str.clone()); + eagerly_translate_with_args!(handler, str.clone().into(),) } Unreachable => { - diag.span_label(self.span, const_eval_unreachable); + eagerly_translate_with_args!(handler, const_eval_unreachable,) } BoundsCheckFailed { len, index } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_bounds_check_failed, "len", len, "index", index, - ); - diag.span_label(self.span, msg); + ) } DivisionByZero => { - diag.span_label(self.span, const_eval_division_by_zero); + eagerly_translate_with_args!(handler, const_eval_division_by_zero,) } RemainderByZero => { - diag.span_label(self.span, const_eval_remainder_by_zero); + eagerly_translate_with_args!(handler, const_eval_remainder_by_zero,) } DivisionOverflow => { - diag.span_label(self.span, const_eval_division_overflow); + eagerly_translate_with_args!(handler, const_eval_division_overflow,) } RemainderOverflow => { - diag.span_label(self.span, const_eval_remainder_overflow); + eagerly_translate_with_args!(handler, const_eval_remainder_overflow,) } PointerArithOverflow => { - diag.span_label(self.span, const_eval_pointer_arithmetic_overflow); + eagerly_translate_with_args!(handler, const_eval_pointer_arithmetic_overflow,) } InvalidMeta(InvalidMetaKind::SliceTooBig) => { - diag.span_label(self.span, const_eval_invalid_meta_slice); + eagerly_translate_with_args!(handler, const_eval_invalid_meta_slice,) } InvalidMeta(InvalidMetaKind::TooBig) => { - diag.span_label(self.span, const_eval_invalid_meta); + eagerly_translate_with_args!(handler, const_eval_invalid_meta,) } UnterminatedCString(ptr) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_unterminated_c_string, "pointer", ptr, - ); - diag.span_label(self.span, msg); + ) } PointerUseAfterFree(alloc_id, msg) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_pointer_use_after_free, "alloc_id", alloc_id, "bad_pointer_message", bad_pointer_message(msg, handler) - ); - diag.span_label(self.span, msg); + ) } PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => { let diagnostic_message = if ptr_size == Size::ZERO { @@ -559,7 +549,7 @@ impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { const_eval_pointer_out_of_bounds }; - let translated_msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, diagnostic_message, "alloc_id", @@ -572,8 +562,7 @@ impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { ptr_size.bytes(), "bad_pointer_message", bad_pointer_message(msg, &self.tcx.sess.parse_sess.span_diagnostic), - ); - diag.span_label(self.span, translated_msg); + ) } DanglingIntPointer(ptr, msg) => { let diagnostic_message = if ptr == 0 { @@ -595,109 +584,98 @@ impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { )); } - let msg = handler.eagerly_translate_to_string( + handler.eagerly_translate_to_string( diagnostic_message, args.iter().map(|(a, b)| (a, b)), - ); - diag.span_label(self.span, msg); + ) } AlignmentCheckFailed { required, has } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_alignment_check_failed, "required", required.bytes(), "has", has.bytes(), - ); - diag.span_label(self.span, msg); + ) } WriteToReadOnly(alloc) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_write_to_read_only, "allocation", alloc, - ); - diag.span_label(self.span, msg); + ) } DerefFunctionPointer(alloc) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_deref_function_pointer, "allocation", alloc, - ); - diag.span_label(self.span, msg); + ) } DerefVTablePointer(alloc) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_deref_vtable_pointer, "allocation", alloc, - ); - diag.span_label(self.span, msg); + ) } InvalidBool(b) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_invalid_bool, "value", format!("{b:02x}"), - ); - diag.span_label(self.span, msg); + ) } InvalidChar(c) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_invalid_char, "value", format!("{c:08x}"), - ); - diag.span_label(self.span, msg); + ) } InvalidTag(tag) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_invalid_tag, - "value", + "tag", format!("{tag:x}"), - ); - diag.span_label(self.span, msg); + ) } InvalidFunctionPointer(ptr) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_invalid_function_pointer, "pointer", ptr, - ); - diag.span_label(self.span, msg); + ) } InvalidVTablePointer(ptr) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_invalid_vtable_pointer, "pointer", ptr, - ); - diag.span_label(self.span, msg); + ) } InvalidStr(err) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_invalid_str, "err", format!("{err}"), - ); - diag.span_label(self.span, msg); + ) } InvalidUninitBytes(None) => { - diag.span_label(self.span, const_eval_invalid_uninit_bytes_unknown); + eagerly_translate_with_args!(handler, const_eval_invalid_uninit_bytes_unknown,) } InvalidUninitBytes(Some((alloc, info))) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_invalid_uninit_bytes, "alloc", @@ -706,32 +684,29 @@ impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { info.access, "uninit", info.bad, - ); - diag.span_label(self.span, msg); + ) } DeadLocal => { - diag.span_label(self.span, const_eval_dead_local); + eagerly_translate_with_args!(handler, const_eval_dead_local,) } ScalarSizeMismatch(info) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_scalar_size_mismatch, "target_size", info.target_size, "data_size", info.data_size, - ); - diag.span_label(self.span, msg); + ) } UninhabitedEnumVariantWritten(_) => { - diag.span_label(self.span, const_eval_uninhabited_enum_variant_written); + eagerly_translate_with_args!(handler, const_eval_uninhabited_enum_variant_written,) } UninhabitedEnumVariantRead(_) => { - diag.span_label(self.span, const_eval_uninhabited_enum_variant_read); + eagerly_translate_with_args!(handler, const_eval_uninhabited_enum_variant_read,) } ValidationError(err) => { - ValidationErrorInfoExt2 { err, tcx: self.tcx, span: self.span } - .add_to_diagnostic(diag); + ValidationErrorInfoExt2 { err, tcx: self.tcx, span: self.span }.eagerly_translate() } Custom(x) => { let mut args = Vec::new(); @@ -740,12 +715,58 @@ impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { args.push((name, value)); }); - let msg = handler.eagerly_translate_to_string( + handler.eagerly_translate_to_string( (x.msg.clone())(), args.iter().map(|(a, b)| (a, b)), - ); + ) + } + } + } +} - diag.span_label(self.span, msg); +impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + use UndefinedBehaviorInfo::*; + + 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) => { + ValidationErrorInfoExt2 { err, tcx: self.tcx, span: self.span } + .add_to_diagnostic(diag); } } } @@ -946,11 +967,8 @@ pub struct ValidationErrorInfoExt2<'tcx> { tcx: TyCtxt<'tcx>, } -impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) - where - F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, - { +impl ValidationErrorInfoExt2<'_> { + fn eagerly_translate(self) -> String { use crate::fluent_generated::*; use crate::interpret::ValidationErrorKind::*; @@ -995,81 +1013,60 @@ impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { ) }; - // Allow untranslatable_diagnostic lint, since we - // eagerly translate our subdiagnostics by using the - // eagerly_translate_with_args!() macro. - #[allow(rustc::untranslatable_diagnostic)] match self.err.kind { PtrToUninhabited { ptr_kind: PointerKind::Box, ty } => { - // FIXME(victor-timofei): maybe it would be a good idea to add a - // span_label_eagerly_translated!() macro - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_box_to_uninhabited, "ty", ty.to_string(), "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } PtrToUninhabited { ptr_kind: PointerKind::Ref, ty } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_ref_to_uninhabited, "ty", ty.to_string(), "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } PtrToStatic { ptr_kind: PointerKind::Box, .. } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_box_to_static, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } PtrToStatic { ptr_kind: PointerKind::Ref, .. } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_ref_to_static, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } PtrToMut { ptr_kind: PointerKind::Box, .. } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_box_to_mut, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } PtrToMut { ptr_kind: PointerKind::Ref, .. } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_ref_to_mut, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } PointerAsInt { expected } => { - diag.help(const_eval_ptr_as_bytes_1); - diag.help(const_eval_ptr_as_bytes_2); - let expected = match expected { ExpectedKind::Reference => fluent::const_eval_validation_expected_ref, ExpectedKind::Box => fluent::const_eval_validation_expected_box, @@ -1085,85 +1082,69 @@ impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { }; let expected = handler.eagerly_translate_to_string(expected, [].into_iter()); - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_pointer_as_int, "expected", expected, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } PartialPointer => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_partial_pointer, "front_matter", front_matter, - ); - diag.span_label(self.span, msg); - - diag.help(const_eval_ptr_as_bytes_1); - diag.help(const_eval_ptr_as_bytes_2); + ) } MutableRefInConst => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_mutable_ref_in_const, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } NullFnPtr => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_null_fn_ptr, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } NeverVal => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_never_val, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } NullablePtrOutOfRange { range, max_value } => { - let msg = eagerly_translate_with_args!( + 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), - ); - - diag.span_label(self.span, msg); + ) } PtrOutOfRange { range, max_value } => { - let msg = eagerly_translate_with_args!( + 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), - ); - - diag.span_label(self.span, msg); + ) } OutOfRange { range, max_value, value } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_out_of_range, "front_matter", @@ -1172,53 +1153,43 @@ impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { get_range_arg(range, max_value, &handler), "value", value, - ); - - diag.span_label(self.span, msg); + ) } UnsafeCell => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_unsafe_cell, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } UninhabitedVal { ty } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_uninhabited_val, "front_matter", front_matter, "ty", ty.to_string(), - ); - - diag.span_label(self.span, msg); + ) } InvalidEnumTag { value } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_enum_tag, "front_matter", front_matter, "value", value, - ); - - diag.span_label(self.span, msg); + ) } UninhabitedEnumVariant => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_uninhabited_enum_variant, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } Uninit { expected } => { let expected = match expected { @@ -1236,71 +1207,59 @@ impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { }; let expected = handler.eagerly_translate_to_string(expected, [].into_iter()); - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_uninit, "expected", expected, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } InvalidVTablePtr { value } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_vtable_ptr, "front_matter", front_matter, "value", value, - ); - - diag.span_label(self.span, msg); + ) } InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_box_slice_meta, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_ref_slice_meta, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_box_meta, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_ref_meta, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } UnalignedPtr { ptr_kind: PointerKind::Ref, required_bytes, found_bytes } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_unaligned_ref, "front_matter", @@ -1309,12 +1268,10 @@ impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { required_bytes.to_string(), "found_bytes", found_bytes.to_string(), - ); - - diag.span_label(self.span, msg); + ) } UnalignedPtr { ptr_kind: PointerKind::Box, required_bytes, found_bytes } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_unaligned_box, "front_matter", @@ -1323,132 +1280,153 @@ impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { required_bytes.to_string(), "found_bytes", found_bytes.to_string(), - ); - - diag.span_label(self.span, msg); + ) } NullPtr { ptr_kind: PointerKind::Box } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_null_box, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } NullPtr { ptr_kind: PointerKind::Ref } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_null_ref, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, pointer } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_dangling_box_no_provenance, "front_matter", front_matter, "pointer", pointer, - ); - - diag.span_label(self.span, msg); + ) } DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, pointer } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_dangling_ref_no_provenance, "front_matter", front_matter, "pointer", pointer, - ); - - diag.span_label(self.span, msg); + ) } DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_dangling_box_out_of_bounds, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_dangling_ref_out_of_bounds, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_dangling_box_use_after_free, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_dangling_ref_use_after_free, "front_matter", front_matter, - ); - - diag.span_label(self.span, msg); + ) } InvalidBool { value } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_bool, "front_matter", front_matter, "value", value, - ); - - diag.span_label(self.span, msg); + ) } InvalidChar { value } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_char, "front_matter", front_matter, "value", value, - ); - - diag.span_label(self.span, msg); + ) } InvalidFnPtr { value } => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_validation_invalid_fn_ptr, "front_matter", front_matter, "value", value, - ); + ) + } + } + } +} - diag.span_label(self.span, msg); +impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { + 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 { .. } + | UnalignedPtr { .. } + | NullPtr { .. } + | DanglingPtrNoProvenance { .. } + | DanglingPtrOutOfBounds { .. } + | 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()); } } @@ -1793,82 +1771,78 @@ pub struct UnsupportedOpExt2<'tcx> { tcx: TyCtxt<'tcx>, } -impl AddToDiagnostic for UnsupportedOpExt2<'_> { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) - where - F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, - { +impl UnsupportedOpExt2<'_> { + fn eagerly_translate(self) -> String { use crate::fluent_generated::*; use UnsupportedOpInfo::*; let handler = &self.tcx.sess.parse_sess.span_diagnostic; - // Allow untranslatable_diagnostic lint, since we - // eagerly translate our subdiagnostics by using the - // eagerly_translate_with_args!() macro. - #[allow(rustc::untranslatable_diagnostic)] match self.err { Unsupported(s) => { - diag.span_label( - self.span, + eagerly_translate_with_args!( + handler, >::into(s.clone()), - ); + ) } OverwritePartialPointer(ptr) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_partial_pointer_overwrite, "ptr", ptr, - ); - diag.span_label(self.span, msg); - - diag.help(const_eval_ptr_as_bytes_1); - diag.help(const_eval_ptr_as_bytes_2); + ) } ReadPartialPointer(ptr) => { - let msg = eagerly_translate_with_args!( - handler, - const_eval_partial_pointer_copy, - "ptr", - ptr, - ); - diag.span_label(self.span, msg); - - diag.help(const_eval_ptr_as_bytes_1); - diag.help(const_eval_ptr_as_bytes_2); + 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`. ReadPointerAsInt(_) => { - diag.span_label(self.span, const_eval_read_pointer_as_int); - - diag.help(const_eval_ptr_as_bytes_1); - diag.help(const_eval_ptr_as_bytes_2); + eagerly_translate_with_args!(handler, const_eval_read_pointer_as_int,) } ThreadLocalStatic(did) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_thread_local_static, "did", format!("{did:?}"), - ); - diag.span_label(self.span, msg); + ) } ReadExternStatic(did) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, const_eval_read_extern_static, "did", format!("{did:?}"), - ); - diag.span_label(self.span, msg); + ) } } } } +impl AddToDiagnostic for UnsupportedOpExt2<'_> { + 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()); + } +} + pub struct InterpErrorExt2<'tcx> { pub err: InterpError<'tcx>, pub span: Span, @@ -1894,19 +1868,43 @@ impl AddToDiagnostic for InterpErrorExt2<'_> { .add_to_diagnostic(diag); } InterpError::ResourceExhaustion(e) => { - ResourceExhaustionExt2 { err: e, span: self.span }.add_to_diagnostic(diag); + ResourceExhaustionExt2 { err: e, span: self.span, tcx: self.tcx } + .add_to_diagnostic(diag); } InterpError::MachineStop(e) => { - MachineStopExt2 { err: e, span: self.span }.add_to_diagnostic(diag); + MachineStopExt2 { err: e, span: self.span, tcx: self.tcx }.add_to_diagnostic(diag); } } } } impl InterpErrorExt2<'_> { - pub fn to_string(&self) -> String { + /// 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 - todo!("InterpErrorExt2::to_string"); + match self.err { + InterpError::UndefinedBehavior(ub) => { + UndefinedBehaviorInfoExt2 { err: ub, span: self.span, tcx: self.tcx } + .eagerly_translate() + } + InterpError::Unsupported(e) => { + UnsupportedOpExt2 { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() + } + InterpError::InvalidProgram(e) => { + InvalidProgramInfoExt2 { err: e, span: self.span, tcx: self.tcx } + .eagerly_translate() + } + InterpError::ResourceExhaustion(e) => { + ResourceExhaustionExt2 { err: e, span: self.span, tcx: self.tcx } + .eagerly_translate() + } + InterpError::MachineStop(e) => { + MachineStopExt2 { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() + } + } } } @@ -1945,21 +1943,33 @@ impl InterpErrorExt<'_> { } } -pub struct MachineStopExt2 { +pub struct MachineStopExt2<'tcx> { err: Box, span: Span, + tcx: TyCtxt<'tcx>, } -impl AddToDiagnostic for MachineStopExt2 { +impl MachineStopExt2<'_> { + 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 MachineStopExt2<'_> { fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, { - diag.span_label(self.span, self.err.diagnostic_message().clone()); - - self.err.add_args(&mut |name, value| { - diag.set_arg(name, value); - }); + #[allow(rustc::untranslatable_diagnostic)] + diag.span_label(self.span, self.eagerly_translate()); } } @@ -1982,50 +1992,39 @@ pub struct InvalidProgramInfoExt2<'tcx> { tcx: TyCtxt<'tcx>, } -impl AddToDiagnostic for InvalidProgramInfoExt2<'_> { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) - where - F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, - { +impl InvalidProgramInfoExt2<'_> { + fn eagerly_translate(self) -> String { use crate::fluent_generated::*; let handler = &self.tcx.sess.parse_sess.span_diagnostic; - // Allow untranslatable_diagnostic lint, since we - // eagerly translate our subdiagnostics by using the - // eagerly_translate_with_args!() macro. - #[allow(rustc::untranslatable_diagnostic)] match self.err { InvalidProgramInfo::TooGeneric => { - diag.span_label(self.span, const_eval_too_generic); + eagerly_translate_with_args!(handler, const_eval_too_generic,) } InvalidProgramInfo::AlreadyReported(_) => { - diag.span_label(self.span, const_eval_already_reported); + eagerly_translate_with_args!(handler, const_eval_already_reported,) } InvalidProgramInfo::Layout(e) => { let builder: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(handler); - for (name, val) in builder.args() { - diag.set_arg(name.clone(), val.clone()); - } + let msg = handler.eagerly_translate_to_string(e.diagnostic_message(), builder.args()); builder.cancel(); - diag.span_label(self.span, msg); + msg } InvalidProgramInfo::FnAbiAdjustForForeignAbi( AdjustForForeignAbiError::Unsupported { arch, abi }, ) => { - let msg = eagerly_translate_with_args!( + eagerly_translate_with_args!( handler, rustc_middle::error::middle_adjust_for_foreign_abi_error, "arch", arch.to_ident_string(), "abi", abi.name(), - ); - - diag.span_label(self.span, msg); + ) } InvalidProgramInfo::ConstPropNonsense => { panic!("We had const-prop nonsense, this should never be printed") @@ -2034,6 +2033,26 @@ impl AddToDiagnostic for InvalidProgramInfoExt2<'_> { } } +impl AddToDiagnostic for InvalidProgramInfoExt2<'_> { + 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::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()); + } +} + pub struct InvalidProgramInfoExt<'a>(InvalidProgramInfo<'a>); impl IntoDiagnostic<'_> for InvalidProgramInfoExt<'_> { @@ -2073,23 +2092,34 @@ impl IntoDiagnostic<'_> for InvalidProgramInfoExt<'_> { } } -pub struct ResourceExhaustionExt2 { +pub struct ResourceExhaustionExt2<'tcx> { err: ResourceExhaustionInfo, span: Span, + tcx: TyCtxt<'tcx>, } -impl AddToDiagnostic for ResourceExhaustionExt2 { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) - where - F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, - { +impl ResourceExhaustionExt2<'_> { + fn eagerly_translate(self) -> String { + let handler = &self.tcx.sess.parse_sess.span_diagnostic; + use crate::fluent_generated::*; 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, }; - diag.span_label(self.span, msg); + + eagerly_translate_with_args!(handler, msg) + } +} + +impl AddToDiagnostic for ResourceExhaustionExt2<'_> { + 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()); } } From 74063d4b10c961bb9e77569264642bfe20821073 Mon Sep 17 00:00:00 2001 From: Victor Timofei Date: Sun, 13 Aug 2023 12:32:50 +0300 Subject: [PATCH 4/5] Remove old *Ext types and fix type visibility --- compiler/rustc_const_eval/src/errors.rs | 647 +----------------------- 1 file changed, 10 insertions(+), 637 deletions(-) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 00b6bf0eca531..7e45b4e92aa2f 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -1,6 +1,6 @@ use rustc_errors::{ - AddToDiagnostic, Diagnostic, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, - EmissionGuarantee, Handler, IntoDiagnostic, IntoDiagnosticArg, SubdiagnosticMessage, + AddToDiagnostic, Diagnostic, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, Handler, + IntoDiagnostic, IntoDiagnosticArg, SubdiagnosticMessage, }; use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -9,8 +9,8 @@ use rustc_middle::mir::interpret::{ MachineStopType, PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, }; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::{ErrorGuaranteed, Span}; +use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_span::Span; use rustc_target::abi::call::AdjustForForeignAbiError; use rustc_target::abi::{Size, WrappingRange}; @@ -470,9 +470,7 @@ fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String { handler.eagerly_translate_to_string(msg, [].into_iter()) } -pub struct UndefinedBehaviorInfoExt<'a>(UndefinedBehaviorInfo<'a>); - -pub struct UndefinedBehaviorInfoExt2<'tcx> { +struct UndefinedBehaviorInfoExt2<'tcx> { err: UndefinedBehaviorInfo<'tcx>, span: Span, tcx: TyCtxt<'tcx>, @@ -772,196 +770,7 @@ impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { } } -impl IntoDiagnostic<'_> for UndefinedBehaviorInfoExt<'_> { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - use crate::fluent_generated::*; - use UndefinedBehaviorInfo::*; - match self.0 { - #[allow(rustc::untranslatable_diagnostic)] - Ub(str) => handler.struct_diagnostic(str.clone()), - Unreachable => handler.struct_diagnostic(const_eval_unreachable), - BoundsCheckFailed { len, index } => { - let mut builder = handler.struct_diagnostic(const_eval_bounds_check_failed); - - builder.set_arg("len", len); - builder.set_arg("index", index); - - builder - } - DivisionByZero => handler.struct_diagnostic(const_eval_division_by_zero), - RemainderByZero => handler.struct_diagnostic(const_eval_remainder_by_zero), - DivisionOverflow => handler.struct_diagnostic(const_eval_division_overflow), - RemainderOverflow => handler.struct_diagnostic(const_eval_remainder_overflow), - PointerArithOverflow => { - handler.struct_diagnostic(const_eval_pointer_arithmetic_overflow) - } - InvalidMeta(InvalidMetaKind::SliceTooBig) => { - handler.struct_diagnostic(const_eval_invalid_meta_slice) - } - InvalidMeta(InvalidMetaKind::TooBig) => { - handler.struct_diagnostic(const_eval_invalid_meta) - } - UnterminatedCString(ptr) => { - let mut builder = handler.struct_diagnostic(const_eval_unterminated_c_string); - - builder.set_arg("pointer", ptr); - - builder - } - PointerUseAfterFree(alloc_id, msg) => { - let mut builder = handler.struct_diagnostic(const_eval_pointer_use_after_free); - - builder.set_arg("allocation", alloc_id); - builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); - - builder - } - PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => { - let mut builder = if ptr_size == Size::ZERO { - handler.struct_diagnostic(const_eval_zst_pointer_out_of_bounds) - } else { - handler.struct_diagnostic(const_eval_pointer_out_of_bounds) - }; - - 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)); - - builder - } - DanglingIntPointer(ptr, msg) => { - let mut builder = if ptr == 0 { - handler.struct_diagnostic(const_eval_dangling_null_pointer) - } else { - handler.struct_diagnostic(const_eval_dangling_int_pointer) - }; - - if ptr != 0 { - builder.set_arg("pointer", format!("{ptr:#x}[noalloc]")); - } - - builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler)); - - builder - } - AlignmentCheckFailed { required, has } => { - let mut builder = handler.struct_diagnostic(const_eval_alignment_check_failed); - - builder.set_arg("required", required.bytes()); - builder.set_arg("has", has.bytes()); - - builder - } - WriteToReadOnly(alloc) => { - let mut builder = handler.struct_diagnostic(const_eval_write_to_read_only); - - builder.set_arg("allocation", alloc); - - builder - } - DerefFunctionPointer(alloc) => { - let mut builder = handler.struct_diagnostic(const_eval_deref_function_pointer); - - builder.set_arg("allocation", alloc); - - builder - } - DerefVTablePointer(alloc) => { - let mut builder = handler.struct_diagnostic(const_eval_deref_vtable_pointer); - - builder.set_arg("allocation", alloc); - - builder - } - InvalidBool(b) => { - let mut builder = handler.struct_diagnostic(const_eval_invalid_bool); - - builder.set_arg("value", format!("{b:02x}")); - - builder - } - InvalidChar(c) => { - let mut builder = handler.struct_diagnostic(const_eval_invalid_char); - - builder.set_arg("value", format!("{c:08x}")); - - builder - } - InvalidTag(tag) => { - let mut builder = handler.struct_diagnostic(const_eval_invalid_tag); - - builder.set_arg("tag", format!("{tag:x}")); - - builder - } - InvalidFunctionPointer(ptr) => { - let mut builder = handler.struct_diagnostic(const_eval_invalid_function_pointer); - - builder.set_arg("pointer", ptr); - - builder - } - InvalidVTablePointer(ptr) => { - let mut builder = handler.struct_diagnostic(const_eval_invalid_vtable_pointer); - - builder.set_arg("pointer", ptr); - - builder - } - InvalidStr(err) => { - let mut builder = handler.struct_diagnostic(const_eval_invalid_str); - - builder.set_arg("err", format!("{err}")); - - builder - } - InvalidUninitBytes(None) => { - handler.struct_diagnostic(const_eval_invalid_uninit_bytes_unknown) - } - InvalidUninitBytes(Some((alloc, info))) => { - let mut builder = handler.struct_diagnostic(const_eval_invalid_uninit_bytes); - - builder.set_arg("alloc", alloc); - builder.set_arg("access", info.access); - builder.set_arg("uninit", info.bad); - - builder - } - DeadLocal => handler.struct_diagnostic(const_eval_dead_local), - ScalarSizeMismatch(info) => { - let mut builder = handler.struct_diagnostic(const_eval_scalar_size_mismatch); - - builder.set_arg("target_size", info.target_size); - builder.set_arg("data_size", info.data_size); - - builder - } - UninhabitedEnumVariantWritten(_) => { - handler.struct_diagnostic(const_eval_uninhabited_enum_variant_written) - } - UninhabitedEnumVariantRead(_) => { - handler.struct_diagnostic(const_eval_uninhabited_enum_variant_read) - } - ValidationError(e) => ValidationErrorInfoExt(e).into_diagnostic(handler), - Custom(x) => { - let mut builder = handler.struct_diagnostic((x.msg.clone())()); - - (x.add_args)(&mut |name, value| { - builder.set_arg(name, value); - }); - - builder - } - } - } -} - -pub struct ValidationErrorInfoExt<'tcx>(ValidationErrorInfo<'tcx>); - -pub struct ValidationErrorInfoExt2<'tcx> { +struct ValidationErrorInfoExt2<'tcx> { err: ValidationErrorInfo<'tcx>, span: Span, tcx: TyCtxt<'tcx>, @@ -1430,342 +1239,7 @@ impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { } } -impl IntoDiagnostic<'_> for ValidationErrorInfoExt<'_> { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - use crate::fluent_generated::*; - use crate::interpret::ValidationErrorKind::*; - - fn add_range_arg( - r: WrappingRange, - max_hi: u128, - handler: &Handler, - err: &mut DiagnosticBuilder<'_, G>, - ) { - let WrappingRange { start: lo, end: hi } = r; - assert!(hi <= max_hi); - let msg = if lo > hi { - fluent::const_eval_range_wrapping - } else if lo == hi { - fluent::const_eval_range_singular - } else if lo == 0 { - assert!(hi < max_hi, "should not be printing if the range covers everything"); - fluent::const_eval_range_upper - } else if hi == max_hi { - assert!(lo > 0, "should not be printing if the range covers everything"); - fluent::const_eval_range_lower - } else { - fluent::const_eval_range - }; - - let args = [ - ("lo".into(), DiagnosticArgValue::Str(lo.to_string().into())), - ("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); - } - - let mut builder = match self.0.kind { - PtrToUninhabited { ptr_kind: PointerKind::Box, ty } => { - let mut builder = - handler.struct_diagnostic(const_eval_validation_box_to_uninhabited); - - builder.set_arg("ty", ty); - - builder - } - PtrToUninhabited { ptr_kind: PointerKind::Ref, ty } => { - let mut builder = - handler.struct_diagnostic(const_eval_validation_ref_to_uninhabited); - - builder.set_arg("ty", ty); - - builder - } - PtrToStatic { ptr_kind: PointerKind::Box, .. } => { - handler.struct_diagnostic(const_eval_validation_box_to_static) - } - PtrToStatic { ptr_kind: PointerKind::Ref, .. } => { - handler.struct_diagnostic(const_eval_validation_ref_to_static) - } - PtrToMut { ptr_kind: PointerKind::Box, .. } => { - handler.struct_diagnostic(const_eval_validation_box_to_mut) - } - PtrToMut { ptr_kind: PointerKind::Ref, .. } => { - handler.struct_diagnostic(const_eval_validation_ref_to_mut) - } - PointerAsInt { expected } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_pointer_as_int); - - builder.help(const_eval_ptr_as_bytes_1); - builder.help(const_eval_ptr_as_bytes_2); - - let msg = 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 msg = handler.eagerly_translate_to_string(msg, [].into_iter()); - builder.set_arg("expected", msg); - - builder - } - PartialPointer => { - let mut builder = handler.struct_diagnostic(const_eval_validation_partial_pointer); - - builder.help(const_eval_ptr_as_bytes_1); - builder.help(const_eval_ptr_as_bytes_2); - - builder - } - MutableRefInConst => { - handler.struct_diagnostic(const_eval_validation_mutable_ref_in_const) - } - NullFnPtr => handler.struct_diagnostic(const_eval_validation_null_fn_ptr), - NeverVal => handler.struct_diagnostic(const_eval_validation_never_val), - NullablePtrOutOfRange { range, max_value } => { - let mut builder = - handler.struct_diagnostic(const_eval_validation_nullable_ptr_out_of_range); - - add_range_arg(range, max_value, handler, &mut builder); - - builder - } - PtrOutOfRange { range, max_value } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_ptr_out_of_range); - - add_range_arg(range, max_value, handler, &mut builder); - - builder - } - OutOfRange { range, max_value, value } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_out_of_range); - - builder.set_arg("value", value); - add_range_arg(range, max_value, handler, &mut builder); - - builder - } - UnsafeCell => handler.struct_diagnostic(const_eval_validation_unsafe_cell), - UninhabitedVal { ty } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_uninhabited_val); - - builder.set_arg("ty", ty); - - builder - } - InvalidEnumTag { value } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_enum_tag); - - builder.set_arg("value", value); - - builder - } - UninhabitedEnumVariant => { - handler.struct_diagnostic(const_eval_validation_uninhabited_enum_variant) - } - Uninit { expected } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_uninit); - - let msg = 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 msg = handler.eagerly_translate_to_string(msg, [].into_iter()); - builder.set_arg("expected", msg); - - builder - } - InvalidVTablePtr { value } => { - let mut builder = - handler.struct_diagnostic(const_eval_validation_invalid_vtable_ptr); - - builder.set_arg("value", value); - - builder - } - InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => { - handler.struct_diagnostic(const_eval_validation_invalid_box_slice_meta) - } - InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => { - handler.struct_diagnostic(const_eval_validation_invalid_ref_slice_meta) - } - InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => { - handler.struct_diagnostic(const_eval_validation_invalid_box_meta) - } - InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => { - handler.struct_diagnostic(const_eval_validation_invalid_ref_meta) - } - UnalignedPtr { ptr_kind: PointerKind::Ref, required_bytes, found_bytes } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_unaligned_ref); - - builder.set_arg("required_bytes", required_bytes); - builder.set_arg("found_bytes", found_bytes); - - builder - } - UnalignedPtr { ptr_kind: PointerKind::Box, required_bytes, found_bytes } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_unaligned_box); - - builder.set_arg("required_bytes", required_bytes); - builder.set_arg("found_bytes", found_bytes); - - builder - } - - NullPtr { ptr_kind: PointerKind::Box } => { - handler.struct_diagnostic(const_eval_validation_null_box) - } - NullPtr { ptr_kind: PointerKind::Ref } => { - handler.struct_diagnostic(const_eval_validation_null_ref) - } - DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, pointer } => { - let mut builder = - handler.struct_diagnostic(const_eval_validation_dangling_box_no_provenance); - - builder.set_arg("pointer", pointer); - - builder - } - DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, pointer } => { - let mut builder = - handler.struct_diagnostic(const_eval_validation_dangling_ref_no_provenance); - - builder.set_arg("pointer", pointer); - - builder - } - DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => { - handler.struct_diagnostic(const_eval_validation_dangling_box_out_of_bounds) - } - DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => { - handler.struct_diagnostic(const_eval_validation_dangling_ref_out_of_bounds) - } - DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => { - handler.struct_diagnostic(const_eval_validation_dangling_box_use_after_free) - } - DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => { - handler.struct_diagnostic(const_eval_validation_dangling_ref_use_after_free) - } - InvalidBool { value } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_bool); - - builder.set_arg("value", value); - - builder - } - InvalidChar { value } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_char); - - builder.set_arg("value", value); - - builder - } - InvalidFnPtr { value } => { - let mut builder = handler.struct_diagnostic(const_eval_validation_invalid_fn_ptr); - - builder.set_arg("value", value); - - builder - } - }; - - use crate::fluent_generated as fluent; - - let message = if let Some(path) = self.0.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(), - ) - }; - - builder.set_arg("front_matter", message); - - builder - } -} - -pub struct UnsupportedExt(UnsupportedOpInfo); - -impl IntoDiagnostic<'_> for UnsupportedExt { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - use crate::fluent_generated::*; - use UnsupportedOpInfo::*; - match self.0 { - Unsupported(s) => handler.struct_diagnostic(>::into(s.clone())), - OverwritePartialPointer(ptr) => { - let mut builder = handler.struct_diagnostic(const_eval_partial_pointer_overwrite); - - builder.help(const_eval_ptr_as_bytes_1); - builder.help(const_eval_ptr_as_bytes_2); - builder.set_arg("ptr", ptr); - - builder - } - ReadPartialPointer(ptr) => { - let mut builder = handler.struct_diagnostic(const_eval_partial_pointer_copy); - - builder.help(const_eval_ptr_as_bytes_1); - builder.help(const_eval_ptr_as_bytes_2); - builder.set_arg("ptr", ptr); - - builder - } - // `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`. - ReadPointerAsInt(_) => { - let mut builder = handler.struct_diagnostic(const_eval_read_pointer_as_int); - - builder.help(const_eval_ptr_as_bytes_1); - builder.help(const_eval_ptr_as_bytes_2); - - builder - } - ThreadLocalStatic(did) => { - let mut builder = handler.struct_diagnostic(const_eval_thread_local_static); - - builder.set_arg("did", format!("{did:?}")); - - builder - } - ReadExternStatic(did) => { - let mut builder = handler.struct_diagnostic(const_eval_read_extern_static); - - builder.set_arg("did", format!("{did:?}")); - - builder - } - } - } -} - -pub struct UnsupportedOpExt2<'tcx> { +struct UnsupportedOpExt2<'tcx> { err: UnsupportedOpInfo, span: Span, tcx: TyCtxt<'tcx>, @@ -1908,42 +1382,7 @@ impl InterpErrorExt2<'_> { } } -pub struct InterpErrorExt<'a>(pub InterpError<'a>); - -impl IntoDiagnostic<'_> for InterpErrorExt<'_> { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - match self.0 { - InterpError::UndefinedBehavior(ub) => { - UndefinedBehaviorInfoExt(ub).into_diagnostic(handler) - } - InterpError::Unsupported(e) => UnsupportedExt(e).into_diagnostic(handler), - InterpError::InvalidProgram(e) => InvalidProgramInfoExt(e).into_diagnostic(handler), - InterpError::ResourceExhaustion(e) => ResourceExhaustionExt(e).into_diagnostic(handler), - InterpError::MachineStop(e) => MachineStopExt(e).into_diagnostic(handler), - } - } -} - -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 { - ty::tls::with(move |tcx| { - let handler = &tcx.sess.parse_sess.span_diagnostic; - let builder = self.into_diagnostic(handler); - let s = handler.eagerly_translate_to_string( - builder.message.first().unwrap().0.to_owned(), - builder.args(), - ); - builder.cancel(); - s - }) - } -} - -pub struct MachineStopExt2<'tcx> { +struct MachineStopExt2<'tcx> { err: Box, span: Span, tcx: TyCtxt<'tcx>, @@ -1973,20 +1412,7 @@ impl AddToDiagnostic for MachineStopExt2<'_> { } } -pub struct MachineStopExt(Box); - -impl IntoDiagnostic<'_> for MachineStopExt { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut builder = handler.struct_diagnostic(self.0.diagnostic_message().clone()); - - self.0.add_args(&mut |name, value| { - builder.set_arg(name, value); - }); - builder - } -} - -pub struct InvalidProgramInfoExt2<'tcx> { +struct InvalidProgramInfoExt2<'tcx> { err: InvalidProgramInfo<'tcx>, span: Span, tcx: TyCtxt<'tcx>, @@ -2053,46 +1479,7 @@ impl AddToDiagnostic for InvalidProgramInfoExt2<'_> { } } -pub struct InvalidProgramInfoExt<'a>(InvalidProgramInfo<'a>); - -impl IntoDiagnostic<'_> for InvalidProgramInfoExt<'_> { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - use crate::fluent_generated::*; - match self.0 { - InvalidProgramInfo::TooGeneric => handler.struct_diagnostic(const_eval_too_generic), - InvalidProgramInfo::AlreadyReported(_) => { - handler.struct_diagnostic(const_eval_already_reported) - } - InvalidProgramInfo::Layout(e) => { - let mut builder = handler.struct_diagnostic(e.diagnostic_message()); - - let diag: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(handler); - for (name, val) in diag.args() { - builder.set_arg(name.clone(), val.clone()); - } - diag.cancel(); - - builder - } - InvalidProgramInfo::FnAbiAdjustForForeignAbi( - AdjustForForeignAbiError::Unsupported { arch, abi }, - ) => { - let mut builder = handler - .struct_diagnostic(rustc_middle::error::middle_adjust_for_foreign_abi_error); - - builder.set_arg("arch", arch); - builder.set_arg("abi", abi.name()); - - builder - } - InvalidProgramInfo::ConstPropNonsense => { - panic!("We had const-prop nonsense, this should never be printed") - } - } - } -} - -pub struct ResourceExhaustionExt2<'tcx> { +struct ResourceExhaustionExt2<'tcx> { err: ResourceExhaustionInfo, span: Span, tcx: TyCtxt<'tcx>, @@ -2122,17 +1509,3 @@ impl AddToDiagnostic for ResourceExhaustionExt2<'_> { diag.span_label(self.span, self.eagerly_translate()); } } - -pub struct ResourceExhaustionExt(ResourceExhaustionInfo); - -impl IntoDiagnostic<'_> for ResourceExhaustionExt { - fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - use crate::fluent_generated::*; - let msg = match self.0 { - ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached, - ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted, - ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full, - }; - handler.struct_diagnostic(msg) - } -} From f2af515719a7b52413219408064858d9e2a822b1 Mon Sep 17 00:00:00 2001 From: Victor Timofei Date: Sun, 13 Aug 2023 12:41:40 +0300 Subject: [PATCH 5/5] Rename *Ext2 types to *Ext --- .../rustc_const_eval/src/const_eval/error.rs | 4 +- compiler/rustc_const_eval/src/errors.rs | 69 +++++++++---------- compiler/rustc_const_eval/src/lib.rs | 2 +- .../rustc_mir_transform/src/const_prop.rs | 4 +- .../src/const_prop_lint.rs | 4 +- src/tools/miri/src/diagnostics.rs | 4 +- 6 files changed, 42 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 41ffcbc4f7b82..d6b6a516e8652 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -10,7 +10,7 @@ use rustc_span::{ErrorGuaranteed, Span, Symbol}; use super::InterpCx; use crate::errors::{self, FrameNote}; use crate::interpret::{ErrorHandled, InterpError, InterpErrorInfo, Machine, MachineStopType}; -use crate::InterpErrorExt2; +use crate::InterpErrorExt; /// The CTFE machine has some custom error kinds. #[derive(Clone, Debug)] @@ -167,7 +167,7 @@ where let (our_span, frames) = get_span_and_frames(); let span = span.unwrap_or(our_span); let err = mk(span, frames); - let interp_err = InterpErrorExt2 { err: error, span, tcx }; + let interp_err = InterpErrorExt { err: error, span, tcx }; let mut err = tcx.sess.create_err(err); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 7e45b4e92aa2f..7e0c42db084de 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -470,13 +470,13 @@ fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String { handler.eagerly_translate_to_string(msg, [].into_iter()) } -struct UndefinedBehaviorInfoExt2<'tcx> { +struct UndefinedBehaviorInfoExt<'tcx> { err: UndefinedBehaviorInfo<'tcx>, span: Span, tcx: TyCtxt<'tcx>, } -impl UndefinedBehaviorInfoExt2<'_> { +impl UndefinedBehaviorInfoExt<'_> { fn eagerly_translate(self) -> String { use crate::fluent_generated::*; use UndefinedBehaviorInfo::*; @@ -704,7 +704,7 @@ impl UndefinedBehaviorInfoExt2<'_> { eagerly_translate_with_args!(handler, const_eval_uninhabited_enum_variant_read,) } ValidationError(err) => { - ValidationErrorInfoExt2 { err, tcx: self.tcx, span: self.span }.eagerly_translate() + ValidationErrorInfoExt { err, tcx: self.tcx, span: self.span }.eagerly_translate() } Custom(x) => { let mut args = Vec::new(); @@ -722,7 +722,7 @@ impl UndefinedBehaviorInfoExt2<'_> { } } -impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { +impl AddToDiagnostic for UndefinedBehaviorInfoExt<'_> { fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, @@ -763,20 +763,20 @@ impl AddToDiagnostic for UndefinedBehaviorInfoExt2<'_> { diag.span_label(self.span, self.eagerly_translate()); } ValidationError(err) => { - ValidationErrorInfoExt2 { err, tcx: self.tcx, span: self.span } + ValidationErrorInfoExt { err, tcx: self.tcx, span: self.span } .add_to_diagnostic(diag); } } } } -struct ValidationErrorInfoExt2<'tcx> { +struct ValidationErrorInfoExt<'tcx> { err: ValidationErrorInfo<'tcx>, span: Span, tcx: TyCtxt<'tcx>, } -impl ValidationErrorInfoExt2<'_> { +impl ValidationErrorInfoExt<'_> { fn eagerly_translate(self) -> String { use crate::fluent_generated::*; use crate::interpret::ValidationErrorKind::*; @@ -1194,7 +1194,7 @@ impl ValidationErrorInfoExt2<'_> { } } -impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { +impl AddToDiagnostic for ValidationErrorInfoExt<'_> { fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, @@ -1239,13 +1239,13 @@ impl AddToDiagnostic for ValidationErrorInfoExt2<'_> { } } -struct UnsupportedOpExt2<'tcx> { +struct UnsupportedOpExt<'tcx> { err: UnsupportedOpInfo, span: Span, tcx: TyCtxt<'tcx>, } -impl UnsupportedOpExt2<'_> { +impl UnsupportedOpExt<'_> { fn eagerly_translate(self) -> String { use crate::fluent_generated::*; use UnsupportedOpInfo::*; @@ -1296,7 +1296,7 @@ impl UnsupportedOpExt2<'_> { } } -impl AddToDiagnostic for UnsupportedOpExt2<'_> { +impl AddToDiagnostic for UnsupportedOpExt<'_> { fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, @@ -1317,42 +1317,41 @@ impl AddToDiagnostic for UnsupportedOpExt2<'_> { } } -pub struct InterpErrorExt2<'tcx> { +pub struct InterpErrorExt<'tcx> { pub err: InterpError<'tcx>, pub span: Span, pub tcx: TyCtxt<'tcx>, } -impl AddToDiagnostic for InterpErrorExt2<'_> { +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) => { - UndefinedBehaviorInfoExt2 { err: ub, span: self.span, tcx: self.tcx } + UndefinedBehaviorInfoExt { err: ub, span: self.span, tcx: self.tcx } .add_to_diagnostic(diag); } InterpError::Unsupported(e) => { - UnsupportedOpExt2 { err: e, span: self.span, tcx: self.tcx } - .add_to_diagnostic(diag); + UnsupportedOpExt { err: e, span: self.span, tcx: self.tcx }.add_to_diagnostic(diag); } InterpError::InvalidProgram(e) => { - InvalidProgramInfoExt2 { err: e, span: self.span, tcx: self.tcx } + InvalidProgramInfoExt { err: e, span: self.span, tcx: self.tcx } .add_to_diagnostic(diag); } InterpError::ResourceExhaustion(e) => { - ResourceExhaustionExt2 { err: e, span: self.span, tcx: self.tcx } + ResourceExhaustionExt { err: e, span: self.span, tcx: self.tcx } .add_to_diagnostic(diag); } InterpError::MachineStop(e) => { - MachineStopExt2 { err: e, span: self.span, tcx: self.tcx }.add_to_diagnostic(diag); + MachineStopExt { err: e, span: self.span, tcx: self.tcx }.add_to_diagnostic(diag); } } } } -impl InterpErrorExt2<'_> { +impl InterpErrorExt<'_> { /// Translate InterpError to String. /// /// This should not be used for any user-facing diagnostics, @@ -1361,34 +1360,32 @@ impl InterpErrorExt2<'_> { // FIXME(victor-timofei): implement this match self.err { InterpError::UndefinedBehavior(ub) => { - UndefinedBehaviorInfoExt2 { err: ub, span: self.span, tcx: self.tcx } + UndefinedBehaviorInfoExt { err: ub, span: self.span, tcx: self.tcx } .eagerly_translate() } InterpError::Unsupported(e) => { - UnsupportedOpExt2 { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() + UnsupportedOpExt { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() } InterpError::InvalidProgram(e) => { - InvalidProgramInfoExt2 { err: e, span: self.span, tcx: self.tcx } - .eagerly_translate() + InvalidProgramInfoExt { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() } InterpError::ResourceExhaustion(e) => { - ResourceExhaustionExt2 { err: e, span: self.span, tcx: self.tcx } - .eagerly_translate() + ResourceExhaustionExt { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() } InterpError::MachineStop(e) => { - MachineStopExt2 { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() + MachineStopExt { err: e, span: self.span, tcx: self.tcx }.eagerly_translate() } } } } -struct MachineStopExt2<'tcx> { +struct MachineStopExt<'tcx> { err: Box, span: Span, tcx: TyCtxt<'tcx>, } -impl MachineStopExt2<'_> { +impl MachineStopExt<'_> { fn eagerly_translate(self) -> String { let mut args = Vec::new(); let msg = self.err.diagnostic_message().clone(); @@ -1402,7 +1399,7 @@ impl MachineStopExt2<'_> { } } -impl AddToDiagnostic for MachineStopExt2<'_> { +impl AddToDiagnostic for MachineStopExt<'_> { fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, @@ -1412,13 +1409,13 @@ impl AddToDiagnostic for MachineStopExt2<'_> { } } -struct InvalidProgramInfoExt2<'tcx> { +struct InvalidProgramInfoExt<'tcx> { err: InvalidProgramInfo<'tcx>, span: Span, tcx: TyCtxt<'tcx>, } -impl InvalidProgramInfoExt2<'_> { +impl InvalidProgramInfoExt<'_> { fn eagerly_translate(self) -> String { use crate::fluent_generated::*; let handler = &self.tcx.sess.parse_sess.span_diagnostic; @@ -1459,7 +1456,7 @@ impl InvalidProgramInfoExt2<'_> { } } -impl AddToDiagnostic for InvalidProgramInfoExt2<'_> { +impl AddToDiagnostic for InvalidProgramInfoExt<'_> { fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, @@ -1479,13 +1476,13 @@ impl AddToDiagnostic for InvalidProgramInfoExt2<'_> { } } -struct ResourceExhaustionExt2<'tcx> { +struct ResourceExhaustionExt<'tcx> { err: ResourceExhaustionInfo, span: Span, tcx: TyCtxt<'tcx>, } -impl ResourceExhaustionExt2<'_> { +impl ResourceExhaustionExt<'_> { fn eagerly_translate(self) -> String { let handler = &self.tcx.sess.parse_sess.span_diagnostic; @@ -1500,7 +1497,7 @@ impl ResourceExhaustionExt2<'_> { } } -impl AddToDiagnostic for ResourceExhaustionExt2<'_> { +impl AddToDiagnostic for ResourceExhaustionExt<'_> { fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 6acb338ddef6e..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::InterpErrorExt2; +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 82a7a1aeac3ee..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::InterpErrorExt2; +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,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { op } Err(e) => { - let err = InterpErrorExt2 { + let err = InterpErrorExt { err: e.into_kind(), span: self.ecx.cur_span(), tcx: *self.ecx.tcx, diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index d70cb7dc00779..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::InterpErrorExt2; +use rustc_const_eval::InterpErrorExt; use rustc_hir::def::DefKind; use rustc_hir::HirId; use rustc_index::bit_set::BitSet; @@ -233,7 +233,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { op } Err(e) => { - let err = InterpErrorExt2 { + let err = InterpErrorExt { err: e.into_kind(), span: self.ecx.cur_span(), tcx: *self.ecx.tcx, diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 16c78785dba5f..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::InterpErrorExt2; +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,7 +336,7 @@ 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 = InterpErrorExt2{ + let e = InterpErrorExt{ err: e, span: ecx.cur_span(), tcx: *ecx.tcx,