From 6af8e46a9af03b94baec980d188798a58f3eb75c Mon Sep 17 00:00:00 2001 From: nidnogg Date: Thu, 18 Aug 2022 01:54:11 -0300 Subject: [PATCH 01/49] Finished const_eval module migration, moving onto sibling folders --- compiler/rustc_const_eval/src/const_eval/mod.rs | 12 ++++++------ compiler/rustc_const_eval/src/errors.rs | 8 ++++++++ .../locales/en-US/const_eval.ftl | 2 ++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 948c334949826..57867f77a02e4 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,16 +1,16 @@ // Not in interpret to make sure we do not use private implementation details +use crate::errors::MaxNumNodesExceeded; +use crate::interpret::{ + intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta, + Scalar, +}; use rustc_hir::Mutability; use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{source_map::DUMMY_SP, symbol::Symbol}; -use crate::interpret::{ - intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta, - Scalar, -}; - mod error; mod eval_queries; mod fn_queries; @@ -77,7 +77,7 @@ pub(crate) fn eval_to_valtree<'tcx>( ValTreeCreationError::NodesOverflow => { let msg = format!("maximum number of nodes exceeded in constant {}", &s); let mut diag = match tcx.hir().span_if_local(did) { - Some(span) => tcx.sess.struct_span_err(span, &msg), + Some(span) => tcx.sess.create_err(MaxNumNodesExceeded { span, s }), None => tcx.sess.struct_err(&msg), }; diag.emit(); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 01619dee0e42f..1a0faad2c2c55 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -87,3 +87,11 @@ pub(crate) struct TransientMutBorrowErrRaw { pub span: Span, pub kind: ConstContext, } + +#[derive(SessionDiagnostic)] +#[error(const_eval::const_evaL_max_num_nodes_exceeded)] +pub(crate) struct MaxNumNodesExceeded { + #[primary_span] + pub span: Span, + pub s: String, +} diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index 341f05efefdfb..37abbe321bd68 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -29,3 +29,5 @@ const_eval_mut_deref = const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s + +const_evaL_max_num_nodes_exceeded = maximum number of nodes exceeded in constant {$s} From 70ea98633e44b1220e40c1e8bcdc82edcc18da77 Mon Sep 17 00:00:00 2001 From: nidnogg Date: Thu, 18 Aug 2022 02:11:52 -0300 Subject: [PATCH 02/49] Migrated Unallowed function pointer calls in interpreter/ops --- compiler/rustc_const_eval/src/errors.rs | 8 ++++++++ .../rustc_const_eval/src/transform/check_consts/ops.rs | 7 ++----- .../rustc_error_messages/locales/en-US/const_eval.ftl | 2 ++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 1a0faad2c2c55..728d890ca60da 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -95,3 +95,11 @@ pub(crate) struct MaxNumNodesExceeded { pub span: Span, pub s: String, } + +#[derive(SessionDiagnostic)] +#[error(const_eval::unallowed_fn_pointer_call)] +pub(crate) struct UnallowedFnPointerCall { + #[primary_span] + pub span: Span, + pub kind: ConstContext, +} diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index c9cfc1f3f469c..ba7f2d072770d 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -25,7 +25,7 @@ use rustc_trait_selection::traits::SelectionContext; use super::ConstCx; use crate::errors::{ MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr, - TransientMutBorrowErr, TransientMutBorrowErrRaw, + TransientMutBorrowErr, TransientMutBorrowErrRaw, UnallowedFnPointerCall, }; use crate::util::{call_kind, CallDesugaringKind, CallKind}; @@ -97,10 +97,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - ccx.tcx.sess.struct_span_err( - span, - &format!("function pointer calls are not allowed in {}s", ccx.const_kind()), - ) + ccx.tcx.sess.create_err(UnallowedFnPointerCall { span, kind: ccx.const_kind() }) } } diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index 37abbe321bd68..5bd41dffdb5d0 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -31,3 +31,5 @@ const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s const_evaL_max_num_nodes_exceeded = maximum number of nodes exceeded in constant {$s} + +const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$const_kind}s \ No newline at end of file From 33e8aaf830578d71ac55c6e612dbcff7aef766d2 Mon Sep 17 00:00:00 2001 From: nidnogg Date: Thu, 18 Aug 2022 22:49:59 -0300 Subject: [PATCH 03/49] Migration on ops.rs for unstable const functions --- compiler/rustc_const_eval/src/errors.rs | 8 ++++++++ .../rustc_const_eval/src/transform/check_consts/ops.rs | 8 +++----- .../rustc_error_messages/locales/en-US/const_eval.ftl | 4 +++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 728d890ca60da..19e9e33ab8005 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -103,3 +103,11 @@ pub(crate) struct UnallowedFnPointerCall { pub span: Span, pub kind: ConstContext, } + +#[derive(SessionDiagnostic)] +#[error(const_eval::unstable_const_fn)] +pub(crate) struct UnstableConstFn { + #[primary_span] + pub span: Span, + pub def_id: String, +} diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index ba7f2d072770d..22d681fd33679 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -25,7 +25,7 @@ use rustc_trait_selection::traits::SelectionContext; use super::ConstCx; use crate::errors::{ MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr, - TransientMutBorrowErr, TransientMutBorrowErrRaw, UnallowedFnPointerCall, + TransientMutBorrowErr, TransientMutBorrowErrRaw, UnallowedFnPointerCall, UnstableConstFn, }; use crate::util::{call_kind, CallDesugaringKind, CallKind}; @@ -351,10 +351,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let FnCallUnstable(def_id, feature) = *self; - let mut err = ccx.tcx.sess.struct_span_err( - span, - &format!("`{}` is not yet stable as a const fn", ccx.tcx.def_path_str(def_id)), - ); + let mut err = + ccx.tcx.sess.create_err(UnstableConstFn { span, def_id: ccx.tcx.def_path_str(def_id) }); if ccx.is_const_stable_const_fn() { err.help("const-stable functions can only call other const-stable functions"); diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index 5bd41dffdb5d0..a9d9838a38242 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -32,4 +32,6 @@ const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in const_evaL_max_num_nodes_exceeded = maximum number of nodes exceeded in constant {$s} -const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$const_kind}s \ No newline at end of file +const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$kind}s + +const_eval_unstable_const_fn = `{$def_id}` is not yet stable as a const fn \ No newline at end of file From d1f14ee1b01dd39cd79cd9cdd71e91ba521901fe Mon Sep 17 00:00:00 2001 From: nidnogg Date: Fri, 19 Aug 2022 15:36:09 -0300 Subject: [PATCH 04/49] Added several more migrations under ops.rs, failing some tests though --- compiler/rustc_const_eval/src/errors.rs | 81 +++++++++ .../src/transform/check_consts/ops.rs | 154 +++++++----------- .../locales/en-US/const_eval.ftl | 50 +++++- 3 files changed, 187 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 19e9e33ab8005..7fa6a67a7f91d 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -111,3 +111,84 @@ pub(crate) struct UnstableConstFn { pub span: Span, pub def_id: String, } + +#[derive(SessionDiagnostic)] +#[error(const_eval::unallowed_mutable_refs, code = "E0764")] +pub(crate) struct UnallowedMutableRefs { + #[primary_span] + pub span: Span, + pub kind: ConstContext, + #[note(const_eval::teach_note)] + pub teach: Option<()>, +} + +#[derive(SessionDiagnostic)] +#[error(const_eval::unallowed_mutable_refs_raw, code = "E0764")] +pub(crate) struct UnallowedMutableRefsRaw { + #[primary_span] + pub span: Span, + pub kind: ConstContext, + #[note(const_eval::teach_note)] + pub teach: Option<()>, +} +#[derive(SessionDiagnostic)] +#[error(const_eval::non_const_fmt_macro_call, code = "E0015")] +pub(crate) struct NonConstFmtMacroCall { + #[primary_span] + pub span: Span, + pub kind: ConstContext, +} + +#[derive(SessionDiagnostic)] +#[error(const_eval::non_const_fn_call, code = "E0015")] +pub(crate) struct NonConstFnCall { + #[primary_span] + pub span: Span, + pub def_path_str: String, + pub kind: ConstContext, +} + +#[derive(SessionDiagnostic)] +#[error(const_eval::unallowed_op_in_const_context)] +pub(crate) struct UnallowedOpInConstContext { + #[primary_span] + pub span: Span, + pub msg: String, +} + +#[derive(SessionDiagnostic)] +#[error(const_eval::unallowed_heap_allocations, code = "E0010")] +pub(crate) struct UnallowedHeapAllocations { + #[primary_span] + pub span: Span, + pub kind: ConstContext, + #[note(const_eval::teach_note)] + pub teach: Option<()>, +} + +#[derive(SessionDiagnostic)] +#[error(const_eval::unallowed_inline_asm, code = "E0015")] +pub(crate) struct UnallowedInlineAsm { + #[primary_span] + pub span: Span, + pub kind: ConstContext, +} + +#[derive(SessionDiagnostic)] +#[error(const_eval::interior_mutable_data_refer, code = "E0492")] +pub(crate) struct InteriorMutableDataRefer { + #[primary_span] + pub span: Span, + #[help] + pub opt_help: Option<()>, + pub kind: ConstContext, + #[note(const_eval::teach_note)] + pub teach: Option<()>, +} + +#[derive(SessionDiagnostic)] +#[error(const_eval::interior_mutability_borrow)] +pub(crate) struct InteriorMutabilityBorrow { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 22d681fd33679..e2cf9b2b3c14d 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -24,8 +24,11 @@ use rustc_trait_selection::traits::SelectionContext; use super::ConstCx; use crate::errors::{ - MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr, - TransientMutBorrowErr, TransientMutBorrowErrRaw, UnallowedFnPointerCall, UnstableConstFn, + InteriorMutabilityBorrow, InteriorMutableDataRefer, MutDerefErr, NonConstFmtMacroCall, + NonConstFnCall, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr, + TransientMutBorrowErr, TransientMutBorrowErrRaw, UnallowedFnPointerCall, + UnallowedHeapAllocations, UnallowedInlineAsm, UnallowedMutableRefs, UnallowedMutableRefsRaw, + UnallowedOpInConstContext, UnstableConstFn, }; use crate::util::{call_kind, CallDesugaringKind, CallKind}; @@ -305,22 +308,13 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { err } _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentV1Methods) => { - struct_span_err!( - ccx.tcx.sess, - span, - E0015, - "cannot call non-const formatting macro in {}s", - ccx.const_kind(), - ) + ccx.tcx.sess.create_err(NonConstFmtMacroCall { span, kind: ccx.const_kind() }) } - _ => struct_span_err!( - ccx.tcx.sess, + _ => ccx.tcx.sess.create_err(NonConstFnCall { span, - E0015, - "cannot call non-const fn `{}` in {}s", - ccx.tcx.def_path_str_with_substs(callee, substs), - ccx.const_kind(), - ), + def_path_str: ccx.tcx.def_path_str_with_substs(callee, substs), + kind: ccx.const_kind(), + }), }; err.note(&format!( @@ -387,9 +381,12 @@ impl<'tcx> NonConstOp<'tcx> for Generator { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind()); if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 { - feature_err(&ccx.tcx.sess.parse_sess, sym::const_async_blocks, span, &msg) + ccx.tcx.sess.create_feature_err( + UnallowedOpInConstContext { span, msg }, + sym::const_async_blocks, + ) } else { - ccx.tcx.sess.struct_span_err(span, &msg) + ccx.tcx.sess.create_err(UnallowedOpInConstContext { span, msg }) } } } @@ -402,23 +399,11 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - let mut err = struct_span_err!( - ccx.tcx.sess, + ccx.tcx.sess.create_err(UnallowedHeapAllocations { span, - E0010, - "allocations are not allowed in {}s", - ccx.const_kind() - ); - err.span_label(span, format!("allocation not allowed in {}s", ccx.const_kind())); - if ccx.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "The value of statics and constants must be known at compile time, \ - and they live for the entire lifetime of a program. Creating a boxed \ - value allocates memory on the heap at runtime, and therefore cannot \ - be done at compile time.", - ); - } - err + kind: ccx.const_kind(), + teach: ccx.tcx.sess.teach(&error_code!(E0010)).then_some(()), + }) } } @@ -430,13 +415,7 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - struct_span_err!( - ccx.tcx.sess, - span, - E0015, - "inline assembly is not allowed in {}s", - ccx.const_kind() - ) + ccx.tcx.sess.create_err(UnallowedInlineAsm { span, kind: ccx.const_kind() }) } } @@ -482,12 +461,7 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - feature_err( - &ccx.tcx.sess.parse_sess, - sym::const_refs_to_cell, - span, - "cannot borrow here, since the borrowed element may contain interior mutability", - ) + ccx.tcx.sess.create_feature_err(InteriorMutabilityBorrow { span }, sym::const_refs_to_cell) } } @@ -502,32 +476,22 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - let mut err = struct_span_err!( - ccx.tcx.sess, - span, - E0492, - "{}s cannot refer to interior mutable data", - ccx.const_kind(), - ); - err.span_label( - span, - "this borrow of an interior mutable value may end up in the final value", - ); + // FIXME: Maybe a more elegant solution to this if else case if let hir::ConstContext::Static(_) = ccx.const_kind() { - err.help( - "to fix this, the value can be extracted to a separate \ - `static` item and then referenced", - ); - } - if ccx.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "A constant containing interior mutable data behind a reference can allow you - to modify that data. This would make multiple uses of a constant to be able to - see different values and allow circumventing the `Send` and `Sync` requirements - for shared mutable data, which is unsound.", - ); + ccx.tcx.sess.create_err(InteriorMutableDataRefer { + span, + opt_help: Some(()), + kind: ccx.const_kind(), + teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()), + }) + } else { + ccx.tcx.sess.create_err(InteriorMutableDataRefer { + span, + opt_help: None, + kind: ccx.const_kind(), + teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()), + }) } - err } } @@ -553,33 +517,29 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - let raw = match self.0 { - hir::BorrowKind::Raw => "raw ", - hir::BorrowKind::Ref => "", - }; - - let mut err = struct_span_err!( - ccx.tcx.sess, - span, - E0764, - "{}mutable references are not allowed in the final value of {}s", - raw, - ccx.const_kind(), - ); - - if ccx.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "References in statics and constants may only refer \ - to immutable values.\n\n\ - Statics are shared everywhere, and if they refer to \ - mutable data one might violate memory safety since \ - holding multiple mutable references to shared data \ - is not allowed.\n\n\ - If you really want global mutable state, try using \ - static mut or a global UnsafeCell.", - ); + // let raw = match self.0 { + // hir::BorrowKind::Raw => "raw ", + // hir::BorrowKind::Ref => "", + // }; + + // ccx.tcx.sess.create_err(UnallowedMutableRefs { + // span, + // raw, + // kind: ccx.const_kind(), + // teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()), + // }) + match self.0 { + hir::BorrowKind::Raw => ccx.tcx.sess.create_err(UnallowedMutableRefsRaw { + span, + kind: ccx.const_kind(), + teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()), + }), + hir::BorrowKind::Ref => ccx.tcx.sess.create_err(UnallowedMutableRefs { + span, + kind: ccx.const_kind(), + teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()), + }), } - err } } diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index a9d9838a38242..24604869dd13a 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -34,4 +34,52 @@ const_evaL_max_num_nodes_exceeded = maximum number of nodes exceeded in constant const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$kind}s -const_eval_unstable_const_fn = `{$def_id}` is not yet stable as a const fn \ No newline at end of file +const_eval_unstable_const_fn = `{$def_id}` is not yet stable as a const fn + +const_eval_unallowed_mutable_refs = + mutable references are not allowed in the final value of {$kind}s + .teach_note = + References in statics and constants may only refer to immutable values.\n\n + Statics are shared everywhere, and if they refer to mutable data one might violate memory + safety since holding multiple mutable references to shared data is not allowed.\n\n + If you really want global mutable state, try using static mut or a global UnsafeCell. + +const_eval_unallowed_mutable_refs_raw = + raw mutable references are not allowed in the final value of {$kind}s + .teach_note = + References in statics and constants may only refer to immutable values.\n\n + Statics are shared everywhere, and if they refer to mutable data one might violate memory + safety since holding multiple mutable references to shared data is not allowed.\n\n + If you really want global mutable state, try using static mut or a global UnsafeCell. + +const_eval_non_const_fmt_macro_call = + cannot call non-const formatting macro in {$kind}s + +const_eval_non_const_fn_call = + cannot call non-const fn `{$def_path_str}` in {$kind}s + +const_eval_unallowed_op_in_const_context = + {$msg} + +const_eval_unallowed_heap_allocations = + allocations are not allowed in {$kind}s + .label = allocation not allowed in {$kind}s + .teach_note = + The value of statics and constants must be known at compile time, and they live for the entire + lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and + therefore cannot be done at compile time. + +const_eval_unallowed_inline_asm = + inline assembly is not allowed in {$kind}s + +const_eval_interior_mutable_data_refer = + {$kind}s cannot refer to interior mutable data + .label = this borrow of an interior mutable value may end up in the final value + .help = to fix this, the value can be extracted to a separate `static` item and then referenced + .teach_note = + A constant containing interior mutable data behind a reference can allow you to modify that data. + This would make multiple uses of a constant to be able to see different values and allow circumventing + the `Send` and `Sync` requirements for shared mutable data, which is unsound. + +const_eval_interior_mutability_borrow = + cannot borrow here, since the borrowed element may contain interior mutability \ No newline at end of file From 4c82845b3ac583377b871bf01dc07ec513c466fe Mon Sep 17 00:00:00 2001 From: nidnogg Date: Sat, 20 Aug 2022 16:27:41 -0300 Subject: [PATCH 05/49] Fixed failing tests (missing labels), added automatic error code in create_feature_err() builder --- compiler/rustc_const_eval/src/const_eval/mod.rs | 4 ++-- compiler/rustc_const_eval/src/errors.rs | 8 +++++--- .../src/transform/check_consts/ops.rs | 17 ++++------------- .../locales/en-US/const_eval.ftl | 8 +++----- compiler/rustc_session/src/session.rs | 5 +++-- 5 files changed, 17 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 57867f77a02e4..9041d55155eae 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,6 +1,6 @@ // Not in interpret to make sure we do not use private implementation details -use crate::errors::MaxNumNodesExceeded; +use crate::errors::MaxNumNodesInConstErr; use crate::interpret::{ intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta, Scalar, @@ -77,7 +77,7 @@ pub(crate) fn eval_to_valtree<'tcx>( ValTreeCreationError::NodesOverflow => { let msg = format!("maximum number of nodes exceeded in constant {}", &s); let mut diag = match tcx.hir().span_if_local(did) { - Some(span) => tcx.sess.create_err(MaxNumNodesExceeded { span, s }), + Some(span) => tcx.sess.create_err(MaxNumNodesInConstErr { span, s }), None => tcx.sess.struct_err(&msg), }; diag.emit(); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 7fa6a67a7f91d..7e1cf4ef1aab8 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -89,8 +89,8 @@ pub(crate) struct TransientMutBorrowErrRaw { } #[derive(SessionDiagnostic)] -#[error(const_eval::const_evaL_max_num_nodes_exceeded)] -pub(crate) struct MaxNumNodesExceeded { +#[error(const_eval::const_evaL_max_num_nodes_in_const_err)] +pub(crate) struct MaxNumNodesInConstErr { #[primary_span] pub span: Span, pub s: String, @@ -109,7 +109,7 @@ pub(crate) struct UnallowedFnPointerCall { pub(crate) struct UnstableConstFn { #[primary_span] pub span: Span, - pub def_id: String, + pub def_path: String, } #[derive(SessionDiagnostic)] @@ -160,6 +160,7 @@ pub(crate) struct UnallowedOpInConstContext { #[error(const_eval::unallowed_heap_allocations, code = "E0010")] pub(crate) struct UnallowedHeapAllocations { #[primary_span] + #[label] pub span: Span, pub kind: ConstContext, #[note(const_eval::teach_note)] @@ -178,6 +179,7 @@ pub(crate) struct UnallowedInlineAsm { #[error(const_eval::interior_mutable_data_refer, code = "E0492")] pub(crate) struct InteriorMutableDataRefer { #[primary_span] + #[label] pub span: Span, #[help] pub opt_help: Option<()>, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index e2cf9b2b3c14d..5fb4bf638b342 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -345,8 +345,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let FnCallUnstable(def_id, feature) = *self; - let mut err = - ccx.tcx.sess.create_err(UnstableConstFn { span, def_id: ccx.tcx.def_path_str(def_id) }); + let mut err = ccx + .tcx + .sess + .create_err(UnstableConstFn { span, def_path: ccx.tcx.def_path_str(def_id) }); if ccx.is_const_stable_const_fn() { err.help("const-stable functions can only call other const-stable functions"); @@ -517,17 +519,6 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow { ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - // let raw = match self.0 { - // hir::BorrowKind::Raw => "raw ", - // hir::BorrowKind::Ref => "", - // }; - - // ccx.tcx.sess.create_err(UnallowedMutableRefs { - // span, - // raw, - // kind: ccx.const_kind(), - // teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()), - // }) match self.0 { hir::BorrowKind::Raw => ccx.tcx.sess.create_err(UnallowedMutableRefsRaw { span, diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index 24604869dd13a..b8e4199dc1c2a 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -30,11 +30,11 @@ const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s -const_evaL_max_num_nodes_exceeded = maximum number of nodes exceeded in constant {$s} +const_evaL_max_num_nodes_in_const_err = maximum number of nodes exceeded in constant {$s} const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$kind}s -const_eval_unstable_const_fn = `{$def_id}` is not yet stable as a const fn +const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn const_eval_unallowed_mutable_refs = mutable references are not allowed in the final value of {$kind}s @@ -65,9 +65,7 @@ const_eval_unallowed_heap_allocations = allocations are not allowed in {$kind}s .label = allocation not allowed in {$kind}s .teach_note = - The value of statics and constants must be known at compile time, and they live for the entire - lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and - therefore cannot be done at compile time. + The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time. const_eval_unallowed_inline_asm = inline assembly is not allowed in {$kind}s diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 80de451276c2c..743b9f429e2bb 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -20,8 +20,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{ - fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee, - ErrorGuaranteed, FluentBundle, LazyFallbackBundle, MultiSpan, + error_code, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, + EmissionGuarantee, ErrorGuaranteed, FluentBundle, LazyFallbackBundle, MultiSpan, }; use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; @@ -467,6 +467,7 @@ impl Session { feature: Symbol, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = self.parse_sess.create_err(err); + err.code = std::option::Option::Some(error_code!(E0658)); add_feature_diagnostics(&mut err, &self.parse_sess, feature); err } From 0a58b26e8a296a4f03d55ae0469ce4da9a6080a6 Mon Sep 17 00:00:00 2001 From: nidnogg Date: Sun, 21 Aug 2022 13:08:14 -0300 Subject: [PATCH 06/49] Hotfix ftl err name, added check for err.code in create_feature_err --- compiler/rustc_const_eval/src/errors.rs | 2 +- compiler/rustc_error_messages/locales/en-US/const_eval.ftl | 2 +- compiler/rustc_session/src/session.rs | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 7e1cf4ef1aab8..d0af304f109f5 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -89,7 +89,7 @@ pub(crate) struct TransientMutBorrowErrRaw { } #[derive(SessionDiagnostic)] -#[error(const_eval::const_evaL_max_num_nodes_in_const_err)] +#[error(const_eval::max_num_nodes_in_const)] pub(crate) struct MaxNumNodesInConstErr { #[primary_span] pub span: Span, diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index b8e4199dc1c2a..8a5e1a7a95709 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -30,7 +30,7 @@ const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s -const_evaL_max_num_nodes_in_const_err = maximum number of nodes exceeded in constant {$s} +const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$s} const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$kind}s diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 743b9f429e2bb..edb187ec3f7c5 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -467,7 +467,9 @@ impl Session { feature: Symbol, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = self.parse_sess.create_err(err); - err.code = std::option::Option::Some(error_code!(E0658)); + if err.code.is_none() { + err.code = std::option::Option::Some(error_code!(E0658)); + } add_feature_diagnostics(&mut err, &self.parse_sess, feature); err } From 13abae2deba8cd27cdc9ec81f4291c9047eaa7e1 Mon Sep 17 00:00:00 2001 From: nidnogg Date: Mon, 22 Aug 2022 00:02:36 -0300 Subject: [PATCH 07/49] Switched errors to diags according to latest PRs --- compiler/rustc_const_eval/src/errors.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index d0af304f109f5..c6e0021958251 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -89,7 +89,7 @@ pub(crate) struct TransientMutBorrowErrRaw { } #[derive(SessionDiagnostic)] -#[error(const_eval::max_num_nodes_in_const)] +#[diag(const_eval::max_num_nodes_in_const)] pub(crate) struct MaxNumNodesInConstErr { #[primary_span] pub span: Span, @@ -97,7 +97,7 @@ pub(crate) struct MaxNumNodesInConstErr { } #[derive(SessionDiagnostic)] -#[error(const_eval::unallowed_fn_pointer_call)] +#[diag(const_eval::unallowed_fn_pointer_call)] pub(crate) struct UnallowedFnPointerCall { #[primary_span] pub span: Span, @@ -105,7 +105,7 @@ pub(crate) struct UnallowedFnPointerCall { } #[derive(SessionDiagnostic)] -#[error(const_eval::unstable_const_fn)] +#[diag(const_eval::unstable_const_fn)] pub(crate) struct UnstableConstFn { #[primary_span] pub span: Span, @@ -113,7 +113,7 @@ pub(crate) struct UnstableConstFn { } #[derive(SessionDiagnostic)] -#[error(const_eval::unallowed_mutable_refs, code = "E0764")] +#[diag(const_eval::unallowed_mutable_refs, code = "E0764")] pub(crate) struct UnallowedMutableRefs { #[primary_span] pub span: Span, @@ -123,7 +123,7 @@ pub(crate) struct UnallowedMutableRefs { } #[derive(SessionDiagnostic)] -#[error(const_eval::unallowed_mutable_refs_raw, code = "E0764")] +#[diag(const_eval::unallowed_mutable_refs_raw, code = "E0764")] pub(crate) struct UnallowedMutableRefsRaw { #[primary_span] pub span: Span, @@ -132,7 +132,7 @@ pub(crate) struct UnallowedMutableRefsRaw { pub teach: Option<()>, } #[derive(SessionDiagnostic)] -#[error(const_eval::non_const_fmt_macro_call, code = "E0015")] +#[diag(const_eval::non_const_fmt_macro_call, code = "E0015")] pub(crate) struct NonConstFmtMacroCall { #[primary_span] pub span: Span, @@ -140,7 +140,7 @@ pub(crate) struct NonConstFmtMacroCall { } #[derive(SessionDiagnostic)] -#[error(const_eval::non_const_fn_call, code = "E0015")] +#[diag(const_eval::non_const_fn_call, code = "E0015")] pub(crate) struct NonConstFnCall { #[primary_span] pub span: Span, @@ -149,7 +149,7 @@ pub(crate) struct NonConstFnCall { } #[derive(SessionDiagnostic)] -#[error(const_eval::unallowed_op_in_const_context)] +#[diag(const_eval::unallowed_op_in_const_context)] pub(crate) struct UnallowedOpInConstContext { #[primary_span] pub span: Span, @@ -157,7 +157,7 @@ pub(crate) struct UnallowedOpInConstContext { } #[derive(SessionDiagnostic)] -#[error(const_eval::unallowed_heap_allocations, code = "E0010")] +#[diag(const_eval::unallowed_heap_allocations, code = "E0010")] pub(crate) struct UnallowedHeapAllocations { #[primary_span] #[label] @@ -168,7 +168,7 @@ pub(crate) struct UnallowedHeapAllocations { } #[derive(SessionDiagnostic)] -#[error(const_eval::unallowed_inline_asm, code = "E0015")] +#[diag(const_eval::unallowed_inline_asm, code = "E0015")] pub(crate) struct UnallowedInlineAsm { #[primary_span] pub span: Span, @@ -176,7 +176,7 @@ pub(crate) struct UnallowedInlineAsm { } #[derive(SessionDiagnostic)] -#[error(const_eval::interior_mutable_data_refer, code = "E0492")] +#[diag(const_eval::interior_mutable_data_refer, code = "E0492")] pub(crate) struct InteriorMutableDataRefer { #[primary_span] #[label] @@ -189,7 +189,7 @@ pub(crate) struct InteriorMutableDataRefer { } #[derive(SessionDiagnostic)] -#[error(const_eval::interior_mutability_borrow)] +#[diag(const_eval::interior_mutability_borrow)] pub(crate) struct InteriorMutabilityBorrow { #[primary_span] pub span: Span, From d197c1eb5bee2d4c2c27c895f5e496df935ccbd0 Mon Sep 17 00:00:00 2001 From: Rejyr Date: Fri, 19 Aug 2022 15:50:38 -0400 Subject: [PATCH 08/49] migrate: `UnknownTool` error to `SessionDiagnostic` --- .../locales/en-US/lint.ftl | 3 +++ compiler/rustc_lint/src/errors.rs | 13 +++++++++ compiler/rustc_lint/src/levels.rs | 27 ++++++++----------- compiler/rustc_lint/src/lib.rs | 3 +++ 4 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 compiler/rustc_lint/src/errors.rs diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 9731711471664..e0943323adee9 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -393,3 +393,6 @@ lint_builtin_deref_nullptr = dereferencing a null pointer .label = this code causes undefined behavior when executed lint_builtin_asm_labels = avoid using named labels in inline assembly + +lint_unknown_tool = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}` + .help = add `#![register_tool({$tool_name})]` to the crate root diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs new file mode 100644 index 0000000000000..3f4d856a1ccc7 --- /dev/null +++ b/compiler/rustc_lint/src/errors.rs @@ -0,0 +1,13 @@ +use rustc_macros::SessionDiagnostic; +use rustc_span::Span; + +#[derive(SessionDiagnostic)] +#[error(lint::unknown_tool, code = "E0710")] +pub struct UnknownTool { + #[primary_span] + pub span: Option, + pub tool_name: String, + pub lint_name: String, + #[help] + pub is_nightly_build: Option<()>, +} diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 1cabb58bbebfd..3db88b7ace439 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::diagnostic_outside_of_impl)] +// #![deny(rustc::untranslatable_diagnostic)] +// use crate::context::{CheckLintNameResult, LintStore}; use crate::late::unerased_lint_store; use rustc_ast as ast; @@ -23,6 +26,8 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use tracing::debug; +use crate::errors::UnknownTool; + fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap { let store = unerased_lint_store(tcx); let levels = @@ -485,22 +490,12 @@ impl<'s> LintLevelsBuilder<'s> { } &CheckLintNameResult::NoTool => { - let mut err = struct_span_err!( - sess, - tool_ident.map_or(DUMMY_SP, |ident| ident.span), - E0710, - "unknown tool name `{}` found in scoped lint: `{}::{}`", - tool_name.unwrap(), - tool_name.unwrap(), - pprust::path_to_string(&meta_item.path), - ); - if sess.is_nightly_build() { - err.help(&format!( - "add `#![register_tool({})]` to the crate root", - tool_name.unwrap() - )); - } - err.emit(); + sess.emit_err(UnknownTool { + span: tool_ident.map(|ident| ident.span), + tool_name: tool_name.unwrap().to_string(), + lint_name: pprust::path_to_string(&meta_item.path), + is_nightly_build: sess.is_nightly_build().then_some(()), + }); continue; } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index f087c624917e8..23fd5d5eea081 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -36,6 +36,8 @@ #![feature(let_else)] #![feature(never_type)] #![recursion_limit = "256"] +// #![deny(rustc::diagnostic_outside_of_impl)] +// #![deny(rustc::untranslatable_diagnostic)] #[macro_use] extern crate rustc_middle; @@ -47,6 +49,7 @@ pub mod builtin; mod context; mod early; mod enum_intrinsics_non_enums; +mod errors; mod expect; pub mod hidden_unicode_codepoints; mod internal; From 874a79fae30ec93bcd9847187741378c405bd9da Mon Sep 17 00:00:00 2001 From: Rejyr Date: Fri, 19 Aug 2022 17:17:14 -0400 Subject: [PATCH 09/49] migrate: `bad_attr` to `SessionDiagnostic` --- .../locales/en-US/lint.ftl | 8 ++++ compiler/rustc_lint/src/errors.rs | 21 +++++++++- compiler/rustc_lint/src/levels.rs | 42 +++++++++++-------- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index e0943323adee9..4569ce82e3ef3 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -394,5 +394,13 @@ lint_builtin_deref_nullptr = dereferencing a null pointer lint_builtin_asm_labels = avoid using named labels in inline assembly +lint_malformed_attribute = malformed lint attribute input + +lint_bad_attribute_argument = bad attribute argument + +lint_reason_must_be_string_literal = reason must be a string literal + +lint_reason_must_come_last = reason in lint attribute must come last + lint_unknown_tool = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}` .help = add `#![register_tool({$tool_name})]` to the crate root diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 3f4d856a1ccc7..679cfad4961eb 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -1,6 +1,25 @@ -use rustc_macros::SessionDiagnostic; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::Span; +#[derive(SessionDiagnostic)] +#[error(lint::malformed_attribute, code = "E0452")] +pub struct MalformedAttribute { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub sub: MalformedAttributeSub, +} + +#[derive(SessionSubdiagnostic)] +pub enum MalformedAttributeSub { + #[label(lint::bad_attribute_argument)] + BadAttributeArgument(#[primary_span] Span), + #[label(lint::reason_must_be_string_literal)] + ReasonMustBeStringLiteral(#[primary_span] Span), + #[label(lint::reason_must_come_last)] + ReasonMustComeLast(#[primary_span] Span), +} + #[derive(SessionDiagnostic)] #[error(lint::unknown_tool, code = "E0710")] pub struct UnknownTool { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 3db88b7ace439..2dd4d2b34cc21 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -26,7 +26,7 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use tracing::debug; -use crate::errors::UnknownTool; +use crate::errors::{MalformedAttribute, MalformedAttributeSub, UnknownTool}; fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap { let store = unerased_lint_store(tcx); @@ -271,7 +271,7 @@ impl<'s> LintLevelsBuilder<'s> { self.cur = self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev }); let sess = self.sess; - let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); + // let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); for (attr_index, attr) in attrs.iter().enumerate() { if attr.has_name(sym::automatically_derived) { self.current_specs_mut().insert( @@ -322,20 +322,27 @@ impl<'s> LintLevelsBuilder<'s> { } reason = Some(rationale); } else { - bad_attr(name_value.span) - .span_label(name_value.span, "reason must be a string literal") - .emit(); + sess.emit_err(MalformedAttribute { + span: name_value.span, + sub: MalformedAttributeSub::ReasonMustBeStringLiteral( + name_value.span, + ), + }); } // found reason, reslice meta list to exclude it metas.pop().unwrap(); } else { - bad_attr(item.span) - .span_label(item.span, "bad attribute argument") - .emit(); + sess.emit_err(MalformedAttribute { + span: item.span, + sub: MalformedAttributeSub::BadAttributeArgument(item.span), + }); } } ast::MetaItemKind::List(_) => { - bad_attr(item.span).span_label(item.span, "bad attribute argument").emit(); + sess.emit_err(MalformedAttribute { + span: item.span, + sub: MalformedAttributeSub::BadAttributeArgument(item.span), + }); } } } @@ -353,20 +360,21 @@ impl<'s> LintLevelsBuilder<'s> { let meta_item = match li { ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item, _ => { - let mut err = bad_attr(sp); - let mut add_label = true; if let Some(item) = li.meta_item() { if let ast::MetaItemKind::NameValue(_) = item.kind { if item.path == sym::reason { - err.span_label(sp, "reason in lint attribute must come last"); - add_label = false; + sess.emit_err(MalformedAttribute { + span: sp, + sub: MalformedAttributeSub::ReasonMustComeLast(sp), + }); + continue; } } } - if add_label { - err.span_label(sp, "bad attribute argument"); - } - err.emit(); + sess.emit_err(MalformedAttribute { + span: sp, + sub: MalformedAttributeSub::BadAttributeArgument(sp), + }); continue; } }; From 6f83ec88e63b15f9cb34e63a5e149c5b826d6310 Mon Sep 17 00:00:00 2001 From: Rejyr Date: Fri, 19 Aug 2022 19:52:20 -0400 Subject: [PATCH 10/49] change: diagnostic `String` field to `Symbol` --- compiler/rustc_lint/src/errors.rs | 2 +- compiler/rustc_lint/src/levels.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 679cfad4961eb..4738e8e82b610 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -25,7 +25,7 @@ pub enum MalformedAttributeSub { pub struct UnknownTool { #[primary_span] pub span: Option, - pub tool_name: String, + pub tool_name: Symbol, pub lint_name: String, #[help] pub is_nightly_build: Option<()>, diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 2dd4d2b34cc21..07e9eab62f3bf 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -271,7 +271,6 @@ impl<'s> LintLevelsBuilder<'s> { self.cur = self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev }); let sess = self.sess; - // let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); for (attr_index, attr) in attrs.iter().enumerate() { if attr.has_name(sym::automatically_derived) { self.current_specs_mut().insert( @@ -500,7 +499,7 @@ impl<'s> LintLevelsBuilder<'s> { &CheckLintNameResult::NoTool => { sess.emit_err(UnknownTool { span: tool_ident.map(|ident| ident.span), - tool_name: tool_name.unwrap().to_string(), + tool_name: tool_name.unwrap(), lint_name: pprust::path_to_string(&meta_item.path), is_nightly_build: sess.is_nightly_build().then_some(()), }); From 32e445af7499fa470961f30750942398bf51d198 Mon Sep 17 00:00:00 2001 From: Rejyr Date: Fri, 19 Aug 2022 20:04:21 -0400 Subject: [PATCH 11/49] hotfix: add missing import --- compiler/rustc_lint/src/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 4738e8e82b610..2d7ec992f2b5f 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -1,5 +1,5 @@ use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic)] #[error(lint::malformed_attribute, code = "E0452")] From 7a6ae2367d3b3442a7ae36e53551b58a9ece7155 Mon Sep 17 00:00:00 2001 From: Rejyr Date: Fri, 19 Aug 2022 20:47:05 -0400 Subject: [PATCH 12/49] migrate: `OverruledAttribute` --- .../locales/en-US/lint.ftl | 10 +++++ compiler/rustc_lint/src/errors.rs | 40 +++++++++++++++++++ compiler/rustc_lint/src/levels.rs | 37 +++++++++++------ 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 4569ce82e3ef3..cb393d67193b9 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -394,6 +394,16 @@ lint_builtin_deref_nullptr = dereferencing a null pointer lint_builtin_asm_labels = avoid using named labels in inline assembly +lint_overruled_attribute = {$lint_level}({$lint_source}) incompatible with previous forbid + .label = overruled by previous forbid + +lint_default_source = `forbid` lint level is the default for {$id} + +lint_node_source = `forbid` level set here + .note = {$reason} + +lint_command_line_source = `forbid` lint level was set on command line + lint_malformed_attribute = malformed lint attribute input lint_bad_attribute_argument = bad attribute argument diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 2d7ec992f2b5f..bb4e23e29e7a3 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -1,6 +1,46 @@ +use rustc_errors::{fluent, AddSubdiagnostic}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::{Span, Symbol}; +#[derive(SessionDiagnostic)] +#[error(lint::overruled_attribute, code = "E0453")] +pub struct OverruledAttribute { + #[primary_span] + pub span: Span, + #[label] + pub overruled: Span, + pub lint_level: String, + pub lint_source: Symbol, + #[subdiagnostic] + pub sub: OverruledAttributeSub, +} +// +pub enum OverruledAttributeSub { + DefaultSource { id: String }, + NodeSource { span: Span, reason: Option }, + CommandLineSource, +} + +impl AddSubdiagnostic for OverruledAttributeSub { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + match self { + OverruledAttributeSub::DefaultSource { id } => { + diag.note(fluent::lint::default_source); + diag.set_arg("id", id); + } + OverruledAttributeSub::NodeSource { span, reason } => { + diag.span_label(span, fluent::lint::node_source); + if let Some(rationale) = reason { + diag.note(rationale.as_str()); + } + } + OverruledAttributeSub::CommandLineSource => { + diag.note(fluent::lint::command_line_source); + } + } + } +} + #[derive(SessionDiagnostic)] #[error(lint::malformed_attribute, code = "E0452")] pub struct MalformedAttribute { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 07e9eab62f3bf..2bafe64c1394a 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -6,7 +6,7 @@ use crate::late::unerased_lint_store; use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, LintDiagnosticBuilder, MultiSpan}; +use rustc_errors::{Applicability, Diagnostic, LintDiagnosticBuilder, MultiSpan}; use rustc_hir as hir; use rustc_hir::{intravisit, HirId}; use rustc_middle::hir::nested_filter; @@ -26,7 +26,10 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use tracing::debug; -use crate::errors::{MalformedAttribute, MalformedAttributeSub, UnknownTool}; +use crate::errors::{ + MalformedAttribute, MalformedAttributeSub, OverruledAttribute, OverruledAttributeSub, + UnknownTool, +}; fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap { let store = unerased_lint_store(tcx); @@ -191,16 +194,26 @@ impl<'s> LintLevelsBuilder<'s> { } }; if !fcw_warning { - let mut diag_builder = struct_span_err!( - self.sess, - src.span(), - E0453, - "{}({}) incompatible with previous forbid", - level.as_str(), - src.name(), - ); - decorate_diag(&mut diag_builder); - diag_builder.emit(); + self.sess.emit_err(OverruledAttribute { + span: src.span(), + overruled: src.span(), + lint_level: level.as_str().to_string(), + lint_source: src.name(), + sub: match old_src { + LintLevelSource::Default => { + OverruledAttributeSub::DefaultSource { id: id.to_string() } + } + LintLevelSource::Node(_, forbid_source_span, reason) => { + OverruledAttributeSub::NodeSource { + span: forbid_source_span, + reason, + } + } + LintLevelSource::CommandLine(_, _) => { + OverruledAttributeSub::CommandLineSource + } + }, + }); } else { self.struct_lint( FORBIDDEN_LINT_GROUPS, From 5d302d11483a7313742d24e024928a37268ed4bd Mon Sep 17 00:00:00 2001 From: Rejyr Date: Sat, 20 Aug 2022 12:11:07 -0400 Subject: [PATCH 13/49] migrate: `BuiltinEllipsisInclusiveRangePatterns` --- compiler/rustc_lint/src/builtin.rs | 36 +++++++++++------------------- compiler/rustc_lint/src/errors.rs | 10 +++++++++ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index bd58021f78fc0..507abad0d5674 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::diagnostic_outside_of_impl)] +// #![deny(rustc::untranslatable_diagnostic)] +// //! Lints in the Rust compiler. //! //! This contains lints which can feasibly be implemented as their own @@ -21,6 +24,7 @@ //! `late_lint_methods!` invocation in `lib.rs`. use crate::{ + errors::BuiltinEllpisisInclusiveRangePatterns, types::{transparent_newtype_field, CItemKind}, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext, }; @@ -1760,18 +1764,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { None => format!("&(..={})", end), }; if join.edition() >= Edition::Edition2021 { - let mut err = cx.sess().struct_span_err_with_code( - pat.span, - msg, - rustc_errors::error_code!(E0783), - ); - err.span_suggestion( - pat.span, - suggestion, + cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns { + span: pat.span, + suggestion: pat.span, replace, - Applicability::MachineApplicable, - ) - .emit(); + }); } else { cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, |lint| { lint.build(msg) @@ -1787,18 +1784,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { } else { let replace = "..="; if join.edition() >= Edition::Edition2021 { - let mut err = cx.sess().struct_span_err_with_code( - pat.span, - msg, - rustc_errors::error_code!(E0783), - ); - err.span_suggestion_short( - join, - suggestion, - replace, - Applicability::MachineApplicable, - ) - .emit(); + cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns { + span: pat.span, + suggestion: join, + replace: replace.to_string(), + }); } else { cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, |lint| { lint.build(msg) diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index bb4e23e29e7a3..569f68bd5e53b 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -70,3 +70,13 @@ pub struct UnknownTool { #[help] pub is_nightly_build: Option<()>, } + +#[derive(SessionDiagnostic)] +#[error(lint::builtin_ellipsis_inclusive_range_patterns, code = "E0783")] +pub struct BuiltinEllpisisInclusiveRangePatterns { + #[primary_span] + pub span: Span, + #[suggestion_short(code = "{replace}", applicability = "machine-applicable")] + pub suggestion: Span, + pub replace: String, +} From dbe838079ca9ec3ea76e196cccd68754fe1bbd70 Mon Sep 17 00:00:00 2001 From: Rejyr Date: Sat, 20 Aug 2022 12:30:49 -0400 Subject: [PATCH 14/49] rename: `UnknownTool` to `UnknownToolInScopedLint` --- compiler/rustc_error_messages/locales/en-US/lint.ftl | 2 +- compiler/rustc_lint/src/errors.rs | 4 ++-- compiler/rustc_lint/src/levels.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index cb393d67193b9..9ae226857d3ee 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -412,5 +412,5 @@ lint_reason_must_be_string_literal = reason must be a string literal lint_reason_must_come_last = reason in lint attribute must come last -lint_unknown_tool = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}` +lint_unknown_tool_in_scoped_lint = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}` .help = add `#![register_tool({$tool_name})]` to the crate root diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 569f68bd5e53b..0f8b8e174d834 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -61,8 +61,8 @@ pub enum MalformedAttributeSub { } #[derive(SessionDiagnostic)] -#[error(lint::unknown_tool, code = "E0710")] -pub struct UnknownTool { +#[error(lint::unknown_tool_in_scoped_lint, code = "E0710")] +pub struct UnknownToolInScopedLint { #[primary_span] pub span: Option, pub tool_name: Symbol, diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 2bafe64c1394a..41d89229009ba 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -28,7 +28,7 @@ use tracing::debug; use crate::errors::{ MalformedAttribute, MalformedAttributeSub, OverruledAttribute, OverruledAttributeSub, - UnknownTool, + UnknownToolInScopedLint, }; fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap { @@ -510,7 +510,7 @@ impl<'s> LintLevelsBuilder<'s> { } &CheckLintNameResult::NoTool => { - sess.emit_err(UnknownTool { + sess.emit_err(UnknownToolInScopedLint { span: tool_ident.map(|ident| ident.span), tool_name: tool_name.unwrap(), lint_name: pprust::path_to_string(&meta_item.path), From 1974186d3285d5ed21e7c9427a1c5e7a93d99596 Mon Sep 17 00:00:00 2001 From: Rejyr Date: Sat, 20 Aug 2022 15:48:03 -0400 Subject: [PATCH 15/49] migrate: `rustc_lint::context` --- .../locales/en-US/lint.ftl | 13 +++ compiler/rustc_lint/src/context.rs | 96 ++++++++----------- compiler/rustc_lint/src/errors.rs | 82 +++++++++++++++- 3 files changed, 132 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 9ae226857d3ee..27ad3e4536601 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -414,3 +414,16 @@ lint_reason_must_come_last = reason in lint attribute must come last lint_unknown_tool_in_scoped_lint = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}` .help = add `#![register_tool({$tool_name})]` to the crate root + +lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´ + +lint_requested_level = requested on the command line with `{$level} {$lint_name}` + +lint_check_name_unknown = unknown lint: `{$lint_name}` + .help = did you mean: `{$suggestion}` + +lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` + +lint_check_name_warning = {$msg} + +lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name} diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index b95fc341db656..a1fdc557f9298 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1,3 +1,6 @@ +// #![deny(rustc::diagnostic_outside_of_impl)] +// #![deny(rustc::untranslatable_diagnostic)] +// //! Implementation of lint checking. //! //! The lint checking is mostly consolidated into one pass which runs @@ -16,12 +19,16 @@ use self::TargetLint::*; +use crate::errors::{ + CheckNameDeprecated, CheckNameUnknown, CheckNameUnknownTool, CheckNameWarning, RequestedLevel, + UnsupportedGroup, +}; use crate::levels::LintLevelsBuilder; use crate::passes::{EarlyLintPassObject, LateLintPassObject}; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; -use rustc_errors::{add_elided_lifetime_in_path_suggestion, struct_span_err}; +use rustc_errors::add_elided_lifetime_in_path_suggestion; use rustc_errors::{ Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle, }; @@ -39,7 +46,7 @@ use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintI use rustc_session::Session; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::symbol::{sym, Ident, Symbol}; -use rustc_span::{BytePos, Span, DUMMY_SP}; +use rustc_span::{BytePos, Span}; use rustc_target::abi; use tracing::debug; @@ -326,68 +333,41 @@ impl LintStore { ) { let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name); if lint_name_only == crate::WARNINGS.name_lower() && matches!(level, Level::ForceWarn(_)) { - struct_span_err!( - sess, - DUMMY_SP, - E0602, - "`{}` lint group is not supported with ´--force-warn´", - crate::WARNINGS.name_lower() - ) - .emit(); + sess.emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() }); return; } - let db = match self.check_lint_name(lint_name_only, tool_name, registered_tools) { - CheckLintNameResult::Ok(_) => None, - CheckLintNameResult::Warning(ref msg, _) => Some(sess.struct_warn(msg)), + let lint_name = lint_name.to_string(); + match self.check_lint_name(lint_name_only, tool_name, registered_tools) { + CheckLintNameResult::Warning(msg, _) => { + sess.emit_warning(CheckNameWarning { + msg, + sub: RequestedLevel { level, lint_name }, + }); + } CheckLintNameResult::NoLint(suggestion) => { - let mut err = - struct_span_err!(sess, DUMMY_SP, E0602, "unknown lint: `{}`", lint_name); - - if let Some(suggestion) = suggestion { - err.help(&format!("did you mean: `{}`", suggestion)); + sess.emit_err(CheckNameUnknown { + lint_name: lint_name.clone(), + suggestion, + sub: RequestedLevel { level, lint_name }, + }); + } + CheckLintNameResult::Tool(result) => { + if let Err((Some(_), new_name)) = result { + sess.emit_warning(CheckNameDeprecated { + lint_name: lint_name.clone(), + new_name, + sub: RequestedLevel { level, lint_name }, + }); } - - Some(err.forget_guarantee()) } - CheckLintNameResult::Tool(result) => match result { - Err((Some(_), new_name)) => Some(sess.struct_warn(&format!( - "lint name `{}` is deprecated \ - and does not have an effect anymore. \ - Use: {}", - lint_name, new_name - ))), - _ => None, - }, - CheckLintNameResult::NoTool => Some( - struct_span_err!( - sess, - DUMMY_SP, - E0602, - "unknown lint tool: `{}`", - tool_name.unwrap() - ) - .forget_guarantee(), - ), + CheckLintNameResult::NoTool => { + sess.emit_err(CheckNameUnknownTool { + tool_name: tool_name.unwrap(), + sub: RequestedLevel { level, lint_name }, + }); + } + _ => {} }; - - if let Some(mut db) = db { - let msg = format!( - "requested on the command line with `{} {}`", - match level { - Level::Allow => "-A", - Level::Warn => "-W", - Level::ForceWarn(_) => "--force-warn", - Level::Deny => "-D", - Level::Forbid => "-F", - Level::Expect(_) => { - unreachable!("lints with the level of `expect` should not run this code"); - } - }, - lint_name - ); - db.note(&msg); - db.emit(); - } } /// True if this symbol represents a lint group name. diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 0f8b8e174d834..a6859311cfd63 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -1,5 +1,6 @@ -use rustc_errors::{fluent, AddSubdiagnostic}; +use rustc_errors::{fluent, AddSubdiagnostic, ErrorGuaranteed}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_session::{lint::Level, parse::ParseSess, SessionDiagnostic}; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic)] @@ -80,3 +81,82 @@ pub struct BuiltinEllpisisInclusiveRangePatterns { pub suggestion: Span, pub replace: String, } + +pub struct RequestedLevel { + pub level: Level, + pub lint_name: String, +} + +impl AddSubdiagnostic for RequestedLevel { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + diag.note(fluent::lint::requested_level); + diag.set_arg( + "level", + match self.level { + Level::Allow => "-A", + Level::Warn => "-W", + Level::ForceWarn(_) => "--force-warn", + Level::Deny => "-D", + Level::Forbid => "-F", + Level::Expect(_) => { + unreachable!("lints with the level of `expect` should not run this code"); + } + }, + ); + diag.set_arg("lint_name", self.lint_name); + } +} + +#[derive(SessionDiagnostic)] +#[error(lint::unsupported_group, code = "E0602")] +pub struct UnsupportedGroup { + pub lint_group: String, +} + +pub struct CheckNameUnknown { + pub lint_name: String, + pub suggestion: Option, + pub sub: RequestedLevel, +} + +impl SessionDiagnostic<'_> for CheckNameUnknown { + fn into_diagnostic( + self, + sess: &ParseSess, + ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = sess.struct_err(fluent::lint::check_name_unknown); + diag.code(rustc_errors::error_code!(E0602)); + if let Some(suggestion) = self.suggestion { + diag.help(fluent::lint::help); + diag.set_arg("suggestion", suggestion); + } + diag.set_arg("lint_name", self.lint_name); + diag.subdiagnostic(self.sub); + diag + } +} + +#[derive(SessionDiagnostic)] +#[error(lint::check_name_unknown_tool, code = "E0602")] +pub struct CheckNameUnknownTool { + pub tool_name: Symbol, + #[subdiagnostic] + pub sub: RequestedLevel, +} + +#[derive(SessionDiagnostic)] +#[warning(lint::check_name_warning)] +pub struct CheckNameWarning { + pub msg: String, + #[subdiagnostic] + pub sub: RequestedLevel, +} + +#[derive(SessionDiagnostic)] +#[warning(lint::check_name_deprecated)] +pub struct CheckNameDeprecated { + pub lint_name: String, + pub new_name: String, + #[subdiagnostic] + pub sub: RequestedLevel, +} From 257cf03e2caa673ca1248727c09b4a08d093d706 Mon Sep 17 00:00:00 2001 From: Rejyr Date: Mon, 22 Aug 2022 08:33:47 -0400 Subject: [PATCH 16/49] refactor: migrate to kind-less `SessionDiagnostic` derives --- compiler/rustc_lint/src/errors.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index a6859311cfd63..606d8bda8aafe 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -4,7 +4,7 @@ use rustc_session::{lint::Level, parse::ParseSess, SessionDiagnostic}; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic)] -#[error(lint::overruled_attribute, code = "E0453")] +#[diag(lint::overruled_attribute, code = "E0453")] pub struct OverruledAttribute { #[primary_span] pub span: Span, @@ -43,7 +43,7 @@ impl AddSubdiagnostic for OverruledAttributeSub { } #[derive(SessionDiagnostic)] -#[error(lint::malformed_attribute, code = "E0452")] +#[diag(lint::malformed_attribute, code = "E0452")] pub struct MalformedAttribute { #[primary_span] pub span: Span, @@ -62,7 +62,7 @@ pub enum MalformedAttributeSub { } #[derive(SessionDiagnostic)] -#[error(lint::unknown_tool_in_scoped_lint, code = "E0710")] +#[diag(lint::unknown_tool_in_scoped_lint, code = "E0710")] pub struct UnknownToolInScopedLint { #[primary_span] pub span: Option, @@ -73,7 +73,7 @@ pub struct UnknownToolInScopedLint { } #[derive(SessionDiagnostic)] -#[error(lint::builtin_ellipsis_inclusive_range_patterns, code = "E0783")] +#[diag(lint::builtin_ellipsis_inclusive_range_patterns, code = "E0783")] pub struct BuiltinEllpisisInclusiveRangePatterns { #[primary_span] pub span: Span, @@ -108,7 +108,7 @@ impl AddSubdiagnostic for RequestedLevel { } #[derive(SessionDiagnostic)] -#[error(lint::unsupported_group, code = "E0602")] +#[diag(lint::unsupported_group, code = "E0602")] pub struct UnsupportedGroup { pub lint_group: String, } @@ -137,7 +137,7 @@ impl SessionDiagnostic<'_> for CheckNameUnknown { } #[derive(SessionDiagnostic)] -#[error(lint::check_name_unknown_tool, code = "E0602")] +#[diag(lint::check_name_unknown_tool, code = "E0602")] pub struct CheckNameUnknownTool { pub tool_name: Symbol, #[subdiagnostic] @@ -145,7 +145,7 @@ pub struct CheckNameUnknownTool { } #[derive(SessionDiagnostic)] -#[warning(lint::check_name_warning)] +#[diag(lint::check_name_warning)] pub struct CheckNameWarning { pub msg: String, #[subdiagnostic] @@ -153,7 +153,7 @@ pub struct CheckNameWarning { } #[derive(SessionDiagnostic)] -#[warning(lint::check_name_deprecated)] +#[diag(lint::check_name_deprecated)] pub struct CheckNameDeprecated { pub lint_name: String, pub new_name: String, From 649749c7b040580abc6b0654584e3a580b1870d7 Mon Sep 17 00:00:00 2001 From: nidnogg Date: Mon, 22 Aug 2022 12:14:49 -0300 Subject: [PATCH 17/49] Addressing last comment on PR review --- compiler/rustc_const_eval/src/const_eval/mod.rs | 6 +++--- compiler/rustc_const_eval/src/errors.rs | 2 +- compiler/rustc_error_messages/locales/en-US/const_eval.ftl | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 9041d55155eae..cef74432102de 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -72,12 +72,12 @@ pub(crate) fn eval_to_valtree<'tcx>( Ok(valtree) => Ok(Some(valtree)), Err(err) => { let did = cid.instance.def_id(); - let s = cid.display(tcx); + let global_const_id = cid.display(tcx); match err { ValTreeCreationError::NodesOverflow => { - let msg = format!("maximum number of nodes exceeded in constant {}", &s); + let msg = format!("maximum number of nodes exceeded in constant {}", &global_const_id); let mut diag = match tcx.hir().span_if_local(did) { - Some(span) => tcx.sess.create_err(MaxNumNodesInConstErr { span, s }), + Some(span) => tcx.sess.create_err(MaxNumNodesInConstErr { span, global_const_id }), None => tcx.sess.struct_err(&msg), }; diag.emit(); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index c6e0021958251..c3547cb3abdf3 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -93,7 +93,7 @@ pub(crate) struct TransientMutBorrowErrRaw { pub(crate) struct MaxNumNodesInConstErr { #[primary_span] pub span: Span, - pub s: String, + pub global_const_id: String, } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index 8a5e1a7a95709..72e7a58cd4758 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -30,7 +30,7 @@ const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s -const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$s} +const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id} const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {$kind}s From 066796cecebf79fe8732c33d10167999661dca67 Mon Sep 17 00:00:00 2001 From: nidnogg Date: Mon, 22 Aug 2022 12:32:42 -0300 Subject: [PATCH 18/49] Addressing tidy check fail --- compiler/rustc_const_eval/src/const_eval/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index cef74432102de..d9c4ae4d53f91 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -75,9 +75,14 @@ pub(crate) fn eval_to_valtree<'tcx>( let global_const_id = cid.display(tcx); match err { ValTreeCreationError::NodesOverflow => { - let msg = format!("maximum number of nodes exceeded in constant {}", &global_const_id); + let msg = format!( + "maximum number of nodes exceeded in constant {}", + &global_const_id + ); let mut diag = match tcx.hir().span_if_local(did) { - Some(span) => tcx.sess.create_err(MaxNumNodesInConstErr { span, global_const_id }), + Some(span) => { + tcx.sess.create_err(MaxNumNodesInConstErr { span, global_const_id }) + } None => tcx.sess.struct_err(&msg), }; diag.emit(); From 5101688d4f92d94b93e038e2b53f7ca0ba6c29a4 Mon Sep 17 00:00:00 2001 From: nidnogg Date: Mon, 22 Aug 2022 12:38:16 -0300 Subject: [PATCH 19/49] Addressed trailing newlines, odd whitespace skipped by x.py fmt --- .../locales/en-US/const_eval.ftl | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl index 72e7a58cd4758..33bb116d6fa23 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl @@ -38,33 +38,33 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn const_eval_unallowed_mutable_refs = mutable references are not allowed in the final value of {$kind}s - .teach_note = + .teach_note = References in statics and constants may only refer to immutable values.\n\n - Statics are shared everywhere, and if they refer to mutable data one might violate memory + Statics are shared everywhere, and if they refer to mutable data one might violate memory safety since holding multiple mutable references to shared data is not allowed.\n\n If you really want global mutable state, try using static mut or a global UnsafeCell. const_eval_unallowed_mutable_refs_raw = raw mutable references are not allowed in the final value of {$kind}s - .teach_note = + .teach_note = References in statics and constants may only refer to immutable values.\n\n - Statics are shared everywhere, and if they refer to mutable data one might violate memory + Statics are shared everywhere, and if they refer to mutable data one might violate memory safety since holding multiple mutable references to shared data is not allowed.\n\n If you really want global mutable state, try using static mut or a global UnsafeCell. -const_eval_non_const_fmt_macro_call = +const_eval_non_const_fmt_macro_call = cannot call non-const formatting macro in {$kind}s -const_eval_non_const_fn_call = +const_eval_non_const_fn_call = cannot call non-const fn `{$def_path_str}` in {$kind}s -const_eval_unallowed_op_in_const_context = +const_eval_unallowed_op_in_const_context = {$msg} const_eval_unallowed_heap_allocations = allocations are not allowed in {$kind}s .label = allocation not allowed in {$kind}s - .teach_note = + .teach_note = The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time. const_eval_unallowed_inline_asm = @@ -74,10 +74,10 @@ const_eval_interior_mutable_data_refer = {$kind}s cannot refer to interior mutable data .label = this borrow of an interior mutable value may end up in the final value .help = to fix this, the value can be extracted to a separate `static` item and then referenced - .teach_note = - A constant containing interior mutable data behind a reference can allow you to modify that data. - This would make multiple uses of a constant to be able to see different values and allow circumventing + .teach_note = + A constant containing interior mutable data behind a reference can allow you to modify that data. + This would make multiple uses of a constant to be able to see different values and allow circumventing the `Send` and `Sync` requirements for shared mutable data, which is unsound. -const_eval_interior_mutability_borrow = - cannot borrow here, since the borrowed element may contain interior mutability \ No newline at end of file +const_eval_interior_mutability_borrow = + cannot borrow here, since the borrowed element may contain interior mutability From 73ae38bac10e010aee20fc2f56735fdada86e5dd Mon Sep 17 00:00:00 2001 From: Jean CASPAR <55629512+JeanCASPAR@users.noreply.github.com> Date: Tue, 16 Aug 2022 22:28:51 +0200 Subject: [PATCH 20/49] Migrate ast_lowering::path to SessionDiagnostic --- Cargo.lock | 1 + compiler/rustc_ast_lowering/Cargo.toml | 1 + compiler/rustc_ast_lowering/src/errors.rs | 29 +++++++++++++++++++ compiler/rustc_ast_lowering/src/lib.rs | 1 + compiler/rustc_ast_lowering/src/path.rs | 23 +++++---------- .../locales/en-US/ast_lowering.ftl | 5 ++++ compiler/rustc_error_messages/src/lib.rs | 1 + 7 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 compiler/rustc_ast_lowering/src/errors.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl diff --git a/Cargo.lock b/Cargo.lock index cb245ce0ff828..40583d7ae9661 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3575,6 +3575,7 @@ dependencies = [ "rustc_errors", "rustc_hir", "rustc_index", + "rustc_macros", "rustc_middle", "rustc_query_system", "rustc_session", diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 39ba62ef2ffc5..474aff2e2aac0 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -15,6 +15,7 @@ rustc_target = { path = "../rustc_target" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } rustc_middle = { path = "../rustc_middle" } +rustc_macros = { path = "../rustc_macros" } rustc_query_system = { path = "../rustc_query_system" } rustc_span = { path = "../rustc_span" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs new file mode 100644 index 0000000000000..8701491c9eb3d --- /dev/null +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -0,0 +1,29 @@ +use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic}; +use rustc_macros::SessionDiagnostic; +use rustc_span::Span; + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::generic_type_with_parentheses, code = "E0214")] +pub struct GenericTypeWithParentheses { + #[primary_span] + #[label] + pub span: Span, + #[subdiagnostic] + pub sub: Option, +} + +#[derive(Clone, Copy)] +pub struct UseAngleBrackets { + pub open_param: Span, + pub close_param: Span, +} + +impl AddSubdiagnostic for UseAngleBrackets { + fn add_to_diagnostic(self, diag: &mut Diagnostic) { + diag.multipart_suggestion( + fluent::ast_lowering::use_angle_brackets, + vec![(self.open_param, String::from("<")), (self.close_param, String::from(">"))], + Applicability::MaybeIncorrect, + ); + } +} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1ac1d689efbdb..c1d9a7e690e69 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -75,6 +75,7 @@ macro_rules! arena_vec { mod asm; mod block; +mod errors; mod expr; mod index; mod item; diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 393be3b454c37..5874d08a94fe0 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -1,11 +1,11 @@ use crate::ImplTraitPosition; +use super::errors::{GenericTypeWithParentheses, UseAngleBrackets}; use super::ResolverAstLoweringExt; use super::{GenericArgsCtor, LifetimeRes, ParenthesizedGenericArgs}; use super::{ImplTraitContext, LoweringContext, ParamMode}; use rustc_ast::{self as ast, *}; -use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, PartialRes, Res}; use rustc_hir::GenericArg; @@ -185,7 +185,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::PathSegment<'hir> { debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args { - let msg = "parenthesized type parameters may only be used with a `Fn` trait"; match **generic_args { GenericArgs::AngleBracketed(ref data) => { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) @@ -193,10 +192,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), ParenthesizedGenericArgs::Err => { - let mut err = struct_span_err!(self.tcx.sess, data.span, E0214, "{}", msg); - err.span_label(data.span, "only `Fn` traits may use parentheses"); // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait` - if !data.inputs.is_empty() { + let sub = if !data.inputs.is_empty() { // Start of the span to the 1st character of 1st argument let open_param = data.inputs_span.shrink_to_lo().to(data .inputs @@ -212,16 +209,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .span .shrink_to_hi() .to(data.inputs_span.shrink_to_hi()); - err.multipart_suggestion( - &format!("use angle brackets instead",), - vec![ - (open_param, String::from("<")), - (close_param, String::from(">")), - ], - Applicability::MaybeIncorrect, - ); - } - err.emit(); + + Some(UseAngleBrackets { open_param, close_param }) + } else { + None + }; + self.tcx.sess.emit_err(GenericTypeWithParentheses { span: data.span, sub }); ( self.lower_angle_bracketed_parameter_data( &data.as_angle_bracketed_args(), diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl new file mode 100644 index 0000000000000..ac7fc37e37dd5 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl @@ -0,0 +1,5 @@ +ast_lowering_generic_type_with_parentheses = + parenthesized type parameters may only be used with a `Fn` trait + .label = only `Fn` traits may use parentheses + +ast_lowering_use_angle_brackets = use angle brackets instead diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 3569c7f063064..31455d47698cb 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -32,6 +32,7 @@ pub use unic_langid::{langid, LanguageIdentifier}; // Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module. fluent_messages! { + ast_lowering => "../locales/en-US/ast_lowering.ftl", ast_passes => "../locales/en-US/ast_passes.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", From 0043d10c712769b45d6cb7fb3fcc141878263d18 Mon Sep 17 00:00:00 2001 From: Jean CASPAR <55629512+JeanCASPAR@users.noreply.github.com> Date: Wed, 17 Aug 2022 16:58:57 +0200 Subject: [PATCH 21/49] Migrate ast_lowering::lib and ast_lowering::item to SessionDiagnostic --- compiler/rustc_ast_lowering/src/errors.rs | 53 ++++++++++++++++++- compiler/rustc_ast_lowering/src/item.rs | 11 ++-- compiler/rustc_ast_lowering/src/lib.rs | 38 +++++-------- .../locales/en-US/ast_lowering.ftl | 13 +++++ 4 files changed, 83 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 8701491c9eb3d..c6337ce161d6f 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -1,6 +1,6 @@ use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic}; use rustc_macros::SessionDiagnostic; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic, Clone, Copy)] #[error(ast_lowering::generic_type_with_parentheses, code = "E0214")] @@ -27,3 +27,54 @@ impl AddSubdiagnostic for UseAngleBrackets { ); } } + +#[derive(SessionDiagnostic)] +#[help] +#[error(ast_lowering::invalid_abi, code = "E0703")] +pub struct InvalidAbi { + #[primary_span] + #[label] + pub span: Span, + pub abi: Symbol, + pub valid_abis: String, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::assoc_ty_parentheses)] +pub struct AssocTyParentheses { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub sub: AssocTyParenthesesSub, +} + +#[derive(Clone, Copy)] +pub enum AssocTyParenthesesSub { + Empty { parentheses_span: Span }, + NotEmpty { open_param: Span, close_param: Span }, +} + +impl AddSubdiagnostic for AssocTyParenthesesSub { + fn add_to_diagnostic(self, diag: &mut Diagnostic) { + match self { + Self::Empty { parentheses_span } => diag.multipart_suggestion( + fluent::ast_lowering::remove_parentheses, + vec![(parentheses_span, String::new())], + Applicability::MaybeIncorrect, + ), + Self::NotEmpty { open_param, close_param } => diag.multipart_suggestion( + fluent::ast_lowering::use_angle_brackets, + vec![(open_param, String::from("<")), (close_param, String::from(">"))], + Applicability::MaybeIncorrect, + ), + }; + } +} + +#[derive(SessionDiagnostic)] +#[error(ast_lowering::misplaced_impl_trait, code = "E0562")] +pub struct MisplacedImplTrait { + #[primary_span] + pub span: Span, + pub position: String, +} diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 0f1bab24f96ca..a789268dfdaff 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,3 +1,4 @@ +use super::errors::InvalidAbi; use super::ResolverAstLoweringExt; use super::{AstOwner, ImplTraitContext, ImplTraitPosition}; use super::{FnDeclKind, LoweringContext, ParamMode}; @@ -7,7 +8,6 @@ use rustc_ast::visit::AssocCtxt; use rustc_ast::*; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; -use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; @@ -1260,10 +1260,11 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn error_on_invalid_abi(&self, abi: StrLit) { - struct_span_err!(self.tcx.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol) - .span_label(abi.span, "invalid ABI") - .help(&format!("valid ABIs: {}", abi::all_names().join(", "))) - .emit(); + self.tcx.sess.emit_err(InvalidAbi { + span: abi.span, + abi: abi.symbol, + valid_abis: abi::all_names().join(", "), + }); } fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c1d9a7e690e69..a44c3c0d23b9e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,6 +39,8 @@ #[macro_use] extern crate tracing; +use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; + use rustc_ast::ptr::P; use rustc_ast::visit; use rustc_ast::{self as ast, *}; @@ -49,7 +51,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; -use rustc_errors::{struct_span_err, Applicability, Handler, StashKey}; +use rustc_errors::{Handler, StashKey}; use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; @@ -1071,19 +1073,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) { - let mut err = self.tcx.sess.struct_span_err( - data.span, - "parenthesized generic arguments cannot be used in associated type constraints", - ); // Suggest removing empty parentheses: "Trait()" -> "Trait" - if data.inputs.is_empty() { + let sub = if data.inputs.is_empty() { let parentheses_span = data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi()); - err.multipart_suggestion( - "remove these parentheses", - vec![(parentheses_span, String::new())], - Applicability::MaybeIncorrect, - ); + AssocTyParenthesesSub::Empty { parentheses_span } } // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait` else { @@ -1097,13 +1091,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // End of last argument to end of parameters let close_param = data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi()); - err.multipart_suggestion( - &format!("use angle brackets instead",), - vec![(open_param, String::from("<")), (close_param, String::from(">"))], - Applicability::MaybeIncorrect, - ); - } - err.emit(); + AssocTyParenthesesSub::NotEmpty { open_param, close_param } + }; + self.tcx.sess.emit_err(AssocTyParentheses { span: data.span, sub }); } #[instrument(level = "debug", skip(self))] @@ -1342,14 +1332,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path } ImplTraitContext::Disallowed(position) => { - let mut err = struct_span_err!( - self.tcx.sess, - t.span, - E0562, - "`impl Trait` only allowed in function and inherent method return types, not in {}", - position - ); - err.emit(); + self.tcx.sess.emit_err(MisplacedImplTrait { + span: t.span, + position: position.to_string(), + }); hir::TyKind::Err } } diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl index ac7fc37e37dd5..3856dd1050bec 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl @@ -3,3 +3,16 @@ ast_lowering_generic_type_with_parentheses = .label = only `Fn` traits may use parentheses ast_lowering_use_angle_brackets = use angle brackets instead + +ast_lowering_invalid_abi = + invalid ABI: found `{$abi}` + .label = invalid ABI + .help = valid ABIs: {$valid_abis} + +ast_lowering_assoc_ty_parentheses = + parenthesized generic arguments cannot be used in associated type constraints + +ast_lowering_remove_parentheses = remove these parentheses + +ast_lowering_misplaced_impl_trait = + `impl Trait` only allowed in function and inherent method return types, not in {$position} From 1382d307d32cd6400adf4416fabc80517b0eed2c Mon Sep 17 00:00:00 2001 From: Jean CASPAR <55629512+JeanCASPAR@users.noreply.github.com> Date: Wed, 17 Aug 2022 19:48:25 +0200 Subject: [PATCH 22/49] Migrate ast_lowering::expr to SessionDiagnostic --- compiler/rustc_ast_lowering/src/errors.rs | 78 ++++++++++++++- compiler/rustc_ast_lowering/src/expr.rs | 94 ++++--------------- .../locales/en-US/ast_lowering.ftl | 33 +++++++ 3 files changed, 125 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index c6337ce161d6f..d704e5c60231e 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -3,7 +3,7 @@ use rustc_macros::SessionDiagnostic; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::generic_type_with_parentheses, code = "E0214")] +#[diag(ast_lowering::generic_type_with_parentheses, code = "E0214")] pub struct GenericTypeWithParentheses { #[primary_span] #[label] @@ -30,7 +30,7 @@ impl AddSubdiagnostic for UseAngleBrackets { #[derive(SessionDiagnostic)] #[help] -#[error(ast_lowering::invalid_abi, code = "E0703")] +#[diag(ast_lowering::invalid_abi, code = "E0703")] pub struct InvalidAbi { #[primary_span] #[label] @@ -40,7 +40,7 @@ pub struct InvalidAbi { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::assoc_ty_parentheses)] +#[diag(ast_lowering::assoc_ty_parentheses)] pub struct AssocTyParentheses { #[primary_span] pub span: Span, @@ -72,9 +72,79 @@ impl AddSubdiagnostic for AssocTyParenthesesSub { } #[derive(SessionDiagnostic)] -#[error(ast_lowering::misplaced_impl_trait, code = "E0562")] +#[diag(ast_lowering::misplaced_impl_trait, code = "E0562")] pub struct MisplacedImplTrait { #[primary_span] pub span: Span, pub position: String, } + +#[derive(SessionDiagnostic, Clone, Copy)] +#[diag(ast_lowering::rustc_box_attribute_error)] +pub struct RustcBoxAttributeError { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[diag(ast_lowering::underscore_expr_lhs_assign)] +pub struct UnderscoreExprLhsAssign { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[diag(ast_lowering::base_expression_double_dot)] +pub struct BaseExpressionDoubleDot { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[diag(ast_lowering::await_only_in_async_fn_and_blocks, code = "E0728")] +pub struct AwaitOnlyInAsyncFnAndBlocks { + #[primary_span] + #[label] + pub dot_await_span: Span, + #[label(ast_lowering::this_not_async)] + pub item_span: Option, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[diag(ast_lowering::generator_too_many_parameters, code = "E0628")] +pub struct GeneratorTooManyParameters { + #[primary_span] + pub fn_decl_span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[diag(ast_lowering::closure_cannot_be_static, code = "E0697")] +pub struct ClosureCannotBeStatic { + #[primary_span] + pub fn_decl_span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[help] +#[diag(ast_lowering::async_non_move_closure_not_supported, code = "E0708")] +pub struct AsyncNonMoveClosureNotSupported { + #[primary_span] + pub fn_decl_span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[diag(ast_lowering::functional_record_update_destructuring_assignment)] +pub struct FunctionalRecordUpdateDestructuringAssignemnt { + #[primary_span] + #[suggestion(code = "", applicability = "machine-applicable")] + pub span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[diag(ast_lowering::async_generators_not_supported, code = "E0727")] +pub struct AsyncGeneratorsNotSupported { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index bd61f4fa87ab8..e470df122b6d3 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,3 +1,8 @@ +use super::errors::{ + AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks, + BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignemnt, + GeneratorTooManyParameters, RustcBoxAttributeError, UnderscoreExprLhsAssign, +}; use super::ResolverAstLoweringExt; use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; use crate::{FnDeclKind, ImplTraitPosition}; @@ -6,7 +11,6 @@ use rustc_ast::attr; use rustc_ast::ptr::P as AstP; use rustc_ast::*; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::definitions::DefPathData; @@ -45,13 +49,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let hir_id = self.lower_node_id(e.id); return hir::Expr { hir_id, kind, span: self.lower_span(e.span) }; } else { - self.tcx.sess - .struct_span_err( - e.span, - "#[rustc_box] requires precisely one argument \ - and no other attributes are allowed", - ) - .emit(); + self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span }); hir::ExprKind::Err } } else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) { @@ -211,13 +209,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims) } ExprKind::Underscore => { - self.tcx - .sess.struct_span_err( - e.span, - "in expressions, `_` can only be used on the left-hand side of an assignment", - ) - .span_label(e.span, "`_` not allowed here") - .emit(); + self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span }); hir::ExprKind::Err } ExprKind::Path(ref qself, ref path) => { @@ -249,11 +241,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let rest = match &se.rest { StructRest::Base(e) => Some(self.lower_expr(e)), StructRest::Rest(sp) => { - self.tcx - .sess - .struct_span_err(*sp, "base expression required after `..`") - .span_label(*sp, "add a base expression here") - .emit(); + self.tcx.sess.emit_err(BaseExpressionDoubleDot { span: *sp }); Some(&*self.arena.alloc(self.expr_err(*sp))) } StructRest::None => None, @@ -662,17 +650,10 @@ impl<'hir> LoweringContext<'_, 'hir> { match self.generator_kind { Some(hir::GeneratorKind::Async(_)) => {} Some(hir::GeneratorKind::Gen) | None => { - let mut err = struct_span_err!( - self.tcx.sess, + self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks { dot_await_span, - E0728, - "`await` is only allowed inside `async` functions and blocks" - ); - err.span_label(dot_await_span, "only allowed inside `async` functions and blocks"); - if let Some(item_sp) = self.current_item { - err.span_label(item_sp, "this is not `async`"); - } - err.emit(); + item_span: self.current_item, + }); } } let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None); @@ -892,13 +873,7 @@ impl<'hir> LoweringContext<'_, 'hir> { match generator_kind { Some(hir::GeneratorKind::Gen) => { if decl.inputs.len() > 1 { - struct_span_err!( - self.tcx.sess, - fn_decl_span, - E0628, - "too many parameters for a generator (expected 0 or 1 parameters)" - ) - .emit(); + self.tcx.sess.emit_err(GeneratorTooManyParameters { fn_decl_span }); } Some(movability) } @@ -907,13 +882,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } None => { if movability == Movability::Static { - struct_span_err!( - self.tcx.sess, - fn_decl_span, - E0697, - "closures cannot be static" - ) - .emit(); + self.tcx.sess.emit_err(ClosureCannotBeStatic { fn_decl_span }); } None } @@ -960,17 +929,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let body = self.with_new_scopes(|this| { // FIXME(cramertj): allow `async` non-`move` closures with arguments. if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() { - struct_span_err!( - this.tcx.sess, - fn_decl_span, - E0708, - "`async` non-`move` closures with parameters are not currently supported", - ) - .help( - "consider using `let` statements to manually capture \ - variables by reference before entering an `async move` closure", - ) - .emit(); + this.tcx.sess.emit_err(AsyncNonMoveClosureNotSupported { fn_decl_span }); } // Transform `async |x: u8| -> X { ... }` into @@ -1210,20 +1169,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let fields_omitted = match &se.rest { StructRest::Base(e) => { - self.tcx - .sess - .struct_span_err( - e.span, - "functional record updates are not allowed in destructuring \ - assignments", - ) - .span_suggestion( - e.span, - "consider removing the trailing pattern", - "", - rustc_errors::Applicability::MachineApplicable, - ) - .emit(); + self.tcx.sess.emit_err(FunctionalRecordUpdateDestructuringAssignemnt { + span: e.span, + }); true } StructRest::Rest(_) => true, @@ -1420,13 +1368,7 @@ impl<'hir> LoweringContext<'_, 'hir> { match self.generator_kind { Some(hir::GeneratorKind::Gen) => {} Some(hir::GeneratorKind::Async(_)) => { - struct_span_err!( - self.tcx.sess, - span, - E0727, - "`async` generators are not yet supported" - ) - .emit(); + self.tcx.sess.emit_err(AsyncGeneratorsNotSupported { span }); } None => self.generator_kind = Some(hir::GeneratorKind::Gen), } diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl index 3856dd1050bec..47f2305b9136e 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl @@ -16,3 +16,36 @@ ast_lowering_remove_parentheses = remove these parentheses ast_lowering_misplaced_impl_trait = `impl Trait` only allowed in function and inherent method return types, not in {$position} + +ast_lowering_rustc_box_attribute_error = + #[rustc_box] requires precisely one argument and no other attributes are allowed + +ast_lowering_underscore_expr_lhs_assign = + in expressions, `_` can only be used on the left-hand side of an assignment + .label = `_` not allowed here + +ast_lowering_base_expression_double_dot = + base expression required after `..` + .label = add a base expression here + +ast_lowering_await_only_in_async_fn_and_blocks = + `await` is only allowed inside `async` functions and blocks + .label = only allowed inside `async` functions and blocks + +ast_lowering_this_not_async = this is not `async` + +ast_lowering_generator_too_many_parameters = + too many parameters for a generator (expected 0 or 1 parameters) + +ast_lowering_closure_cannot_be_static = closures cannot be static + +ast_lowering_async_non_move_closure_not_supported = + `async` non-`move` closures with parameters are not currently supported + .help = consider using `let` statements to manually capture variables by reference before entering an `async move` closure + +ast_lowering_functional_record_update_destructuring_assignment = + functional record updates are not allowed in destructuring assignments + .suggestion = consider removing the trailing pattern + +ast_lowering_async_generators_not_supported = + `async` generators are not yet supported From d75fd91d502e220fce60c358dd5c52737f249169 Mon Sep 17 00:00:00 2001 From: Jean CASPAR <55629512+JeanCASPAR@users.noreply.github.com> Date: Wed, 17 Aug 2022 23:00:33 +0200 Subject: [PATCH 23/49] Migrate ast_lowering::ast to SessionDiagnostic --- compiler/rustc_ast_lowering/src/asm.rs | 161 +++++++----------- compiler/rustc_ast_lowering/src/errors.rs | 124 +++++++++++++- .../locales/en-US/ast_lowering.ftl | 54 ++++++ 3 files changed, 239 insertions(+), 100 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 4166b4fc2e5bc..d246510e0c1ed 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -1,11 +1,17 @@ use crate::{ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt}; +use super::errors::{ + AbiSpecifiedMultipleTimes, AttSyntaxOnlyX86, ClobberAbiNotSupported, + InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst, + InvalidAsmTemplateModifierRegClass, InvalidAsmTemplateModifierRegClassSub, + InvalidAsmTemplateModifierSym, InvalidRegister, InvalidRegisterClass, RegisterClassOnlyClobber, + RegisterConflict, +}; use super::LoweringContext; use rustc_ast::ptr::P; use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::definitions::DefPathData; @@ -26,13 +32,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let asm_arch = if self.tcx.sess.opts.actually_rustdoc { None } else { self.tcx.sess.asm_arch }; if asm_arch.is_none() && !self.tcx.sess.opts.actually_rustdoc { - struct_span_err!( - self.tcx.sess, - sp, - E0472, - "inline assembly is unsupported on this target" - ) - .emit(); + self.tcx.sess.emit_err(InlineAsmUnsupportedTarget { span: sp }); } if let Some(asm_arch) = asm_arch { // Inline assembly is currently only stable for these architectures. @@ -59,10 +59,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { && !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64)) && !self.tcx.sess.opts.actually_rustdoc { - self.tcx - .sess - .struct_span_err(sp, "the `att_syntax` option is only supported on x86") - .emit(); + self.tcx.sess.emit_err(AttSyntaxOnlyX86 { span: sp }); } if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind { feature_err( @@ -82,51 +79,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // If the abi was already in the list, emit an error match clobber_abis.get(&abi) { Some((prev_name, prev_sp)) => { - let mut err = self.tcx.sess.struct_span_err( - *abi_span, - &format!("`{}` ABI specified multiple times", prev_name), - ); - err.span_label(*prev_sp, "previously specified here"); - // Multiple different abi names may actually be the same ABI // If the specified ABIs are not the same name, alert the user that they resolve to the same ABI let source_map = self.tcx.sess.source_map(); - if source_map.span_to_snippet(*prev_sp) - != source_map.span_to_snippet(*abi_span) - { - err.note("these ABIs are equivalent on the current target"); - } + let equivalent = (source_map.span_to_snippet(*prev_sp) + != source_map.span_to_snippet(*abi_span)) + .then_some(()); - err.emit(); + self.tcx.sess.emit_err(AbiSpecifiedMultipleTimes { + abi_span: *abi_span, + prev_name: *prev_name, + prev_span: *prev_sp, + equivalent, + }); } None => { - clobber_abis.insert(abi, (abi_name, *abi_span)); + clobber_abis.insert(abi, (*abi_name, *abi_span)); } } } Err(&[]) => { - self.tcx - .sess - .struct_span_err( - *abi_span, - "`clobber_abi` is not supported on this target", - ) - .emit(); + self.tcx.sess.emit_err(ClobberAbiNotSupported { abi_span: *abi_span }); } Err(supported_abis) => { - let mut err = self - .tcx - .sess - .struct_span_err(*abi_span, "invalid ABI for `clobber_abi`"); let mut abis = format!("`{}`", supported_abis[0]); for m in &supported_abis[1..] { let _ = write!(abis, ", `{}`", m); } - err.note(&format!( - "the following ABIs are supported on this target: {}", - abis - )); - err.emit(); + self.tcx.sess.emit_err(InvalidAbiClobberAbi { + abi_span: *abi_span, + supported_abis: abis, + }); } } } @@ -144,8 +127,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { InlineAsmRegOrRegClass::Reg(s) => { asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch { asm::InlineAsmReg::parse(asm_arch, s).unwrap_or_else(|e| { - let msg = format!("invalid register `{}`: {}", s, e); - sess.struct_span_err(*op_sp, &msg).emit(); + sess.emit_err(InvalidRegister { op_span: *op_sp, s, e }); asm::InlineAsmReg::Err }) } else { @@ -155,8 +137,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { InlineAsmRegOrRegClass::RegClass(s) => { asm::InlineAsmRegOrRegClass::RegClass(if let Some(asm_arch) = asm_arch { asm::InlineAsmRegClass::parse(asm_arch, s).unwrap_or_else(|e| { - let msg = format!("invalid register class `{}`: {}", s, e); - sess.struct_span_err(*op_sp, &msg).emit(); + sess.emit_err(InvalidRegisterClass { op_span: *op_sp, s, e }); asm::InlineAsmRegClass::Err }) } else { @@ -282,50 +263,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let valid_modifiers = class.valid_modifiers(asm_arch.unwrap()); if !valid_modifiers.contains(&modifier) { - let mut err = sess.struct_span_err( - placeholder_span, - "invalid asm template modifier for this register class", - ); - err.span_label(placeholder_span, "template modifier"); - err.span_label(op_sp, "argument"); - if !valid_modifiers.is_empty() { + let sub = if !valid_modifiers.is_empty() { let mut mods = format!("`{}`", valid_modifiers[0]); for m in &valid_modifiers[1..] { let _ = write!(mods, ", `{}`", m); } - err.note(&format!( - "the `{}` register class supports \ - the following template modifiers: {}", - class.name(), - mods - )); + InvalidAsmTemplateModifierRegClassSub::SupportModifier { + class_name: class.name(), + modifiers: mods, + } } else { - err.note(&format!( - "the `{}` register class does not support template modifiers", - class.name() - )); - } - err.emit(); + InvalidAsmTemplateModifierRegClassSub::DoesNotSupportModifier { + class_name: class.name(), + } + }; + sess.emit_err(InvalidAsmTemplateModifierRegClass { + placeholder_span, + op_span: op_sp, + sub, + }); } } hir::InlineAsmOperand::Const { .. } => { - let mut err = sess.struct_span_err( + sess.emit_err(InvalidAsmTemplateModifierConst { placeholder_span, - "asm template modifiers are not allowed for `const` arguments", - ); - err.span_label(placeholder_span, "template modifier"); - err.span_label(op_sp, "argument"); - err.emit(); + op_span: op_sp, + }); } hir::InlineAsmOperand::SymFn { .. } | hir::InlineAsmOperand::SymStatic { .. } => { - let mut err = sess.struct_span_err( + sess.emit_err(InvalidAsmTemplateModifierSym { placeholder_span, - "asm template modifiers are not allowed for `sym` arguments", - ); - err.span_label(placeholder_span, "template modifier"); - err.span_label(op_sp, "argument"); - err.emit(); + op_span: op_sp, + }); } } } @@ -346,12 +316,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // require that the operand name an explicit register, not a // register class. if reg_class.is_clobber_only(asm_arch.unwrap()) && !op.is_clobber() { - let msg = format!( - "register class `{}` can only be used as a clobber, \ - not as an input or output", - reg_class.name() - ); - sess.struct_span_err(op_sp, &msg).emit(); + sess.emit_err(RegisterClassOnlyClobber { + op_span: op_sp, + reg_class_name: reg_class.name(), + }); continue; } @@ -391,16 +359,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { unreachable!(); }; - let msg = format!( - "register `{}` conflicts with register `{}`", - reg.name(), - reg2.name() - ); - let mut err = sess.struct_span_err(op_sp, &msg); - err.span_label(op_sp, &format!("register `{}`", reg.name())); - err.span_label(op_sp2, &format!("register `{}`", reg2.name())); - - match (op, op2) { + let in_out = match (op, op2) { ( hir::InlineAsmOperand::In { .. }, hir::InlineAsmOperand::Out { late, .. }, @@ -411,14 +370,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) => { assert!(!*late); let out_op_sp = if input { op_sp2 } else { op_sp }; - let msg = "use `lateout` instead of \ - `out` to avoid conflict"; - err.span_help(out_op_sp, msg); - } - _ => {} - } + Some(out_op_sp) + }, + _ => None, + }; - err.emit(); + sess.emit_err(RegisterConflict { + op_span1: op_sp, + op_span2: op_sp2, + reg1_name: reg.name(), + reg2_name: reg2.name(), + in_out + }); } Entry::Vacant(v) => { if r == reg { diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index d704e5c60231e..24115237bd972 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -1,5 +1,5 @@ use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic}; -use rustc_macros::SessionDiagnostic; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic, Clone, Copy)] @@ -148,3 +148,125 @@ pub struct AsyncGeneratorsNotSupported { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::inline_asm_unsupported_target, code = "E0472")] +pub struct InlineAsmUnsupportedTarget { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::att_syntax_only_x86)] +pub struct AttSyntaxOnlyX86 { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::abi_specified_multiple_times)] +pub struct AbiSpecifiedMultipleTimes { + #[primary_span] + pub abi_span: Span, + pub prev_name: Symbol, + #[label] + pub prev_span: Span, + #[note] + pub equivalent: Option<()>, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::clobber_abi_not_supported)] +pub struct ClobberAbiNotSupported { + #[primary_span] + pub abi_span: Span, +} + +#[derive(SessionDiagnostic)] +#[note] +#[error(ast_lowering::invalid_abi_clobber_abi)] +pub struct InvalidAbiClobberAbi { + #[primary_span] + pub abi_span: Span, + pub supported_abis: String, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::invalid_register)] +pub struct InvalidRegister<'a> { + #[primary_span] + pub op_span: Span, + pub s: Symbol, + pub e: &'a str, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::invalid_register_class)] +pub struct InvalidRegisterClass<'a> { + #[primary_span] + pub op_span: Span, + pub s: Symbol, + pub e: &'a str, +} + +#[derive(SessionDiagnostic)] +#[error(ast_lowering::invalid_asm_template_modifier_reg_class)] +pub struct InvalidAsmTemplateModifierRegClass { + #[primary_span] + #[label(ast_lowering::template_modifier)] + pub placeholder_span: Span, + #[label(ast_lowering::argument)] + pub op_span: Span, + #[subdiagnostic] + pub sub: InvalidAsmTemplateModifierRegClassSub, +} + +#[derive(SessionSubdiagnostic)] +pub enum InvalidAsmTemplateModifierRegClassSub { + #[note(ast_lowering::support_modifiers)] + SupportModifier { class_name: Symbol, modifiers: String }, + #[note(ast_lowering::does_not_support_modifiers)] + DoesNotSupportModifier { class_name: Symbol }, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::invalid_asm_template_modifier_const)] +pub struct InvalidAsmTemplateModifierConst { + #[primary_span] + #[label(ast_lowering::template_modifier)] + pub placeholder_span: Span, + #[label(ast_lowering::argument)] + pub op_span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::invalid_asm_template_modifier_sym)] +pub struct InvalidAsmTemplateModifierSym { + #[primary_span] + #[label(ast_lowering::template_modifier)] + pub placeholder_span: Span, + #[label(ast_lowering::argument)] + pub op_span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::register_class_only_clobber)] +pub struct RegisterClassOnlyClobber { + #[primary_span] + pub op_span: Span, + pub reg_class_name: Symbol, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::register_conflict)] +pub struct RegisterConflict<'a> { + #[primary_span] + #[label(ast_lowering::register1)] + pub op_span1: Span, + #[label(ast_lowering::register2)] + pub op_span2: Span, + pub reg1_name: &'a str, + pub reg2_name: &'a str, + #[help] + pub in_out: Option, +} diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl index 47f2305b9136e..592e303b53fdd 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl @@ -49,3 +49,57 @@ ast_lowering_functional_record_update_destructuring_assignment = ast_lowering_async_generators_not_supported = `async` generators are not yet supported + +ast_lowering_inline_asm_unsupported_target = + inline assembly is unsupported on this target + +ast_lowering_att_syntax_only_x86 = + the `att_syntax` option is only supported on x86 + +ast_lowering_abi_specified_multiple_times = + `{$prev_name}` ABI specified multiple times + .label = previously specified here + .note = these ABIs are equivalent on the current target + +ast_lowering_clobber_abi_not_supported = + `clobber_abi` is not supported on this target + +ast_lowering_invalid_abi_clobber_abi = + invalid ABI for `clobber_abi` + .note = the following ABIs are supported on this target: {$supported_abis} + +ast_lowering_invalid_register = + invalid register `{$s}`: {$e} + +ast_lowering_invalid_register_class = + invalid register class `{$s}`: {$e} + +ast_lowering_invalid_asm_template_modifier_reg_class = + invalid asm template modifier for this register class + +ast_lowering_argument = argument + +ast_lowering_template_modifier = template modifier + +ast_lowering_support_modifiers = + the `{$class_name}` register class supports the following template modifiers: {$modifiers} + +ast_lowering_does_not_support_modifiers = + the `{$class_name}` register class does not support template modifiers + +ast_lowering_invalid_asm_template_modifier_const = + asm template modifiers are not allowed for `const` arguments + +ast_lowering_invalid_asm_template_modifier_sym = + asm template modifiers are not allowed for `sym` arguments + +ast_lowering_register_class_only_clobber = + register class `{$reg_class_name}` can only be used as a clobber, not as an input or output + +ast_lowering_register_conflict = + register `{$reg1_name}` conflicts with register `{$reg2_name}` + .help = use `lateout` instead of `out` to avoid conflict + +ast_lowering_register1 = register `{$reg1_name}` + +ast_lowering_register2 = register `{$reg2_name}` From 51649665917366f605842e9261e77d49fc4e7549 Mon Sep 17 00:00:00 2001 From: Jean CASPAR <55629512+JeanCASPAR@users.noreply.github.com> Date: Thu, 18 Aug 2022 18:08:39 +0200 Subject: [PATCH 24/49] Migrate ast_lowering::pat to SessionDiagnostic --- compiler/rustc_ast_lowering/src/errors.rs | 38 ++++++++++++++++++- compiler/rustc_ast_lowering/src/pat.rs | 33 +++++----------- .../locales/en-US/ast_lowering.ftl | 17 +++++++++ 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 24115237bd972..3644e664cebf2 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -1,6 +1,6 @@ use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; -use rustc_span::{Span, Symbol}; +use rustc_span::{symbol::Ident, Span, Symbol}; #[derive(SessionDiagnostic, Clone, Copy)] #[diag(ast_lowering::generic_type_with_parentheses, code = "E0214")] @@ -270,3 +270,39 @@ pub struct RegisterConflict<'a> { #[help] pub in_out: Option, } + +#[derive(SessionDiagnostic, Clone, Copy)] +#[help] +#[error(ast_lowering::sub_tuple_binding)] +pub struct SubTupleBinding<'a> { + #[primary_span] + #[label] + #[suggestion_verbose( + ast_lowering::sub_tuple_binding_suggestion, + code = "..", + applicability = "maybe-incorrect" + )] + pub span: Span, + pub ident: Ident, + pub ident_name: Symbol, + pub ctx: &'a str, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::extra_double_dot)] +pub struct ExtraDoubleDot<'a> { + #[primary_span] + #[label] + pub span: Span, + #[label(ast_lowering::previously_used_here)] + pub prev_span: Span, + pub ctx: &'a str, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[note] +#[error(ast_lowering::misplaced_double_dot)] +pub struct MisplacedDoubleDot { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 51f67e505f4ee..abe9b354252ac 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -1,3 +1,4 @@ +use super::errors::{ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding}; use super::ResolverAstLoweringExt; use super::{ImplTraitContext, LoweringContext, ParamMode}; use crate::ImplTraitPosition; @@ -5,7 +6,6 @@ use crate::ImplTraitPosition; use rustc_ast::ptr::P; use rustc_ast::*; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_span::symbol::Ident; @@ -134,20 +134,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // This is not allowed as a sub-tuple pattern PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => { let sp = pat.span; - self.diagnostic() - .struct_span_err( - sp, - &format!("`{} @` is not allowed in a {}", ident.name, ctx), - ) - .span_label(sp, "this is only allowed in slice patterns") - .help("remove this and bind each tuple field independently") - .span_suggestion_verbose( - sp, - &format!("if you don't need to use the contents of {}, discard the tuple's remaining fields", ident), - "..", - Applicability::MaybeIncorrect, - ) - .emit(); + self.tcx.sess.emit_err(SubTupleBinding { + span: sp, + ident_name: ident.name, + ident, + ctx, + }); } _ => {} } @@ -296,19 +288,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern. pub(crate) fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) { - self.diagnostic() - .struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx)) - .span_label(sp, &format!("can only be used once per {} pattern", ctx)) - .span_label(prev_sp, "previously used here") - .emit(); + self.tcx.sess.emit_err(ExtraDoubleDot { span: sp, prev_span: prev_sp, ctx }); } /// Used to ban the `..` pattern in places it shouldn't be semantically. fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> { - self.diagnostic() - .struct_span_err(sp, "`..` patterns are not allowed here") - .note("only allowed in tuple, tuple struct, and slice patterns") - .emit(); + self.tcx.sess.emit_err(MisplacedDoubleDot { span: sp }); // We're not in a list context so `..` can be reasonably treated // as `_` because it should always be valid and roughly matches the diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl index 592e303b53fdd..438fbd8e57ba0 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl @@ -103,3 +103,20 @@ ast_lowering_register_conflict = ast_lowering_register1 = register `{$reg1_name}` ast_lowering_register2 = register `{$reg2_name}` + +ast_lowering_sub_tuple_binding = + `{$ident_name} @` is not allowed in a {$ctx} + .label = this is only allowed in slice patterns + .help = remove this and bind each tuple field independently + +ast_lowering_sub_tuple_binding_suggestion = if you don't need to use the contents of {$ident}, discard the tuple's remaining fields + +ast_lowering_extra_double_dot = + `..` can only be used once per {$ctx} pattern + .label = can only be used once per {$ctx} pattern + +ast_lowering_previously_used_here = previously used here + +ast_lowering_misplaced_double_dot = + `..` patterns are not allowed here + .note = only allowed in tuple, tuple struct, and slice patterns From e701c72a631ca443d16d7d37a4ccb584db93ef41 Mon Sep 17 00:00:00 2001 From: Jean CASPAR <55629512+JeanCASPAR@users.noreply.github.com> Date: Thu, 18 Aug 2022 19:30:56 +0200 Subject: [PATCH 25/49] Migrate all span_err(...) in ast_lowering to SessionDiagnostic --- compiler/rustc_ast_lowering/src/errors.rs | 21 +++++++++++++++++++ compiler/rustc_ast_lowering/src/expr.rs | 8 +++---- compiler/rustc_ast_lowering/src/item.rs | 8 ++----- compiler/rustc_ast_lowering/src/pat.rs | 7 ++++--- .../locales/en-US/ast_lowering.ftl | 9 ++++++++ 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 3644e664cebf2..2da42c96ec0cf 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -306,3 +306,24 @@ pub struct MisplacedDoubleDot { #[primary_span] pub span: Span, } + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::misplaced_relax_trait_bound)] +pub struct MisplacedRelaxTraitBound { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::not_supported_for_lifetime_binder_async_closure)] +pub struct NotSupportedForLifetimeBinderAsyncClosure { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic, Clone, Copy)] +#[error(ast_lowering::arbitrary_expression_in_pattern)] +pub struct ArbitraryExpressionInPattern { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index e470df122b6d3..61f8c0216f1cf 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,7 +1,8 @@ use super::errors::{ AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignemnt, - GeneratorTooManyParameters, RustcBoxAttributeError, UnderscoreExprLhsAssign, + GeneratorTooManyParameters, NotSupportedForLifetimeBinderAsyncClosure, RustcBoxAttributeError, + UnderscoreExprLhsAssign, }; use super::ResolverAstLoweringExt; use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; @@ -915,10 +916,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn_decl_span: Span, ) -> hir::ExprKind<'hir> { if let &ClosureBinder::For { span, .. } = binder { - self.tcx.sess.span_err( - span, - "`for<...>` binders on `async` closures are not currently supported", - ); + self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span }); } let (binder_clause, generic_params) = self.lower_closure_binder(binder); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index a789268dfdaff..fd338ffc0c5e8 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,4 +1,4 @@ -use super::errors::InvalidAbi; +use super::errors::{InvalidAbi, MisplacedRelaxTraitBound}; use super::ResolverAstLoweringExt; use super::{AstOwner, ImplTraitContext, ImplTraitPosition}; use super::{FnDeclKind, LoweringContext, ParamMode}; @@ -1339,11 +1339,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } let is_param = *is_param.get_or_insert_with(compute_is_param); if !is_param { - self.diagnostic().span_err( - bound.span(), - "`?Trait` bounds are only permitted at the \ - point where a type parameter is declared", - ); + self.tcx.sess.emit_err(MisplacedRelaxTraitBound { span: bound.span() }); } } } diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index abe9b354252ac..1efa19a3a8286 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -1,4 +1,6 @@ -use super::errors::{ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding}; +use super::errors::{ + ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding, +}; use super::ResolverAstLoweringExt; use super::{ImplTraitContext, LoweringContext, ParamMode}; use crate::ImplTraitPosition; @@ -330,8 +332,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ExprKind::Path(..) if allow_paths => {} ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} _ => { - self.diagnostic() - .span_err(expr.span, "arbitrary expressions aren't allowed in patterns"); + self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span }); return self.arena.alloc(self.expr_err(expr.span)); } } diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl index 438fbd8e57ba0..8effd9ca75017 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl @@ -120,3 +120,12 @@ ast_lowering_previously_used_here = previously used here ast_lowering_misplaced_double_dot = `..` patterns are not allowed here .note = only allowed in tuple, tuple struct, and slice patterns + +ast_lowering_misplaced_relax_trait_bound = + `?Trait` bounds are only permitted at the point where a type parameter is declared + +ast_lowering_not_supported_for_lifetime_binder_async_closure = + `for<...>` binders on `async` closures are not currently supported + +ast_lowering_arbitrary_expression_in_pattern = + arbitrary expressions aren't allowed in patterns From 9472df10d0dc9e2a1ee027d6f7ebe947bd660ae8 Mon Sep 17 00:00:00 2001 From: Jean CASPAR <55629512+JeanCASPAR@users.noreply.github.com> Date: Fri, 19 Aug 2022 14:55:06 +0200 Subject: [PATCH 26/49] Changes made in response to feedback --- compiler/rustc_ast_lowering/src/asm.rs | 22 ++++++++++++------- compiler/rustc_ast_lowering/src/errors.rs | 14 ++++++------ compiler/rustc_ast_lowering/src/lib.rs | 4 ++-- .../locales/en-US/ast_lowering.ftl | 4 ++-- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index d246510e0c1ed..0dba9da63da2a 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -124,22 +124,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .iter() .map(|(op, op_sp)| { let lower_reg = |reg| match reg { - InlineAsmRegOrRegClass::Reg(s) => { + InlineAsmRegOrRegClass::Reg(reg) => { asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch { - asm::InlineAsmReg::parse(asm_arch, s).unwrap_or_else(|e| { - sess.emit_err(InvalidRegister { op_span: *op_sp, s, e }); + asm::InlineAsmReg::parse(asm_arch, reg).unwrap_or_else(|error| { + sess.emit_err(InvalidRegister { op_span: *op_sp, reg, error }); asm::InlineAsmReg::Err }) } else { asm::InlineAsmReg::Err }) } - InlineAsmRegOrRegClass::RegClass(s) => { + InlineAsmRegOrRegClass::RegClass(reg_class) => { asm::InlineAsmRegOrRegClass::RegClass(if let Some(asm_arch) = asm_arch { - asm::InlineAsmRegClass::parse(asm_arch, s).unwrap_or_else(|e| { - sess.emit_err(InvalidRegisterClass { op_span: *op_sp, s, e }); - asm::InlineAsmRegClass::Err - }) + asm::InlineAsmRegClass::parse(asm_arch, reg_class).unwrap_or_else( + |error| { + sess.emit_err(InvalidRegisterClass { + op_span: *op_sp, + reg_class, + error, + }); + asm::InlineAsmRegClass::Err + }, + ) } else { asm::InlineAsmRegClass::Err }) diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 2da42c96ec0cf..edc7ac9fbe383 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic}; +use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic, DiagnosticArgFromDisplay}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::{symbol::Ident, Span, Symbol}; @@ -73,10 +73,10 @@ impl AddSubdiagnostic for AssocTyParenthesesSub { #[derive(SessionDiagnostic)] #[diag(ast_lowering::misplaced_impl_trait, code = "E0562")] -pub struct MisplacedImplTrait { +pub struct MisplacedImplTrait<'a> { #[primary_span] pub span: Span, - pub position: String, + pub position: DiagnosticArgFromDisplay<'a>, } #[derive(SessionDiagnostic, Clone, Copy)] @@ -196,8 +196,8 @@ pub struct InvalidAbiClobberAbi { pub struct InvalidRegister<'a> { #[primary_span] pub op_span: Span, - pub s: Symbol, - pub e: &'a str, + pub reg: Symbol, + pub error: &'a str, } #[derive(SessionDiagnostic, Clone, Copy)] @@ -205,8 +205,8 @@ pub struct InvalidRegister<'a> { pub struct InvalidRegisterClass<'a> { #[primary_span] pub op_span: Span, - pub s: Symbol, - pub e: &'a str, + pub reg_class: Symbol, + pub error: &'a str, } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a44c3c0d23b9e..ed28f81f88ead 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -51,7 +51,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; -use rustc_errors::{Handler, StashKey}; +use rustc_errors::{DiagnosticArgFromDisplay, Handler, StashKey}; use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; @@ -1334,7 +1334,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ImplTraitContext::Disallowed(position) => { self.tcx.sess.emit_err(MisplacedImplTrait { span: t.span, - position: position.to_string(), + position: DiagnosticArgFromDisplay(&position), }); hir::TyKind::Err } diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl index 8effd9ca75017..dcb1e2b08306f 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl @@ -69,10 +69,10 @@ ast_lowering_invalid_abi_clobber_abi = .note = the following ABIs are supported on this target: {$supported_abis} ast_lowering_invalid_register = - invalid register `{$s}`: {$e} + invalid register `{$reg}`: {$error} ast_lowering_invalid_register_class = - invalid register class `{$s}`: {$e} + invalid register class `{$reg_class}`: {$error} ast_lowering_invalid_asm_template_modifier_reg_class = invalid asm template modifier for this register class From 5fef1b865f01d6d6c38288e1fcad3451e68e1765 Mon Sep 17 00:00:00 2001 From: Jean CASPAR <55629512+JeanCASPAR@users.noreply.github.com> Date: Mon, 22 Aug 2022 19:34:19 +0200 Subject: [PATCH 27/49] Resolve conflicts --- compiler/rustc_ast_lowering/src/errors.rs | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index edc7ac9fbe383..59f1b7180e4f4 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -150,21 +150,21 @@ pub struct AsyncGeneratorsNotSupported { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::inline_asm_unsupported_target, code = "E0472")] +#[diag(ast_lowering::inline_asm_unsupported_target, code = "E0472")] pub struct InlineAsmUnsupportedTarget { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::att_syntax_only_x86)] +#[diag(ast_lowering::att_syntax_only_x86)] pub struct AttSyntaxOnlyX86 { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::abi_specified_multiple_times)] +#[diag(ast_lowering::abi_specified_multiple_times)] pub struct AbiSpecifiedMultipleTimes { #[primary_span] pub abi_span: Span, @@ -176,7 +176,7 @@ pub struct AbiSpecifiedMultipleTimes { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::clobber_abi_not_supported)] +#[diag(ast_lowering::clobber_abi_not_supported)] pub struct ClobberAbiNotSupported { #[primary_span] pub abi_span: Span, @@ -184,7 +184,7 @@ pub struct ClobberAbiNotSupported { #[derive(SessionDiagnostic)] #[note] -#[error(ast_lowering::invalid_abi_clobber_abi)] +#[diag(ast_lowering::invalid_abi_clobber_abi)] pub struct InvalidAbiClobberAbi { #[primary_span] pub abi_span: Span, @@ -192,7 +192,7 @@ pub struct InvalidAbiClobberAbi { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::invalid_register)] +#[diag(ast_lowering::invalid_register)] pub struct InvalidRegister<'a> { #[primary_span] pub op_span: Span, @@ -201,7 +201,7 @@ pub struct InvalidRegister<'a> { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::invalid_register_class)] +#[diag(ast_lowering::invalid_register_class)] pub struct InvalidRegisterClass<'a> { #[primary_span] pub op_span: Span, @@ -210,7 +210,7 @@ pub struct InvalidRegisterClass<'a> { } #[derive(SessionDiagnostic)] -#[error(ast_lowering::invalid_asm_template_modifier_reg_class)] +#[diag(ast_lowering::invalid_asm_template_modifier_reg_class)] pub struct InvalidAsmTemplateModifierRegClass { #[primary_span] #[label(ast_lowering::template_modifier)] @@ -230,7 +230,7 @@ pub enum InvalidAsmTemplateModifierRegClassSub { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::invalid_asm_template_modifier_const)] +#[diag(ast_lowering::invalid_asm_template_modifier_const)] pub struct InvalidAsmTemplateModifierConst { #[primary_span] #[label(ast_lowering::template_modifier)] @@ -240,7 +240,7 @@ pub struct InvalidAsmTemplateModifierConst { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::invalid_asm_template_modifier_sym)] +#[diag(ast_lowering::invalid_asm_template_modifier_sym)] pub struct InvalidAsmTemplateModifierSym { #[primary_span] #[label(ast_lowering::template_modifier)] @@ -250,7 +250,7 @@ pub struct InvalidAsmTemplateModifierSym { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::register_class_only_clobber)] +#[diag(ast_lowering::register_class_only_clobber)] pub struct RegisterClassOnlyClobber { #[primary_span] pub op_span: Span, @@ -258,7 +258,7 @@ pub struct RegisterClassOnlyClobber { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::register_conflict)] +#[diag(ast_lowering::register_conflict)] pub struct RegisterConflict<'a> { #[primary_span] #[label(ast_lowering::register1)] @@ -273,7 +273,7 @@ pub struct RegisterConflict<'a> { #[derive(SessionDiagnostic, Clone, Copy)] #[help] -#[error(ast_lowering::sub_tuple_binding)] +#[diag(ast_lowering::sub_tuple_binding)] pub struct SubTupleBinding<'a> { #[primary_span] #[label] @@ -289,7 +289,7 @@ pub struct SubTupleBinding<'a> { } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::extra_double_dot)] +#[diag(ast_lowering::extra_double_dot)] pub struct ExtraDoubleDot<'a> { #[primary_span] #[label] @@ -301,28 +301,28 @@ pub struct ExtraDoubleDot<'a> { #[derive(SessionDiagnostic, Clone, Copy)] #[note] -#[error(ast_lowering::misplaced_double_dot)] +#[diag(ast_lowering::misplaced_double_dot)] pub struct MisplacedDoubleDot { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::misplaced_relax_trait_bound)] +#[diag(ast_lowering::misplaced_relax_trait_bound)] pub struct MisplacedRelaxTraitBound { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::not_supported_for_lifetime_binder_async_closure)] +#[diag(ast_lowering::not_supported_for_lifetime_binder_async_closure)] pub struct NotSupportedForLifetimeBinderAsyncClosure { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic, Clone, Copy)] -#[error(ast_lowering::arbitrary_expression_in_pattern)] +#[diag(ast_lowering::arbitrary_expression_in_pattern)] pub struct ArbitraryExpressionInPattern { #[primary_span] pub span: Span, From 0005f628f068a766647bb0b159dac2c6cefcefa1 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 08:46:05 +0200 Subject: [PATCH 28/49] Refactor diagnostics in `handle_errors` function --- compiler/rustc_attr/src/builtin.rs | 58 +++--- compiler/rustc_attr/src/lib.rs | 1 + .../rustc_attr/src/session_diagnostics.rs | 196 ++++++++++++++++++ .../locales/en-US/attr.ftl | 29 +++ compiler/rustc_error_messages/src/lib.rs | 1 + 5 files changed, 254 insertions(+), 31 deletions(-) create mode 100644 compiler/rustc_attr/src/session_diagnostics.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/attr.ftl diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 62ccd734fe720..b43551db43d67 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -14,6 +14,8 @@ use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; use std::num::NonZeroU32; +use crate::session_diagnostics; + pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() } @@ -25,46 +27,38 @@ enum AttrError { NonIdentFeature, MissingFeature, MultipleStabilityLevels, - UnsupportedLiteral(&'static str, /* is_bytestr */ bool), + UnsupportedLiteral(UnsupportedLiteralReason, /* is_bytestr */ bool), +} + +pub(crate) enum UnsupportedLiteralReason { + Generic, + CfgString, + DeprecatedString, + DeprecatedKvPair, } fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { - let diag = &sess.span_diagnostic; match error { AttrError::MultipleItem(item) => { - struct_span_err!(diag, span, E0538, "multiple '{}' items", item).emit(); + sess.emit_err(session_diagnostics::MultipleItem { span, item }); } AttrError::UnknownMetaItem(item, expected) => { - let expected = expected.iter().map(|name| format!("`{}`", name)).collect::>(); - struct_span_err!(diag, span, E0541, "unknown meta item '{}'", item) - .span_label(span, format!("expected one of {}", expected.join(", "))) - .emit(); + sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected }); } AttrError::MissingSince => { - struct_span_err!(diag, span, E0542, "missing 'since'").emit(); + sess.emit_err(session_diagnostics::MissingSince { span }); } AttrError::NonIdentFeature => { - struct_span_err!(diag, span, E0546, "'feature' is not an identifier").emit(); + sess.emit_err(session_diagnostics::NonIdentFeature { span }); } AttrError::MissingFeature => { - struct_span_err!(diag, span, E0546, "missing 'feature'").emit(); + sess.emit_err(session_diagnostics::MissingFeature { span }); } AttrError::MultipleStabilityLevels => { - struct_span_err!(diag, span, E0544, "multiple stability levels").emit(); + sess.emit_err(session_diagnostics::MultipleStabilityLevels { span }); } - AttrError::UnsupportedLiteral(msg, is_bytestr) => { - let mut err = struct_span_err!(diag, span, E0565, "{}", msg); - if is_bytestr { - if let Ok(lint_str) = sess.source_map().span_to_snippet(span) { - err.span_suggestion( - span, - "consider removing the prefix", - &lint_str[1..], - Applicability::MaybeIncorrect, - ); - } - } - err.emit(); + AttrError::UnsupportedLiteral(reason, is_bytestr) => { + sess.emit_err(session_diagnostics::UnsupportedLiteral { span, reason, is_bytestr }); } } } @@ -326,7 +320,7 @@ where handle_errors( &sess.parse_sess, meta.span(), - AttrError::UnsupportedLiteral("unsupported literal", false), + AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), ); continue 'outer; }; @@ -494,7 +488,10 @@ where handle_errors( &sess.parse_sess, lit.span, - AttrError::UnsupportedLiteral("unsupported literal", false), + AttrError::UnsupportedLiteral( + UnsupportedLiteralReason::Generic, + false, + ), ); continue 'outer; } @@ -711,7 +708,7 @@ pub fn eval_condition( handle_errors( sess, mi.span(), - AttrError::UnsupportedLiteral("unsupported literal", false), + AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), ); return false; } @@ -790,7 +787,7 @@ pub fn eval_condition( sess, lit.span, AttrError::UnsupportedLiteral( - "literal in `cfg` predicate value must be a string", + UnsupportedLiteralReason::CfgString, lit.kind.is_bytestr(), ), ); @@ -870,8 +867,7 @@ where &sess.parse_sess, lit.span, AttrError::UnsupportedLiteral( - "literal in `deprecated` \ - value must be a string", + UnsupportedLiteralReason::DeprecatedString, lit.kind.is_bytestr(), ), ); @@ -934,7 +930,7 @@ where &sess.parse_sess, lit.span, AttrError::UnsupportedLiteral( - "item in `deprecated` must be a key/value pair", + UnsupportedLiteralReason::DeprecatedKvPair, false, ), ); diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index c95c1c40a34c2..36a3620b6b9a2 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -10,6 +10,7 @@ extern crate rustc_macros; mod builtin; +mod session_diagnostics; pub use builtin::*; pub use IntType::*; diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs new file mode 100644 index 0000000000000..92ce9336edc59 --- /dev/null +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -0,0 +1,196 @@ +use std::num::IntErrorKind; + +use rustc_errors::{error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_macros::SessionDiagnostic; +use rustc_session::{parse::ParseSess, SessionDiagnostic}; +use rustc_span::Span; + +use crate::UnsupportedLiteralReason; + +#[derive(SessionDiagnostic)] +#[error(attr::multiple_item, code = "E0538")] +pub(crate) struct MultipleItem { + #[primary_span] + pub span: Span, + + pub item: String, +} + +#[derive(SessionDiagnostic)] +#[error(attr::missing_since, code = "E0542")] +pub(crate) struct MissingSince { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::non_ident_feature, code = "E0546")] +pub(crate) struct NonIdentFeature { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::missing_feature, code = "E0546")] +pub(crate) struct MissingFeature { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::multiple_stability_levels, code = "E0544")] +pub(crate) struct MultipleStabilityLevels { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::invalid_meta_item, code = "E0539")] +pub(crate) struct InvalidMetaItem { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::missing_issue, code = "E0547")] +pub(crate) struct MissingIssue { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::rustc_promotable_pairing, code = "E0717")] +pub(crate) struct RustcPromotablePairing { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::rustc_allowed_unstable_pairing, code = "E0789")] +pub(crate) struct RustcAllowedUnstablePairing { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::soft_no_args)] +pub(crate) struct SoftNoArgs { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::invalid_issue_string, code = "E0545")] +pub(crate) struct InvalidIssueString { + #[primary_span] + pub span: Span, + + #[subdiagnostic] + pub cause: Option, +} + +// The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be +// translatable. +#[derive(SessionSubdiagnostic)] +pub(crate) enum InvalidIssueStringCause { + #[label(attr::must_not_be_zero)] + MustNotBeZero { + #[primary_span] + span: Span, + }, + + #[label(attr::empty)] + Empty { + #[primary_span] + span: Span, + }, + + #[label(attr::invalid_digit)] + InvalidDigit { + #[primary_span] + span: Span, + }, + + #[label(attr::pos_overflow)] + PosOverflow { + #[primary_span] + span: Span, + }, + + #[label(attr::neg_overflow)] + NegOverflow { + #[primary_span] + span: Span, + }, +} + +impl InvalidIssueStringCause { + pub fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option { + match kind { + IntErrorKind::Empty => Some(Self::Empty { span }), + IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }), + IntErrorKind::PosOverflow => Some(Self::PosOverflow { span }), + IntErrorKind::NegOverflow => Some(Self::NegOverflow { span }), + IntErrorKind::Zero => Some(Self::MustNotBeZero { span }), + _ => None, + } + } +} + +pub(crate) struct UnknownMetaItem<'a> { + pub span: Span, + pub item: String, + pub expected: &'a [&'a str], +} + +// Manual implementation to be able to format `expected` items correctly. +impl<'a> SessionDiagnostic<'a> for UnknownMetaItem<'_> { + fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::>(); + let mut diag = sess.span_diagnostic.struct_span_err_with_code( + self.span, + fluent::attr::unknown_meta_item, + error_code!(E0541), + ); + diag.set_arg("item", self.item); + diag.set_arg("expected", expected.join(", ")); + diag.span_label(self.span, fluent::attr::label); + diag + } +} + +pub(crate) struct UnsupportedLiteral { + pub span: Span, + pub reason: UnsupportedLiteralReason, + pub is_bytestr: bool, +} + +impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral { + fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + let mut diag = sess.span_diagnostic.struct_span_err_with_code( + self.span, + match self.reason { + UnsupportedLiteralReason::Generic => fluent::attr::unsupported_literal_generic, + UnsupportedLiteralReason::CfgString => fluent::attr::unsupported_literal_cfg_string, + UnsupportedLiteralReason::DeprecatedString => { + fluent::attr::unsupported_literal_deprecated_string + } + UnsupportedLiteralReason::DeprecatedKvPair => { + fluent::attr::unsupported_literal_deprecated_kv_pair + } + }, + error_code!(E0565), + ); + if self.is_bytestr { + if let Ok(lint_str) = sess.source_map().span_to_snippet(self.span) { + diag.span_suggestion( + self.span, + fluent::attr::unsupported_literal_suggestion, + &lint_str[1..], + Applicability::MaybeIncorrect, + ); + } + } + diag + } +} diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_error_messages/locales/en-US/attr.ftl new file mode 100644 index 0000000000000..a8207b1f7bc37 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/attr.ftl @@ -0,0 +1,29 @@ +attr_multiple_item = + multiple '{$item}' items + +attr_unknown_meta_item = + unknown meta item '{$item}' + .label = expected one of {$expected} + +attr_missing_since = + missing 'since' + +attr_non_ident_feature = + 'feature' is not an identifier + +attr_missing_feature = + missing 'feature' + +attr_multiple_stability_levels = + multiple stability levels + +attr_unsupported_literal_generic = + unsupported literal +attr_unsupported_literal_cfg_string = + literal in `cfg` predicate value must be a string +attr_unsupported_literal_deprecated_string = + literal in `deprecated` value must be a string +attr_unsupported_literal_deprecated_kv_pair = + item in `deprecated` must be a key/value pair +attr_unsupported_literal_suggestion = + consider removing the prefix diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 3569c7f063064..ab09a902b0a7a 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -33,6 +33,7 @@ pub use unic_langid::{langid, LanguageIdentifier}; // Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module. fluent_messages! { ast_passes => "../locales/en-US/ast_passes.ftl", + attr => "../locales/en-US/attr.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", const_eval => "../locales/en-US/const_eval.ftl", From 83a724eab5e7f6c7b03374efd625b71ff9cf92a3 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 08:48:14 +0200 Subject: [PATCH 29/49] Refactor more diagnostics in `rustc_attr` --- compiler/rustc_attr/src/builtin.rs | 69 ++++++------------- .../locales/en-US/attr.ftl | 28 ++++++++ 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index b43551db43d67..98a171488caba 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -237,8 +237,6 @@ where let mut promotable = false; let mut allowed_through_unstable_modules = false; - let diagnostic = &sess.parse_sess.span_diagnostic; - 'outer: for attr in attrs_iter { if ![ sym::rustc_const_unstable, @@ -278,7 +276,7 @@ where *item = Some(v); true } else { - struct_span_err!(diagnostic, meta.span, E0539, "incorrect meta item").emit(); + sess.emit_err(session_diagnostics::InvalidMetaItem { span: meta.span }); false } }; @@ -344,39 +342,28 @@ where // is a name/value pair string literal. issue_num = match issue.unwrap().as_str() { "none" => None, - issue => { - let emit_diag = |msg: &str| { - struct_span_err!( - diagnostic, - mi.span, - E0545, - "`issue` must be a non-zero numeric string \ - or \"none\"", - ) - .span_label(mi.name_value_literal_span().unwrap(), msg) - .emit(); - }; - match issue.parse() { - Ok(0) => { - emit_diag( - "`issue` must not be \"0\", \ - use \"none\" instead", - ); - continue 'outer; - } - Ok(num) => NonZeroU32::new(num), - Err(err) => { - emit_diag(&err.to_string()); - continue 'outer; - } + issue => match issue.parse::() { + Ok(num) => Some(num), + Err(err) => { + sess.emit_err( + session_diagnostics::InvalidIssueString { + span: mi.span, + cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( + mi.name_value_literal_span().unwrap(), + err.kind(), + ), + }, + ); + continue 'outer; } - } + }, }; } sym::soft => { if !mi.is_word() { - let msg = "`soft` should not have any arguments"; - sess.parse_sess.span_diagnostic.span_err(mi.span, msg); + sess.emit_err(session_diagnostics::SoftNoArgs { + span: mi.span, + }); } is_soft = true; } @@ -434,8 +421,7 @@ where continue; } _ => { - struct_span_err!(diagnostic, attr.span, E0547, "missing 'issue'") - .emit(); + sess.emit_err(session_diagnostics::MissingIssue { span: attr.span }); continue; } } @@ -530,14 +516,7 @@ where if let Some((ref mut stab, _)) = const_stab { stab.promotable = promotable; } else { - struct_span_err!( - diagnostic, - item_sp, - E0717, - "`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` \ - or a `rustc_const_stable` attribute" - ) - .emit(); + sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }); } } @@ -552,13 +531,7 @@ where { *allowed_through_unstable_modules = true; } else { - struct_span_err!( - diagnostic, - item_sp, - E0789, - "`rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute" - ) - .emit(); + sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp }); } } diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_error_messages/locales/en-US/attr.ftl index a8207b1f7bc37..45dda0ea7c458 100644 --- a/compiler/rustc_error_messages/locales/en-US/attr.ftl +++ b/compiler/rustc_error_messages/locales/en-US/attr.ftl @@ -27,3 +27,31 @@ attr_unsupported_literal_deprecated_kv_pair = item in `deprecated` must be a key/value pair attr_unsupported_literal_suggestion = consider removing the prefix + +attr_invalid_meta_item = + incorrect meta item + +attr_invalid_issue_string = + `issue` must be a non-zero numeric string or "none" +attr_must_not_be_zero = + `issue` must not be "0", use "none" instead +attr_empty = + cannot parse integer from empty string +attr_invalid_digit = + invalid digit found in string +attr_pos_overflow = + number too large to fit in target type +attr_neg_overflow = + number too small to fit in target type + +attr_missing_issue = + missing 'issue' + +attr_rustc_promotable_pairing = + `rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute + +attr_rustc_allowed_unstable_pairing = + `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute + +attr_soft_no_args = + `soft` should not have any arguments From 40c5184eec0c607e856fba385d186684fdd25412 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 10:03:28 +0200 Subject: [PATCH 30/49] Add internal diagnistics lints --- compiler/rustc_attr/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index 36a3620b6b9a2..3a43f1aad02d6 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -5,6 +5,8 @@ //! to this crate. #![feature(let_else)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_macros; From b3be7698d60f0e6840856daffce0ed22737a5289 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 12:36:16 +0200 Subject: [PATCH 31/49] Refactor additional diagnostics in `rustc_attr` --- compiler/rustc_attr/src/builtin.rs | 56 ++++++----------- .../rustc_attr/src/session_diagnostics.rs | 62 +++++++++++++++++++ .../locales/en-US/attr.ftl | 26 ++++++++ 3 files changed, 106 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 98a171488caba..b752daecc8820 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -645,25 +645,18 @@ pub fn eval_condition( NestedMetaItem::Literal(Lit { span, .. }) | NestedMetaItem::MetaItem(MetaItem { span, .. }), ] => { - sess.span_diagnostic - .struct_span_err(*span, "expected a version literal") - .emit(); + sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); return false; } [..] => { - sess.span_diagnostic - .struct_span_err(cfg.span, "expected single version literal") - .emit(); + sess.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { + span: cfg.span, + }); return false; } }; let Some(min_version) = parse_version(min_version.as_str(), false) else { - sess.span_diagnostic - .struct_span_warn( - *span, - "unknown version literal format, assuming it refers to a future version", - ) - .emit(); + sess.emit_warning(session_diagnostics::UnknownVersionLiteral { span: *span }); return false; }; let rustc_version = parse_version(env!("CFG_RELEASE"), true).unwrap(); @@ -706,13 +699,9 @@ pub fn eval_condition( }), sym::not => { if mis.len() != 1 { - struct_span_err!( - sess.span_diagnostic, - cfg.span, - E0536, - "expected 1 cfg-pattern" - ) - .emit(); + sess.emit_err(session_diagnostics::ExpectedOneCfgPattern { + span: cfg.span, + }); return false; } @@ -738,21 +727,16 @@ pub fn eval_condition( }) } _ => { - struct_span_err!( - sess.span_diagnostic, - cfg.span, - E0537, - "invalid predicate `{}`", - pprust::path_to_string(&cfg.path) - ) - .emit(); + sess.emit_err(session_diagnostics::InvalidPredicate { + span: cfg.span, + predicate: pprust::path_to_string(&cfg.path), + }); false } } } ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => { - sess.span_diagnostic - .span_err(cfg.path.span, "`cfg` predicate key must be an identifier"); + sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); true } MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => { @@ -868,14 +852,10 @@ where } sym::suggestion => { if !sess.features_untracked().deprecated_suggestion { - let mut diag = sess.struct_span_err( - mi.span, - "suggestions on deprecated items are unstable", - ); - if sess.is_nightly_build() { - diag.help("add `#![feature(deprecated_suggestion)]` to the crate root"); - } - diag.note("see #94785 for more details").emit(); + sess.emit_err(session_diagnostics::DeprecatedItemSuggestion { + span: mi.span, + is_nightly: sess.is_nightly_build().then_some(()), + }); } if !get(mi, &mut suggestion) { @@ -921,7 +901,7 @@ where } if note.is_none() { - struct_span_err!(diagnostic, attr.span, E0543, "missing 'note'").emit(); + sess.emit_err(session_diagnostics::MissingNote { span: attr.span }); continue; } } diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 92ce9336edc59..4b9f1541f4733 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -79,6 +79,68 @@ pub(crate) struct SoftNoArgs { pub span: Span, } +#[derive(SessionDiagnostic)] +#[error(attr::expected_version_literal)] +pub(crate) struct ExpectedVersionLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::expected_single_version_literal)] +pub(crate) struct ExpectedSingleVersionLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[warning(attr::unknown_version_literal)] +pub(crate) struct UnknownVersionLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::expected_one_cfg_pattern, code = "E0536")] +pub(crate) struct ExpectedOneCfgPattern { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::invalid_predicate, code = "E0537")] +pub(crate) struct InvalidPredicate { + #[primary_span] + pub span: Span, + + pub predicate: String, +} + +#[derive(SessionDiagnostic)] +#[error(attr::cfg_predicate_identifier)] +pub(crate) struct CfgPredicateIdentifier { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::deprecated_item_suggestion)] +#[note] +pub(crate) struct DeprecatedItemSuggestion { + #[primary_span] + pub span: Span, + + #[help] + pub is_nightly: Option<()>, +} + +#[derive(SessionDiagnostic)] +#[error(attr::missing_note, code = "E0543")] +pub(crate) struct MissingNote { + #[primary_span] + pub span: Span, +} + #[derive(SessionDiagnostic)] #[error(attr::invalid_issue_string, code = "E0545")] pub(crate) struct InvalidIssueString { diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_error_messages/locales/en-US/attr.ftl index 45dda0ea7c458..378377ed8660d 100644 --- a/compiler/rustc_error_messages/locales/en-US/attr.ftl +++ b/compiler/rustc_error_messages/locales/en-US/attr.ftl @@ -55,3 +55,29 @@ attr_rustc_allowed_unstable_pairing = attr_soft_no_args = `soft` should not have any arguments + +attr_expected_version_literal = + expected a version literal + +attr_expected_single_version_literal = + expected single version literal + +attr_unknown_version_literal = + unknown version literal format, assuming it refers to a future version + +attr_expected_one_cfg_pattern = + expected 1 cfg-pattern + +attr_invalid_predicate = + invalid predicate `{$predicate}` + +attr_cfg_predicate_identifier = + `cfg` predicate key must be an identifier + +attr_deprecated_item_suggestion = + suggestions on deprecated items are unstable + .help = add `#![feature(deprecated_suggestion)]` to the crate root + .note = see #94785 for more details + +attr_missing_note = + missing 'note' From b731bfa2d42641472028e35aeb088bf1e113f366 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 12:38:22 +0200 Subject: [PATCH 32/49] Refactor 'invalid issue' diagnostic to use labels within the same Fluent object --- .../rustc_error_messages/locales/en-US/attr.ftl | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_error_messages/locales/en-US/attr.ftl index 378377ed8660d..56473e9c3692d 100644 --- a/compiler/rustc_error_messages/locales/en-US/attr.ftl +++ b/compiler/rustc_error_messages/locales/en-US/attr.ftl @@ -33,16 +33,11 @@ attr_invalid_meta_item = attr_invalid_issue_string = `issue` must be a non-zero numeric string or "none" -attr_must_not_be_zero = - `issue` must not be "0", use "none" instead -attr_empty = - cannot parse integer from empty string -attr_invalid_digit = - invalid digit found in string -attr_pos_overflow = - number too large to fit in target type -attr_neg_overflow = - number too small to fit in target type + .must_not_be_zero = `issue` must not be "0", use "none" instead + .empty = cannot parse integer from empty string + .invalid_digit = invalid digit found in string + .pos_overflow = number too large to fit in target type + .neg_overflow = number too small to fit in target type attr_missing_issue = missing 'issue' From c4f59605d2f460aadaa23c92dda826b8906ebc4b Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 20:56:29 +0200 Subject: [PATCH 33/49] Refactor remaining diagnostics --- compiler/rustc_attr/src/builtin.rs | 165 +++++++----------- .../locales/en-US/attr.ftl | 31 +++- 2 files changed, 93 insertions(+), 103 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index b752daecc8820..96cedfd6fb06e 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -3,7 +3,6 @@ use rustc_ast as ast; use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem, NodeId}; use rustc_ast_pretty::pprust; -use rustc_errors::{struct_span_err, Applicability}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_macros::HashStable_Generic; use rustc_session::lint::builtin::UNEXPECTED_CFGS; @@ -14,7 +13,7 @@ use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; use std::num::NonZeroU32; -use crate::session_diagnostics; +use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() @@ -276,7 +275,7 @@ where *item = Some(v); true } else { - sess.emit_err(session_diagnostics::InvalidMetaItem { span: meta.span }); + sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); false } }; @@ -788,7 +787,6 @@ where I: Iterator, { let mut depr: Option<(Deprecation, Span)> = None; - let diagnostic = &sess.parse_sess.span_diagnostic; let is_rustc = sess.features_untracked().staged_api; 'outer: for attr in attrs_iter { @@ -829,8 +827,12 @@ where ), ); } else { - struct_span_err!(diagnostic, meta.span, E0551, "incorrect meta item") - .emit(); + // FIXME: This diagnostic is identical to `IncorrectMetaItem`, barring + // the error code. Consider changing this to `IncorrectMetaItem`. See + // #51489. + sess.emit_err(session_diagnostics::IncorrectMetaItem2 { + span: meta.span, + }); } false @@ -971,19 +973,9 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { sym::simd => Some(ReprSimd), sym::transparent => Some(ReprTransparent), sym::align => { - let mut err = struct_span_err!( - diagnostic, - item.span(), - E0589, - "invalid `repr(align)` attribute: `align` needs an argument" - ); - err.span_suggestion( - item.span(), - "supply an argument here", - "align(...)", - Applicability::HasPlaceholders, - ); - err.emit(); + sess.emit_err(session_diagnostics::InvalidReprAlignNeedArg { + span: item.span(), + }); recognised = true; None } @@ -1012,57 +1004,44 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { || int_type_of_word(name).is_some() { recognised = true; - struct_span_err!( - diagnostic, - item.span(), - E0552, - "invalid representation hint: `{}` does not take a parenthesized argument list", - name.to_ident_string(), - ).emit(); + sess.emit_err(session_diagnostics::InvalidReprHintNoParen { + span: item.span(), + name: name.to_ident_string(), + }); } if let Some(literal_error) = literal_error { - struct_span_err!( - diagnostic, - item.span(), - E0589, - "invalid `repr({})` attribute: {}", - name.to_ident_string(), - literal_error - ) - .emit(); + sess.emit_err(session_diagnostics::InvalidReprGeneric { + span: item.span(), + repr_arg: name.to_ident_string(), + error_part: literal_error, + }); } } else if let Some(meta_item) = item.meta_item() { if let MetaItemKind::NameValue(ref value) = meta_item.kind { if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) { let name = meta_item.name_or_empty().to_ident_string(); recognised = true; - let mut err = struct_span_err!( - diagnostic, - item.span(), - E0693, - "incorrect `repr({})` attribute format", - name, - ); - match value.kind { - ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { - err.span_suggestion( - item.span(), - "use parentheses instead", - format!("{}({})", name, int), - Applicability::MachineApplicable, - ); - } - ast::LitKind::Str(s, _) => { - err.span_suggestion( - item.span(), - "use parentheses instead", - format!("{}({})", name, s), - Applicability::MachineApplicable, - ); - } - _ => {} - } - err.emit(); + sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric { + span: item.span(), + repr_arg: &name, + cause: match value.kind { + ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { + Some(IncorrectReprFormatGenericCause::Int { + span: item.span(), + name: &name, + int, + }) + } + ast::LitKind::Str(symbol, _) => { + Some(IncorrectReprFormatGenericCause::Symbol { + span: item.span(), + name: &name, + symbol, + }) + } + _ => None, + }, + }); } else { if matches!( meta_item.name_or_empty(), @@ -1070,51 +1049,33 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { ) || int_type_of_word(meta_item.name_or_empty()).is_some() { recognised = true; - struct_span_err!( - diagnostic, - meta_item.span, - E0552, - "invalid representation hint: `{}` does not take a value", - meta_item.name_or_empty().to_ident_string(), - ) - .emit(); + sess.emit_err(session_diagnostics::InvalidReprHintNoValue { + span: meta_item.span, + name: meta_item.name_or_empty().to_ident_string(), + }); } } } else if let MetaItemKind::List(_) = meta_item.kind { if meta_item.has_name(sym::align) { recognised = true; - struct_span_err!( - diagnostic, - meta_item.span, - E0693, - "incorrect `repr(align)` attribute format: \ - `align` takes exactly one argument in parentheses" - ) - .emit(); + sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg { + span: meta_item.span, + }); } else if meta_item.has_name(sym::packed) { recognised = true; - struct_span_err!( - diagnostic, - meta_item.span, - E0552, - "incorrect `repr(packed)` attribute format: \ - `packed` takes exactly one parenthesized argument, \ - or no parentheses at all" - ) - .emit(); + sess.emit_err(session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { + span: meta_item.span, + }); } else if matches!( meta_item.name_or_empty(), sym::C | sym::simd | sym::transparent ) || int_type_of_word(meta_item.name_or_empty()).is_some() { recognised = true; - struct_span_err!( - diagnostic, - meta_item.span, - E0552, - "invalid representation hint: `{}` does not take a parenthesized argument list", - meta_item.name_or_empty().to_ident_string(), - ).emit(); + sess.emit_err(session_diagnostics::InvalidReprHintNoParen { + span: meta_item.span, + name: meta_item.name_or_empty().to_ident_string(), + }); } } } @@ -1211,10 +1172,10 @@ fn allow_unstable<'a>( let list = attrs .filter_map(move |attr| { attr.meta_item_list().or_else(|| { - sess.diagnostic().span_err( - attr.span, - &format!("`{}` expects a list of feature names", symbol.to_ident_string()), - ); + sess.emit_err(session_diagnostics::ExpectsFeatureList { + span: attr.span, + name: symbol.to_ident_string(), + }); None }) }) @@ -1223,10 +1184,10 @@ fn allow_unstable<'a>( list.into_iter().filter_map(move |it| { let name = it.ident().map(|ident| ident.name); if name.is_none() { - sess.diagnostic().span_err( - it.span(), - &format!("`{}` expects feature names", symbol.to_ident_string()), - ); + sess.emit_err(session_diagnostics::ExpectsFeatures { + span: it.span(), + name: symbol.to_ident_string(), + }); } name }) diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_error_messages/locales/en-US/attr.ftl index 56473e9c3692d..ad4a70fac8c5f 100644 --- a/compiler/rustc_error_messages/locales/en-US/attr.ftl +++ b/compiler/rustc_error_messages/locales/en-US/attr.ftl @@ -28,7 +28,7 @@ attr_unsupported_literal_deprecated_kv_pair = attr_unsupported_literal_suggestion = consider removing the prefix -attr_invalid_meta_item = +attr_incorrect_meta_item = incorrect meta item attr_invalid_issue_string = @@ -76,3 +76,32 @@ attr_deprecated_item_suggestion = attr_missing_note = missing 'note' + +attr_invalid_repr_align_need_arg = + invalid `repr(align)` attribute: `align` needs an argument + .suggestion = supply an argument here + +attr_invalid_repr_generic = + invalid `repr({$repr_arg})` attribute: {$error_part} + +attr_invalid_repr_hint_no_paren = + invalid representation hint: `{$name}` does not take a parenthesized argument list + +attr_invalid_repr_hint_no_value = + invalid representation hint: `{$name}` does not take a value + +attr_incorrect_repr_format_generic = + incorrect `repr({$repr_arg})` attribute format + .suggestion = use parentheses instead + +attr_incorrect_repr_format_align_one_arg = + incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses + +attr_incorrect_repr_format_packed_one_or_zero_arg = + incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all + +attr_expects_feature_list = + `{$name}` expects a list of feature names + +attr_expects_features = + `{$name}` expects feature names From 1c28006bf6f6e0f989c725c74c1ee7d14cd62b81 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 21:43:03 +0200 Subject: [PATCH 34/49] Reorder diagnostics in code order, then alphabetical order --- compiler/rustc_attr/src/builtin.rs | 3 - .../rustc_attr/src/session_diagnostics.rs | 343 ++++++++++++------ .../locales/en-US/attr.ftl | 114 +++--- 3 files changed, 290 insertions(+), 170 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 96cedfd6fb06e..17ea47082d446 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -827,9 +827,6 @@ where ), ); } else { - // FIXME: This diagnostic is identical to `IncorrectMetaItem`, barring - // the error code. Consider changing this to `IncorrectMetaItem`. See - // #51489. sess.emit_err(session_diagnostics::IncorrectMetaItem2 { span: meta.span, }); diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 4b9f1541f4733..d0b1f02cf3c16 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -3,140 +3,82 @@ use std::num::IntErrorKind; use rustc_errors::{error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_macros::SessionDiagnostic; use rustc_session::{parse::ParseSess, SessionDiagnostic}; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use crate::UnsupportedLiteralReason; #[derive(SessionDiagnostic)] -#[error(attr::multiple_item, code = "E0538")] -pub(crate) struct MultipleItem { - #[primary_span] - pub span: Span, - - pub item: String, -} - -#[derive(SessionDiagnostic)] -#[error(attr::missing_since, code = "E0542")] -pub(crate) struct MissingSince { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(attr::non_ident_feature, code = "E0546")] -pub(crate) struct NonIdentFeature { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(attr::missing_feature, code = "E0546")] -pub(crate) struct MissingFeature { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(attr::multiple_stability_levels, code = "E0544")] -pub(crate) struct MultipleStabilityLevels { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(attr::invalid_meta_item, code = "E0539")] -pub(crate) struct InvalidMetaItem { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(attr::missing_issue, code = "E0547")] -pub(crate) struct MissingIssue { - #[primary_span] - pub span: Span, -} - -#[derive(SessionDiagnostic)] -#[error(attr::rustc_promotable_pairing, code = "E0717")] -pub(crate) struct RustcPromotablePairing { +#[error(attr::expected_one_cfg_pattern, code = "E0536")] +pub(crate) struct ExpectedOneCfgPattern { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::rustc_allowed_unstable_pairing, code = "E0789")] -pub(crate) struct RustcAllowedUnstablePairing { +#[error(attr::invalid_predicate, code = "E0537")] +pub(crate) struct InvalidPredicate { #[primary_span] pub span: Span, -} -#[derive(SessionDiagnostic)] -#[error(attr::soft_no_args)] -pub(crate) struct SoftNoArgs { - #[primary_span] - pub span: Span, + pub predicate: String, } #[derive(SessionDiagnostic)] -#[error(attr::expected_version_literal)] -pub(crate) struct ExpectedVersionLiteral { +#[error(attr::multiple_item, code = "E0538")] +pub(crate) struct MultipleItem { #[primary_span] pub span: Span, -} -#[derive(SessionDiagnostic)] -#[error(attr::expected_single_version_literal)] -pub(crate) struct ExpectedSingleVersionLiteral { - #[primary_span] - pub span: Span, + pub item: String, } #[derive(SessionDiagnostic)] -#[warning(attr::unknown_version_literal)] -pub(crate) struct UnknownVersionLiteral { +#[error(attr::incorrect_meta_item, code = "E0539")] +pub(crate) struct IncorrectMetaItem { #[primary_span] pub span: Span, } -#[derive(SessionDiagnostic)] -#[error(attr::expected_one_cfg_pattern, code = "E0536")] -pub(crate) struct ExpectedOneCfgPattern { - #[primary_span] +// Error code: E0541 +pub(crate) struct UnknownMetaItem<'a> { pub span: Span, + pub item: String, + pub expected: &'a [&'a str], } -#[derive(SessionDiagnostic)] -#[error(attr::invalid_predicate, code = "E0537")] -pub(crate) struct InvalidPredicate { - #[primary_span] - pub span: Span, - - pub predicate: String, +// Manual implementation to be able to format `expected` items correctly. +impl<'a> SessionDiagnostic<'a> for UnknownMetaItem<'_> { + fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::>(); + let mut diag = sess.span_diagnostic.struct_span_err_with_code( + self.span, + fluent::attr::unknown_meta_item, + error_code!(E0541), + ); + diag.set_arg("item", self.item); + diag.set_arg("expected", expected.join(", ")); + diag.span_label(self.span, fluent::attr::label); + diag + } } #[derive(SessionDiagnostic)] -#[error(attr::cfg_predicate_identifier)] -pub(crate) struct CfgPredicateIdentifier { +#[error(attr::missing_since, code = "E0542")] +pub(crate) struct MissingSince { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::deprecated_item_suggestion)] -#[note] -pub(crate) struct DeprecatedItemSuggestion { +#[error(attr::missing_note, code = "E0543")] +pub(crate) struct MissingNote { #[primary_span] pub span: Span, - - #[help] - pub is_nightly: Option<()>, } #[derive(SessionDiagnostic)] -#[error(attr::missing_note, code = "E0543")] -pub(crate) struct MissingNote { +#[error(attr::multiple_stability_levels, code = "E0544")] +pub(crate) struct MultipleStabilityLevels { #[primary_span] pub span: Span, } @@ -199,28 +141,64 @@ impl InvalidIssueStringCause { } } -pub(crate) struct UnknownMetaItem<'a> { +#[derive(SessionDiagnostic)] +#[error(attr::missing_feature, code = "E0546")] +pub(crate) struct MissingFeature { + #[primary_span] pub span: Span, - pub item: String, - pub expected: &'a [&'a str], } -// Manual implementation to be able to format `expected` items correctly. -impl<'a> SessionDiagnostic<'a> for UnknownMetaItem<'_> { - fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::>(); - let mut diag = sess.span_diagnostic.struct_span_err_with_code( - self.span, - fluent::attr::unknown_meta_item, - error_code!(E0541), - ); - diag.set_arg("item", self.item); - diag.set_arg("expected", expected.join(", ")); - diag.span_label(self.span, fluent::attr::label); - diag - } +#[derive(SessionDiagnostic)] +#[error(attr::non_ident_feature, code = "E0546")] +pub(crate) struct NonIdentFeature { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::missing_issue, code = "E0547")] +pub(crate) struct MissingIssue { + #[primary_span] + pub span: Span, +} + +// FIXME: This diagnostic is identical to `IncorrectMetaItem`, barring the error code. Consider +// changing this to `IncorrectMetaItem`. See #51489. +#[derive(SessionDiagnostic)] +#[error(attr::incorrect_meta_item, code = "E0551")] +pub(crate) struct IncorrectMetaItem2 { + #[primary_span] + pub span: Span, +} + +// FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`? +// It is more similar to `IncorrectReprFormatGeneric`. +#[derive(SessionDiagnostic)] +#[error(attr::incorrect_repr_format_packed_one_or_zero_arg, code = "E0552")] +pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::invalid_repr_hint_no_paren, code = "E0552")] +pub(crate) struct InvalidReprHintNoParen { + #[primary_span] + pub span: Span, + + pub name: String, } +#[derive(SessionDiagnostic)] +#[error(attr::invalid_repr_hint_no_value, code = "E0552")] +pub(crate) struct InvalidReprHintNoValue { + #[primary_span] + pub span: Span, + + pub name: String, +} + +// Error code: E0565 pub(crate) struct UnsupportedLiteral { pub span: Span, pub reason: UnsupportedLiteralReason, @@ -256,3 +234,148 @@ impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral { diag } } +#[derive(SessionDiagnostic)] +#[error(attr::invalid_repr_align_need_arg, code = "E0589")] +pub(crate) struct InvalidReprAlignNeedArg { + #[primary_span] + #[suggestion(code = "align(...)", applicability = "has-placeholders")] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::invalid_repr_generic, code = "E0589")] +pub(crate) struct InvalidReprGeneric<'a> { + #[primary_span] + pub span: Span, + + pub repr_arg: String, + pub error_part: &'a str, +} + +#[derive(SessionDiagnostic)] +#[error(attr::incorrect_repr_format_align_one_arg, code = "E0693")] +pub(crate) struct IncorrectReprFormatAlignOneArg { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::incorrect_repr_format_generic, code = "E0693")] +pub(crate) struct IncorrectReprFormatGeneric<'a> { + #[primary_span] + pub span: Span, + + pub repr_arg: &'a str, + + #[subdiagnostic] + pub cause: Option>, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum IncorrectReprFormatGenericCause<'a> { + #[suggestion(attr::suggestion, code = "{name}({int})", applicability = "machine-applicable")] + Int { + #[primary_span] + span: Span, + + #[skip_arg] + name: &'a str, + + #[skip_arg] + int: u128, + }, + + #[suggestion( + attr::suggestion, + code = "{name}({symbol})", + applicability = "machine-applicable" + )] + Symbol { + #[primary_span] + span: Span, + + #[skip_arg] + name: &'a str, + + #[skip_arg] + symbol: Symbol, + }, +} + +#[derive(SessionDiagnostic)] +#[error(attr::rustc_promotable_pairing, code = "E0717")] +pub(crate) struct RustcPromotablePairing { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::rustc_allowed_unstable_pairing, code = "E0789")] +pub(crate) struct RustcAllowedUnstablePairing { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::cfg_predicate_identifier)] +pub(crate) struct CfgPredicateIdentifier { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::deprecated_item_suggestion)] +#[note] +pub(crate) struct DeprecatedItemSuggestion { + #[primary_span] + pub span: Span, + + #[help] + pub is_nightly: Option<()>, +} + +#[derive(SessionDiagnostic)] +#[error(attr::expected_single_version_literal)] +pub(crate) struct ExpectedSingleVersionLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::expected_version_literal)] +pub(crate) struct ExpectedVersionLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(attr::expects_feature_list)] +pub(crate) struct ExpectsFeatureList { + #[primary_span] + pub span: Span, + + pub name: String, +} + +#[derive(SessionDiagnostic)] +#[error(attr::expects_features)] +pub(crate) struct ExpectsFeatures { + #[primary_span] + pub span: Span, + + pub name: String, +} + +#[derive(SessionDiagnostic)] +#[error(attr::soft_no_args)] +pub(crate) struct SoftNoArgs { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[warning(attr::unknown_version_literal)] +pub(crate) struct UnknownVersionLiteral { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_error_messages/locales/en-US/attr.ftl index ad4a70fac8c5f..a7f8c993d4225 100644 --- a/compiler/rustc_error_messages/locales/en-US/attr.ftl +++ b/compiler/rustc_error_messages/locales/en-US/attr.ftl @@ -1,6 +1,15 @@ +attr_expected_one_cfg_pattern = + expected 1 cfg-pattern + +attr_invalid_predicate = + invalid predicate `{$predicate}` + attr_multiple_item = multiple '{$item}' items +attr_incorrect_meta_item = + incorrect meta item + attr_unknown_meta_item = unknown meta item '{$item}' .label = expected one of {$expected} @@ -8,14 +17,37 @@ attr_unknown_meta_item = attr_missing_since = missing 'since' -attr_non_ident_feature = - 'feature' is not an identifier +attr_missing_note = + missing 'note' + +attr_multiple_stability_levels = + multiple stability levels + +attr_invalid_issue_string = + `issue` must be a non-zero numeric string or "none" + .must_not_be_zero = `issue` must not be "0", use "none" instead + .empty = cannot parse integer from empty string + .invalid_digit = invalid digit found in string + .pos_overflow = number too large to fit in target type + .neg_overflow = number too small to fit in target type attr_missing_feature = missing 'feature' -attr_multiple_stability_levels = - multiple stability levels +attr_non_ident_feature = + 'feature' is not an identifier + +attr_missing_issue = + missing 'issue' + +attr_incorrect_repr_format_packed_one_or_zero_arg = + incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all + +attr_invalid_repr_hint_no_paren = + invalid representation hint: `{$name}` does not take a parenthesized argument list + +attr_invalid_repr_hint_no_value = + invalid representation hint: `{$name}` does not take a value attr_unsupported_literal_generic = unsupported literal @@ -28,19 +60,19 @@ attr_unsupported_literal_deprecated_kv_pair = attr_unsupported_literal_suggestion = consider removing the prefix -attr_incorrect_meta_item = - incorrect meta item +attr_invalid_repr_align_need_arg = + invalid `repr(align)` attribute: `align` needs an argument + .suggestion = supply an argument here -attr_invalid_issue_string = - `issue` must be a non-zero numeric string or "none" - .must_not_be_zero = `issue` must not be "0", use "none" instead - .empty = cannot parse integer from empty string - .invalid_digit = invalid digit found in string - .pos_overflow = number too large to fit in target type - .neg_overflow = number too small to fit in target type +attr_invalid_repr_generic = + invalid `repr({$repr_arg})` attribute: {$error_part} -attr_missing_issue = - missing 'issue' +attr_incorrect_repr_format_align_one_arg = + incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses + +attr_incorrect_repr_format_generic = + incorrect `repr({$repr_arg})` attribute format + .suggestion = use parentheses instead attr_rustc_promotable_pairing = `rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute @@ -48,24 +80,6 @@ attr_rustc_promotable_pairing = attr_rustc_allowed_unstable_pairing = `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute -attr_soft_no_args = - `soft` should not have any arguments - -attr_expected_version_literal = - expected a version literal - -attr_expected_single_version_literal = - expected single version literal - -attr_unknown_version_literal = - unknown version literal format, assuming it refers to a future version - -attr_expected_one_cfg_pattern = - expected 1 cfg-pattern - -attr_invalid_predicate = - invalid predicate `{$predicate}` - attr_cfg_predicate_identifier = `cfg` predicate key must be an identifier @@ -74,34 +88,20 @@ attr_deprecated_item_suggestion = .help = add `#![feature(deprecated_suggestion)]` to the crate root .note = see #94785 for more details -attr_missing_note = - missing 'note' - -attr_invalid_repr_align_need_arg = - invalid `repr(align)` attribute: `align` needs an argument - .suggestion = supply an argument here - -attr_invalid_repr_generic = - invalid `repr({$repr_arg})` attribute: {$error_part} - -attr_invalid_repr_hint_no_paren = - invalid representation hint: `{$name}` does not take a parenthesized argument list - -attr_invalid_repr_hint_no_value = - invalid representation hint: `{$name}` does not take a value - -attr_incorrect_repr_format_generic = - incorrect `repr({$repr_arg})` attribute format - .suggestion = use parentheses instead - -attr_incorrect_repr_format_align_one_arg = - incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses +attr_expected_single_version_literal = + expected single version literal -attr_incorrect_repr_format_packed_one_or_zero_arg = - incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all +attr_expected_version_literal = + expected a version literal attr_expects_feature_list = `{$name}` expects a list of feature names attr_expects_features = `{$name}` expects feature names + +attr_soft_no_args = + `soft` should not have any arguments + +attr_unknown_version_literal = + unknown version literal format, assuming it refers to a future version From 944a3e22ef39cd9640995331e3ab6d373d1241c8 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 21:52:15 +0200 Subject: [PATCH 35/49] Change to `diag` attributes --- .../rustc_attr/src/session_diagnostics.rs | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index d0b1f02cf3c16..34e9815609109 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -8,14 +8,14 @@ use rustc_span::{Span, Symbol}; use crate::UnsupportedLiteralReason; #[derive(SessionDiagnostic)] -#[error(attr::expected_one_cfg_pattern, code = "E0536")] +#[diag(attr::expected_one_cfg_pattern, code = "E0536")] pub(crate) struct ExpectedOneCfgPattern { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::invalid_predicate, code = "E0537")] +#[diag(attr::invalid_predicate, code = "E0537")] pub(crate) struct InvalidPredicate { #[primary_span] pub span: Span, @@ -24,7 +24,7 @@ pub(crate) struct InvalidPredicate { } #[derive(SessionDiagnostic)] -#[error(attr::multiple_item, code = "E0538")] +#[diag(attr::multiple_item, code = "E0538")] pub(crate) struct MultipleItem { #[primary_span] pub span: Span, @@ -33,7 +33,7 @@ pub(crate) struct MultipleItem { } #[derive(SessionDiagnostic)] -#[error(attr::incorrect_meta_item, code = "E0539")] +#[diag(attr::incorrect_meta_item, code = "E0539")] pub(crate) struct IncorrectMetaItem { #[primary_span] pub span: Span, @@ -63,28 +63,28 @@ impl<'a> SessionDiagnostic<'a> for UnknownMetaItem<'_> { } #[derive(SessionDiagnostic)] -#[error(attr::missing_since, code = "E0542")] +#[diag(attr::missing_since, code = "E0542")] pub(crate) struct MissingSince { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::missing_note, code = "E0543")] +#[diag(attr::missing_note, code = "E0543")] pub(crate) struct MissingNote { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::multiple_stability_levels, code = "E0544")] +#[diag(attr::multiple_stability_levels, code = "E0544")] pub(crate) struct MultipleStabilityLevels { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::invalid_issue_string, code = "E0545")] +#[diag(attr::invalid_issue_string, code = "E0545")] pub(crate) struct InvalidIssueString { #[primary_span] pub span: Span, @@ -142,21 +142,21 @@ impl InvalidIssueStringCause { } #[derive(SessionDiagnostic)] -#[error(attr::missing_feature, code = "E0546")] +#[diag(attr::missing_feature, code = "E0546")] pub(crate) struct MissingFeature { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::non_ident_feature, code = "E0546")] +#[diag(attr::non_ident_feature, code = "E0546")] pub(crate) struct NonIdentFeature { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::missing_issue, code = "E0547")] +#[diag(attr::missing_issue, code = "E0547")] pub(crate) struct MissingIssue { #[primary_span] pub span: Span, @@ -165,7 +165,7 @@ pub(crate) struct MissingIssue { // FIXME: This diagnostic is identical to `IncorrectMetaItem`, barring the error code. Consider // changing this to `IncorrectMetaItem`. See #51489. #[derive(SessionDiagnostic)] -#[error(attr::incorrect_meta_item, code = "E0551")] +#[diag(attr::incorrect_meta_item, code = "E0551")] pub(crate) struct IncorrectMetaItem2 { #[primary_span] pub span: Span, @@ -174,14 +174,14 @@ pub(crate) struct IncorrectMetaItem2 { // FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`? // It is more similar to `IncorrectReprFormatGeneric`. #[derive(SessionDiagnostic)] -#[error(attr::incorrect_repr_format_packed_one_or_zero_arg, code = "E0552")] +#[diag(attr::incorrect_repr_format_packed_one_or_zero_arg, code = "E0552")] pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::invalid_repr_hint_no_paren, code = "E0552")] +#[diag(attr::invalid_repr_hint_no_paren, code = "E0552")] pub(crate) struct InvalidReprHintNoParen { #[primary_span] pub span: Span, @@ -190,7 +190,7 @@ pub(crate) struct InvalidReprHintNoParen { } #[derive(SessionDiagnostic)] -#[error(attr::invalid_repr_hint_no_value, code = "E0552")] +#[diag(attr::invalid_repr_hint_no_value, code = "E0552")] pub(crate) struct InvalidReprHintNoValue { #[primary_span] pub span: Span, @@ -234,8 +234,9 @@ impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral { diag } } + #[derive(SessionDiagnostic)] -#[error(attr::invalid_repr_align_need_arg, code = "E0589")] +#[diag(attr::invalid_repr_align_need_arg, code = "E0589")] pub(crate) struct InvalidReprAlignNeedArg { #[primary_span] #[suggestion(code = "align(...)", applicability = "has-placeholders")] @@ -243,7 +244,7 @@ pub(crate) struct InvalidReprAlignNeedArg { } #[derive(SessionDiagnostic)] -#[error(attr::invalid_repr_generic, code = "E0589")] +#[diag(attr::invalid_repr_generic, code = "E0589")] pub(crate) struct InvalidReprGeneric<'a> { #[primary_span] pub span: Span, @@ -253,14 +254,14 @@ pub(crate) struct InvalidReprGeneric<'a> { } #[derive(SessionDiagnostic)] -#[error(attr::incorrect_repr_format_align_one_arg, code = "E0693")] +#[diag(attr::incorrect_repr_format_align_one_arg, code = "E0693")] pub(crate) struct IncorrectReprFormatAlignOneArg { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::incorrect_repr_format_generic, code = "E0693")] +#[diag(attr::incorrect_repr_format_generic, code = "E0693")] pub(crate) struct IncorrectReprFormatGeneric<'a> { #[primary_span] pub span: Span, @@ -303,28 +304,28 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> { } #[derive(SessionDiagnostic)] -#[error(attr::rustc_promotable_pairing, code = "E0717")] +#[diag(attr::rustc_promotable_pairing, code = "E0717")] pub(crate) struct RustcPromotablePairing { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::rustc_allowed_unstable_pairing, code = "E0789")] +#[diag(attr::rustc_allowed_unstable_pairing, code = "E0789")] pub(crate) struct RustcAllowedUnstablePairing { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::cfg_predicate_identifier)] +#[diag(attr::cfg_predicate_identifier)] pub(crate) struct CfgPredicateIdentifier { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::deprecated_item_suggestion)] +#[diag(attr::deprecated_item_suggestion)] #[note] pub(crate) struct DeprecatedItemSuggestion { #[primary_span] @@ -335,21 +336,21 @@ pub(crate) struct DeprecatedItemSuggestion { } #[derive(SessionDiagnostic)] -#[error(attr::expected_single_version_literal)] +#[diag(attr::expected_single_version_literal)] pub(crate) struct ExpectedSingleVersionLiteral { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::expected_version_literal)] +#[diag(attr::expected_version_literal)] pub(crate) struct ExpectedVersionLiteral { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(attr::expects_feature_list)] +#[diag(attr::expects_feature_list)] pub(crate) struct ExpectsFeatureList { #[primary_span] pub span: Span, @@ -358,7 +359,7 @@ pub(crate) struct ExpectsFeatureList { } #[derive(SessionDiagnostic)] -#[error(attr::expects_features)] +#[diag(attr::expects_features)] pub(crate) struct ExpectsFeatures { #[primary_span] pub span: Span, @@ -367,14 +368,14 @@ pub(crate) struct ExpectsFeatures { } #[derive(SessionDiagnostic)] -#[error(attr::soft_no_args)] +#[diag(attr::soft_no_args)] pub(crate) struct SoftNoArgs { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[warning(attr::unknown_version_literal)] +#[diag(attr::unknown_version_literal)] pub(crate) struct UnknownVersionLiteral { #[primary_span] pub span: Span, From afd34765f6ef42bd3472040933f07dbb56621565 Mon Sep 17 00:00:00 2001 From: Hampus Lidin Date: Sun, 21 Aug 2022 22:11:41 +0200 Subject: [PATCH 36/49] Move `LitKind` logic to `session_diagnostics` module --- compiler/rustc_attr/src/builtin.rs | 23 +++++-------------- .../rustc_attr/src/session_diagnostics.rs | 17 +++++++++++++- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 17ea47082d446..65edab78ce74e 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -854,6 +854,7 @@ where sess.emit_err(session_diagnostics::DeprecatedItemSuggestion { span: mi.span, is_nightly: sess.is_nightly_build().then_some(()), + details: (), }); } @@ -1021,23 +1022,11 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric { span: item.span(), repr_arg: &name, - cause: match value.kind { - ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { - Some(IncorrectReprFormatGenericCause::Int { - span: item.span(), - name: &name, - int, - }) - } - ast::LitKind::Str(symbol, _) => { - Some(IncorrectReprFormatGenericCause::Symbol { - span: item.span(), - name: &name, - symbol, - }) - } - _ => None, - }, + cause: IncorrectReprFormatGenericCause::from_lit_kind( + item.span(), + &value.kind, + &name, + ), }); } else { if matches!( diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 34e9815609109..a75e7409fba18 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -1,5 +1,6 @@ use std::num::IntErrorKind; +use rustc_ast as ast; use rustc_errors::{error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed}; use rustc_macros::SessionDiagnostic; use rustc_session::{parse::ParseSess, SessionDiagnostic}; @@ -303,6 +304,18 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> { }, } +impl<'a> IncorrectReprFormatGenericCause<'a> { + pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option { + match kind { + ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { + Some(Self::Int { span, name, int: *int }) + } + ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }), + _ => None, + } + } +} + #[derive(SessionDiagnostic)] #[diag(attr::rustc_promotable_pairing, code = "E0717")] pub(crate) struct RustcPromotablePairing { @@ -326,13 +339,15 @@ pub(crate) struct CfgPredicateIdentifier { #[derive(SessionDiagnostic)] #[diag(attr::deprecated_item_suggestion)] -#[note] pub(crate) struct DeprecatedItemSuggestion { #[primary_span] pub span: Span, #[help] pub is_nightly: Option<()>, + + #[note] + pub details: (), } #[derive(SessionDiagnostic)] From 69715c903312c3e734bfd9098a5e8773f2e19d01 Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Sat, 20 Aug 2022 20:47:31 +0000 Subject: [PATCH 37/49] sugg: suggest the usage of boolean value when there is a typo in the keyword Signed-off-by: Vincenzo Palazzo --- .../rustc_resolve/src/late/diagnostics.rs | 27 +++++++++++++++---- .../ui/suggestions/bool_typo_err_suggest.rs | 12 +++++++++ .../suggestions/bool_typo_err_suggest.stderr | 25 +++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/suggestions/bool_typo_err_suggest.rs create mode 100644 src/test/ui/suggestions/bool_typo_err_suggest.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 4175527da470c..9bb6e4645804b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -250,13 +250,30 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .map_or_else(String::new, |res| format!("{} ", res.descr())); (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)), None) }; + + let (fallback_label, suggestion) = if path_str == "async" + && expected.starts_with("struct") + { + ("`async` blocks are only allowed in Rust 2018 or later".to_string(), suggestion) + } else { + // check if we are in situation of typo like `True` instead of `true`. + let override_suggestion = + if ["true", "false"].contains(&item_str.to_string().to_lowercase().as_str()) { + let item_typo = item_str.to_string().to_lowercase(); + Some(( + item_span, + "you may want to use a bool value instead", + format!("{}", item_typo), + )) + } else { + suggestion + }; + (format!("not found in {mod_str}"), override_suggestion) + }; + BaseError { msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"), - fallback_label: if path_str == "async" && expected.starts_with("struct") { - "`async` blocks are only allowed in Rust 2018 or later".to_string() - } else { - format!("not found in {mod_str}") - }, + fallback_label, span: item_span, span_label: None, could_be_expr: false, diff --git a/src/test/ui/suggestions/bool_typo_err_suggest.rs b/src/test/ui/suggestions/bool_typo_err_suggest.rs new file mode 100644 index 0000000000000..deab0fb05b76b --- /dev/null +++ b/src/test/ui/suggestions/bool_typo_err_suggest.rs @@ -0,0 +1,12 @@ +// Suggest the boolean value instead of emit a generic error that the value +// True is not in the scope. + +fn main() { + let x = True; + //~^ ERROR cannot find value `True` in this scope + //~| HELP you may want to use a bool value instead + + let y = False; + //~^ ERROR cannot find value `False` in this scope + //~| HELP you may want to use a bool value instead +} diff --git a/src/test/ui/suggestions/bool_typo_err_suggest.stderr b/src/test/ui/suggestions/bool_typo_err_suggest.stderr new file mode 100644 index 0000000000000..52bde07ca0770 --- /dev/null +++ b/src/test/ui/suggestions/bool_typo_err_suggest.stderr @@ -0,0 +1,25 @@ +error[E0425]: cannot find value `True` in this scope + --> $DIR/bool_typo_err_suggest.rs:5:13 + | +LL | let x = True; + | ^^^^ not found in this scope + | +help: you may want to use a bool value instead + | +LL | let x = true; + | ~~~~ + +error[E0425]: cannot find value `False` in this scope + --> $DIR/bool_typo_err_suggest.rs:9:13 + | +LL | let y = False; + | ^^^^^ not found in this scope + | +help: you may want to use a bool value instead + | +LL | let y = false; + | ~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. From ee2b16100e2fad2c08f01f913b826c00024f85a8 Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Fri, 19 Aug 2022 10:21:14 +0100 Subject: [PATCH 38/49] Migrate rustc_mir_dataflow to diagnostic structs --- Cargo.lock | 3 + .../locales/en-US/rustc_mir_dataflow.ftl | 29 ++++++++ compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_mir_dataflow/Cargo.toml | 3 + compiler/rustc_mir_dataflow/src/errors.rs | 71 +++++++++++++++++++ .../src/framework/engine.rs | 13 ++-- compiler/rustc_mir_dataflow/src/lib.rs | 3 + compiler/rustc_mir_dataflow/src/rustc_peek.rs | 28 ++++---- 8 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl create mode 100644 compiler/rustc_mir_dataflow/src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index ebacd32db4fc7..a7905a12e0feb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4213,11 +4213,14 @@ dependencies = [ "regex", "rustc_ast", "rustc_data_structures", + "rustc_errors", "rustc_graphviz", "rustc_hir", "rustc_index", + "rustc_macros", "rustc_middle", "rustc_serialize", + "rustc_session", "rustc_span", "rustc_target", "smallvec", diff --git a/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl b/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl new file mode 100644 index 0000000000000..bfc9470bbdf30 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl @@ -0,0 +1,29 @@ +rustc_mir_dataflow_path_must_end_in_filename = + path must end in a filename + +rustc_mir_dataflow_unknown_formatter = + unknown formatter + +rustc_mir_dataflow_duplicate_values_for = + duplicate values for `{$name}` + +rustc_mir_dataflow_requires_an_argument = + `{$name}` requires an argument + +rustc_mir_dataflow_stop_after_dataflow_ended_compilation = + stop_after_dataflow ended compilation + +rustc_mir_dataflow_peek_must_be_place_or_ref_place = + rustc_peek: argument expression must be either `place` or `&place` + +rustc_mir_dataflow_peek_must_be_not_temporary = + dataflow::sanity_check cannot feed a non-temp to rustc_peek. + +rustc_mir_dataflow_peek_bit_not_set = + rustc_peek: bit not set + +rustc_mir_dataflow_peek_argument_not_a_local = + rustc_peek: argument was not a local + +rustc_mir_dataflow_peek_argument_untracked = + rustc_peek: argument untracked diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 3569c7f063064..bcbaa649a01fc 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -43,6 +43,7 @@ fluent_messages! { passes => "../locales/en-US/passes.ftl", privacy => "../locales/en-US/privacy.ftl", typeck => "../locales/en-US/typeck.ftl", + rustc_mir_dataflow => "../locales/en-US/rustc_mir_dataflow.ftl", } pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index baf9735fbc846..385e9ba748fb9 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -13,10 +13,13 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } +rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_serialize = { path = "../rustc_serialize" } +rustc_session = { path = "../rustc_session" } rustc_target = { path = "../rustc_target" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_mir_dataflow/src/errors.rs b/compiler/rustc_mir_dataflow/src/errors.rs new file mode 100644 index 0000000000000..a30bf35fa1a2d --- /dev/null +++ b/compiler/rustc_mir_dataflow/src/errors.rs @@ -0,0 +1,71 @@ +use rustc_macros::SessionDiagnostic; +use rustc_span::{Span, Symbol}; + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::path_must_end_in_filename)] +pub(crate) struct PathMustEndInFilename { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::unknown_formatter)] +pub(crate) struct UnknownFormatter { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::duplicate_values_for)] +pub(crate) struct DuplicateValuesFor { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::requires_an_argument)] +pub(crate) struct RequiresAnArgument { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::stop_after_dataflow_ended_compilation)] +pub(crate) struct StopAfterDataFlowEndedCompilation; + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::peek_must_be_place_or_ref_place)] +pub(crate) struct PeekMustBePlaceOrRefPlace { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::peek_must_be_not_temporary)] +pub(crate) struct PeekMustBeNotTemporary { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::peek_bit_not_set)] +pub(crate) struct PeekBitNotSet { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::peek_argument_not_a_local)] +pub(crate) struct PeekArgumentNotALocal { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(rustc_mir_dataflow::peek_argument_untracked)] +pub(crate) struct PeekArgumentUntracked { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index f374658ceb691..112204c7599be 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -1,5 +1,8 @@ //! A solver for dataflow problems. +use crate::errors::{ + DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter, +}; use crate::framework::BitSetExt; use std::ffi::OsString; @@ -347,7 +350,7 @@ impl RustcMirAttrs { match path.file_name() { Some(_) => Ok(path), None => { - tcx.sess.span_err(attr.span(), "path must end in a filename"); + tcx.sess.emit_err(PathMustEndInFilename { span: attr.span() }); Err(()) } } @@ -356,7 +359,7 @@ impl RustcMirAttrs { Self::set_field(&mut ret.formatter, tcx, &attr, |s| match s { sym::gen_kill | sym::two_phase => Ok(s), _ => { - tcx.sess.span_err(attr.span(), "unknown formatter"); + tcx.sess.emit_err(UnknownFormatter { span: attr.span() }); Err(()) } }) @@ -377,8 +380,7 @@ impl RustcMirAttrs { mapper: impl FnOnce(Symbol) -> Result, ) -> Result<(), ()> { if field.is_some() { - tcx.sess - .span_err(attr.span(), &format!("duplicate values for `{}`", attr.name_or_empty())); + tcx.sess.emit_err(DuplicateValuesFor { span: attr.span(), name: attr.name_or_empty() }); return Err(()); } @@ -387,8 +389,7 @@ impl RustcMirAttrs { *field = Some(mapper(s)?); Ok(()) } else { - tcx.sess - .span_err(attr.span(), &format!("`{}` requires an argument", attr.name_or_empty())); + tcx.sess.emit_err(RequiresAnArgument { span: attr.span(), name: attr.name_or_empty() }); Err(()) } } diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 5793a286bd03d..62b712f7b8dbd 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -7,6 +7,8 @@ #![feature(stmt_expr_attributes)] #![feature(trusted_step)] #![recursion_limit = "256"] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate tracing; @@ -33,6 +35,7 @@ use self::move_paths::MoveData; pub mod drop_flag_effects; pub mod elaborate_drops; +mod errors; mod framework; pub mod impls; pub mod move_paths; diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index f2471f37a5266..5fb7cb6584beb 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -6,6 +6,10 @@ use rustc_middle::mir::MirPass; use rustc_middle::mir::{self, Body, Local, Location}; use rustc_middle::ty::{self, Ty, TyCtxt}; +use crate::errors::{ + PeekArgumentNotALocal, PeekArgumentUntracked, PeekBitNotSet, PeekMustBeNotTemporary, + PeekMustBePlaceOrRefPlace, StopAfterDataFlowEndedCompilation, +}; use crate::framework::BitSetExt; use crate::impls::{ DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPlaces, @@ -64,7 +68,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { } if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() { - tcx.sess.fatal("stop_after_dataflow ended compilation"); + tcx.sess.emit_fatal(StopAfterDataFlowEndedCompilation); } } } @@ -133,9 +137,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>( } _ => { - let msg = "rustc_peek: argument expression \ - must be either `place` or `&place`"; - tcx.sess.span_err(call.span, msg); + tcx.sess.emit_err(PeekMustBePlaceOrRefPlace { span: call.span }); } } } @@ -204,18 +206,12 @@ impl PeekCall { if let Some(local) = place.as_local() { local } else { - tcx.sess.diagnostic().span_err( - span, - "dataflow::sanity_check cannot feed a non-temp to rustc_peek.", - ); + tcx.sess.emit_err(PeekMustBeNotTemporary { span }); return None; } } _ => { - tcx.sess.diagnostic().span_err( - span, - "dataflow::sanity_check cannot feed a non-temp to rustc_peek.", - ); + tcx.sess.emit_err(PeekMustBeNotTemporary { span }); return None; } }; @@ -255,12 +251,12 @@ where let bit_state = flow_state.contains(peek_mpi); debug!("rustc_peek({:?} = &{:?}) bit_state: {}", call.arg, place, bit_state); if !bit_state { - tcx.sess.span_err(call.span, "rustc_peek: bit not set"); + tcx.sess.emit_err(PeekBitNotSet { span: call.span }); } } LookupResult::Parent(..) => { - tcx.sess.span_err(call.span, "rustc_peek: argument untracked"); + tcx.sess.emit_err(PeekArgumentUntracked { span: call.span }); } } } @@ -276,12 +272,12 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals { ) { info!(?place, "peek_at"); let Some(local) = place.as_local() else { - tcx.sess.span_err(call.span, "rustc_peek: argument was not a local"); + tcx.sess.emit_err(PeekArgumentNotALocal { span: call.span }); return; }; if !flow_state.contains(local) { - tcx.sess.span_err(call.span, "rustc_peek: bit not set"); + tcx.sess.emit_err(PeekBitNotSet { span: call.span }); } } } From 7f125ed7d5645c7d2c7656d6303e6bdd499739a1 Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Tue, 23 Aug 2022 13:18:45 +0100 Subject: [PATCH 39/49] Remove full stop in diagnostic message --- .../rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl b/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl index bfc9470bbdf30..1bf654eb01aa0 100644 --- a/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl +++ b/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl @@ -17,7 +17,7 @@ rustc_mir_dataflow_peek_must_be_place_or_ref_place = rustc_peek: argument expression must be either `place` or `&place` rustc_mir_dataflow_peek_must_be_not_temporary = - dataflow::sanity_check cannot feed a non-temp to rustc_peek. + dataflow::sanity_check cannot feed a non-temp to rustc_peek rustc_mir_dataflow_peek_bit_not_set = rustc_peek: bit not set From f20cc9ae4ea6e9b5226680e93229a53468022350 Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Tue, 23 Aug 2022 13:48:15 +0100 Subject: [PATCH 40/49] Rename rustc_mir_dataflow diagnostic to mir_dataflow --- .../locales/en-US/mir_dataflow.ftl | 29 +++++++++++++++++++ .../locales/en-US/rustc_mir_dataflow.ftl | 29 ------------------- compiler/rustc_error_messages/src/lib.rs | 2 +- compiler/rustc_mir_dataflow/src/errors.rs | 20 ++++++------- 4 files changed, 40 insertions(+), 40 deletions(-) create mode 100644 compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl delete mode 100644 compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl diff --git a/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl b/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl new file mode 100644 index 0000000000000..9885415250883 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl @@ -0,0 +1,29 @@ +mir_dataflow_path_must_end_in_filename = + path must end in a filename + +mir_dataflow_unknown_formatter = + unknown formatter + +mir_dataflow_duplicate_values_for = + duplicate values for `{$name}` + +mir_dataflow_requires_an_argument = + `{$name}` requires an argument + +mir_dataflow_stop_after_dataflow_ended_compilation = + stop_after_dataflow ended compilation + +mir_dataflow_peek_must_be_place_or_ref_place = + rustc_peek: argument expression must be either `place` or `&place` + +mir_dataflow_peek_must_be_not_temporary = + dataflow::sanity_check cannot feed a non-temp to rustc_peek + +mir_dataflow_peek_bit_not_set = + rustc_peek: bit not set + +mir_dataflow_peek_argument_not_a_local = + rustc_peek: argument was not a local + +mir_dataflow_peek_argument_untracked = + rustc_peek: argument untracked diff --git a/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl b/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl deleted file mode 100644 index 1bf654eb01aa0..0000000000000 --- a/compiler/rustc_error_messages/locales/en-US/rustc_mir_dataflow.ftl +++ /dev/null @@ -1,29 +0,0 @@ -rustc_mir_dataflow_path_must_end_in_filename = - path must end in a filename - -rustc_mir_dataflow_unknown_formatter = - unknown formatter - -rustc_mir_dataflow_duplicate_values_for = - duplicate values for `{$name}` - -rustc_mir_dataflow_requires_an_argument = - `{$name}` requires an argument - -rustc_mir_dataflow_stop_after_dataflow_ended_compilation = - stop_after_dataflow ended compilation - -rustc_mir_dataflow_peek_must_be_place_or_ref_place = - rustc_peek: argument expression must be either `place` or `&place` - -rustc_mir_dataflow_peek_must_be_not_temporary = - dataflow::sanity_check cannot feed a non-temp to rustc_peek - -rustc_mir_dataflow_peek_bit_not_set = - rustc_peek: bit not set - -rustc_mir_dataflow_peek_argument_not_a_local = - rustc_peek: argument was not a local - -rustc_mir_dataflow_peek_argument_untracked = - rustc_peek: argument untracked diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index bcbaa649a01fc..52451306bcd4c 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -43,7 +43,7 @@ fluent_messages! { passes => "../locales/en-US/passes.ftl", privacy => "../locales/en-US/privacy.ftl", typeck => "../locales/en-US/typeck.ftl", - rustc_mir_dataflow => "../locales/en-US/rustc_mir_dataflow.ftl", + mir_dataflow => "../locales/en-US/mir_dataflow.ftl", } pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; diff --git a/compiler/rustc_mir_dataflow/src/errors.rs b/compiler/rustc_mir_dataflow/src/errors.rs index a30bf35fa1a2d..cc14257876c5c 100644 --- a/compiler/rustc_mir_dataflow/src/errors.rs +++ b/compiler/rustc_mir_dataflow/src/errors.rs @@ -2,21 +2,21 @@ use rustc_macros::SessionDiagnostic; use rustc_span::{Span, Symbol}; #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::path_must_end_in_filename)] +#[diag(mir_dataflow::path_must_end_in_filename)] pub(crate) struct PathMustEndInFilename { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::unknown_formatter)] +#[diag(mir_dataflow::unknown_formatter)] pub(crate) struct UnknownFormatter { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::duplicate_values_for)] +#[diag(mir_dataflow::duplicate_values_for)] pub(crate) struct DuplicateValuesFor { #[primary_span] pub span: Span, @@ -24,7 +24,7 @@ pub(crate) struct DuplicateValuesFor { } #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::requires_an_argument)] +#[diag(mir_dataflow::requires_an_argument)] pub(crate) struct RequiresAnArgument { #[primary_span] pub span: Span, @@ -32,39 +32,39 @@ pub(crate) struct RequiresAnArgument { } #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::stop_after_dataflow_ended_compilation)] +#[diag(mir_dataflow::stop_after_dataflow_ended_compilation)] pub(crate) struct StopAfterDataFlowEndedCompilation; #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::peek_must_be_place_or_ref_place)] +#[diag(mir_dataflow::peek_must_be_place_or_ref_place)] pub(crate) struct PeekMustBePlaceOrRefPlace { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::peek_must_be_not_temporary)] +#[diag(mir_dataflow::peek_must_be_not_temporary)] pub(crate) struct PeekMustBeNotTemporary { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::peek_bit_not_set)] +#[diag(mir_dataflow::peek_bit_not_set)] pub(crate) struct PeekBitNotSet { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::peek_argument_not_a_local)] +#[diag(mir_dataflow::peek_argument_not_a_local)] pub(crate) struct PeekArgumentNotALocal { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[diag(rustc_mir_dataflow::peek_argument_untracked)] +#[diag(mir_dataflow::peek_argument_untracked)] pub(crate) struct PeekArgumentUntracked { #[primary_span] pub span: Span, From 1693993d8ff16b1a5d288bc858db052902126053 Mon Sep 17 00:00:00 2001 From: Rejyr Date: Tue, 23 Aug 2022 10:41:02 -0400 Subject: [PATCH 41/49] cleanup: commented lints --- compiler/rustc_lint/src/builtin.rs | 3 --- compiler/rustc_lint/src/context.rs | 3 --- compiler/rustc_lint/src/levels.rs | 3 --- compiler/rustc_lint/src/lib.rs | 2 -- 4 files changed, 11 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 507abad0d5674..af7ef96e485b5 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1,6 +1,3 @@ -// #![deny(rustc::diagnostic_outside_of_impl)] -// #![deny(rustc::untranslatable_diagnostic)] -// //! Lints in the Rust compiler. //! //! This contains lints which can feasibly be implemented as their own diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index a1fdc557f9298..e0679a6112a4c 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1,6 +1,3 @@ -// #![deny(rustc::diagnostic_outside_of_impl)] -// #![deny(rustc::untranslatable_diagnostic)] -// //! Implementation of lint checking. //! //! The lint checking is mostly consolidated into one pass which runs diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 41d89229009ba..89409b58f88b9 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1,6 +1,3 @@ -// #![deny(rustc::diagnostic_outside_of_impl)] -// #![deny(rustc::untranslatable_diagnostic)] -// use crate::context::{CheckLintNameResult, LintStore}; use crate::late::unerased_lint_store; use rustc_ast as ast; diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 23fd5d5eea081..f34e062fd12a9 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -36,8 +36,6 @@ #![feature(let_else)] #![feature(never_type)] #![recursion_limit = "256"] -// #![deny(rustc::diagnostic_outside_of_impl)] -// #![deny(rustc::untranslatable_diagnostic)] #[macro_use] extern crate rustc_middle; From dbe39d835e93d784076b96564176825e556e8824 Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Mon, 22 Aug 2022 23:43:09 +0200 Subject: [PATCH 42/49] Start moving rustc_driver to SessionDiagnostic --- Cargo.lock | 1 + compiler/rustc_driver/Cargo.toml | 1 + compiler/rustc_driver/src/lib.rs | 29 +++++++++++++++---- .../rustc_driver/src/session_diagnostics.rs | 25 ++++++++++++++++ .../locales/en-US/driver.ftl | 5 ++++ compiler/rustc_error_messages/src/lib.rs | 1 + 6 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 compiler/rustc_driver/src/session_diagnostics.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/driver.ftl diff --git a/Cargo.lock b/Cargo.lock index 9464c87fc728b..3776d562ff8cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3820,6 +3820,7 @@ dependencies = [ "rustc_interface", "rustc_lint", "rustc_log", + "rustc_macros", "rustc_metadata", "rustc_middle", "rustc_parse", diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index 08d5d4f343c77..4570c1448337e 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -19,6 +19,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } +rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } rustc_parse = { path = "../rustc_parse" } rustc_plugin_impl = { path = "../rustc_plugin_impl" } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index dac8df7dc55e0..a34face14a993 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -9,6 +9,8 @@ #![feature(once_cell)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate tracing; @@ -56,6 +58,9 @@ use std::time::Instant; pub mod args; pub mod pretty; +mod session_diagnostics; + +use crate::session_diagnostics::{RlinkNotAFile, RlinkUnableToDeserialize, RlinkUnableToRead}; /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -545,7 +550,11 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { fn show_content_with_pager(content: &str) { let pager_name = env::var_os("PAGER").unwrap_or_else(|| { - if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") } + if cfg!(windows) { + OsString::from("more.com") + } else { + OsString::from("less") + } }); let mut fallback_to_println = false; @@ -581,18 +590,24 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp sess.init_crate_types(collect_crate_types(sess, &[])); let outputs = compiler.build_output_filenames(sess, &[]); let rlink_data = fs::read(file).unwrap_or_else(|err| { - sess.fatal(&format!("failed to read rlink file: {}", err)); + sess.fatal(RlinkUnableToRead { + span: Default::default(), + error_message: err.to_string(), + }); }); let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) { Ok(codegen) => codegen, Err(error) => { - sess.fatal(&format!("Could not deserialize .rlink file: {error}")); + sess.fatal(RlinkUnableToDeserialize { + span: Default::default(), + error_message: error.to_string(), + }); } }; let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); abort_on_err(result, sess); } else { - sess.fatal("rlink must be a file") + sess.fatal(RlinkNotAFile { span: Default::default() }) } Compilation::Stop } else { @@ -1116,7 +1131,11 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { } } - if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None } + if !result.is_empty() { + Some((result, excluded_cargo_defaults)) + } else { + None + } } /// Runs a closure and catches unwinds triggered by fatal errors. diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs new file mode 100644 index 0000000000000..19468cb678d29 --- /dev/null +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -0,0 +1,25 @@ +use rustc_macros::SessionDiagnostic; +use rustc_span::Span; + +#[derive(SessionDiagnostic)] +#[error(driver::rlink_unable_to_read)] +pub(crate) struct RlinkUnableToRead { + #[primary_span] + pub span: Span, + pub error_message: String, +} + +#[derive(SessionDiagnostic)] +#[error(driver::rlink_unable_to_deserialize)] +pub(crate) struct RlinkUnableToDeserialize { + #[primary_span] + pub span: Span, + pub error_message: String, +} + +#[derive(SessionDiagnostic)] +#[error(driver::rlink_no_a_file)] +pub(crate) struct RlinkNotAFile { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_error_messages/locales/en-US/driver.ftl b/compiler/rustc_error_messages/locales/en-US/driver.ftl new file mode 100644 index 0000000000000..57104612cc8e4 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/driver.ftl @@ -0,0 +1,5 @@ +driver_rlink_unable_to_read = failed to read rlink file: `{$error_message}` + +driver_rlink_unable_to_deserialize = could not deserialize .rlink file: `{$error_message}` + +driver_rlink_no_a_file = rlink must be a file diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 2d001d445be02..2ea07ca1a487a 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -36,6 +36,7 @@ fluent_messages! { borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", const_eval => "../locales/en-US/const_eval.ftl", + driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", interface => "../locales/en-US/interface.ftl", lint => "../locales/en-US/lint.ftl", From e7ded9246c12319330c39b3ab10162935ccbfe17 Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Tue, 23 Aug 2022 18:48:46 +0200 Subject: [PATCH 43/49] Fixes fmt & SessionDiagnostic structs --- compiler/rustc_driver/src/lib.rs | 24 ++++--------------- .../rustc_driver/src/session_diagnostics.rs | 16 ++++--------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index a34face14a993..33af7fd0e42c0 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -550,11 +550,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { fn show_content_with_pager(content: &str) { let pager_name = env::var_os("PAGER").unwrap_or_else(|| { - if cfg!(windows) { - OsString::from("more.com") - } else { - OsString::from("less") - } + if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") } }); let mut fallback_to_println = false; @@ -590,24 +586,18 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp sess.init_crate_types(collect_crate_types(sess, &[])); let outputs = compiler.build_output_filenames(sess, &[]); let rlink_data = fs::read(file).unwrap_or_else(|err| { - sess.fatal(RlinkUnableToRead { - span: Default::default(), - error_message: err.to_string(), - }); + sess.emit_fatal(RlinkUnableToRead { error_message: err.to_string() }); }); let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) { Ok(codegen) => codegen, Err(error) => { - sess.fatal(RlinkUnableToDeserialize { - span: Default::default(), - error_message: error.to_string(), - }); + sess.emit_fatal(RlinkUnableToDeserialize { error_message: error.to_string() }); } }; let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); abort_on_err(result, sess); } else { - sess.fatal(RlinkNotAFile { span: Default::default() }) + sess.emit_fatal(RlinkNotAFile {}) } Compilation::Stop } else { @@ -1131,11 +1121,7 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { } } - if !result.is_empty() { - Some((result, excluded_cargo_defaults)) - } else { - None - } + if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None } } /// Runs a closure and catches unwinds triggered by fatal errors. diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs index 19468cb678d29..ed10a66c8231c 100644 --- a/compiler/rustc_driver/src/session_diagnostics.rs +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -1,25 +1,17 @@ use rustc_macros::SessionDiagnostic; -use rustc_span::Span; #[derive(SessionDiagnostic)] -#[error(driver::rlink_unable_to_read)] +#[diag(driver::rlink_unable_to_read)] pub(crate) struct RlinkUnableToRead { - #[primary_span] - pub span: Span, pub error_message: String, } #[derive(SessionDiagnostic)] -#[error(driver::rlink_unable_to_deserialize)] +#[diag(driver::rlink_unable_to_deserialize)] pub(crate) struct RlinkUnableToDeserialize { - #[primary_span] - pub span: Span, pub error_message: String, } #[derive(SessionDiagnostic)] -#[error(driver::rlink_no_a_file)] -pub(crate) struct RlinkNotAFile { - #[primary_span] - pub span: Span, -} +#[diag(driver::rlink_no_a_file)] +pub(crate) struct RlinkNotAFile {} From 1c575c5fe05110a628a7bf0e609602bb9066edec Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Wed, 24 Aug 2022 14:12:39 +0200 Subject: [PATCH 44/49] Use std::io::Error and remove useless to_string --- compiler/rustc_driver/src/lib.rs | 6 +++--- compiler/rustc_driver/src/session_diagnostics.rs | 4 ++-- compiler/rustc_error_messages/locales/en-US/driver.ftl | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 33af7fd0e42c0..90e4d629b61f5 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -586,12 +586,12 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp sess.init_crate_types(collect_crate_types(sess, &[])); let outputs = compiler.build_output_filenames(sess, &[]); let rlink_data = fs::read(file).unwrap_or_else(|err| { - sess.emit_fatal(RlinkUnableToRead { error_message: err.to_string() }); + sess.emit_fatal(RlinkUnableToRead { err }); }); let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) { Ok(codegen) => codegen, - Err(error) => { - sess.emit_fatal(RlinkUnableToDeserialize { error_message: error.to_string() }); + Err(error_message) => { + sess.emit_fatal(RlinkUnableToDeserialize { error_message }); } }; let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs index ed10a66c8231c..a5dbef45475ea 100644 --- a/compiler/rustc_driver/src/session_diagnostics.rs +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -3,7 +3,7 @@ use rustc_macros::SessionDiagnostic; #[derive(SessionDiagnostic)] #[diag(driver::rlink_unable_to_read)] pub(crate) struct RlinkUnableToRead { - pub error_message: String, + pub err: std::io::Error, } #[derive(SessionDiagnostic)] @@ -14,4 +14,4 @@ pub(crate) struct RlinkUnableToDeserialize { #[derive(SessionDiagnostic)] #[diag(driver::rlink_no_a_file)] -pub(crate) struct RlinkNotAFile {} +pub(crate) struct RlinkNotAFile; diff --git a/compiler/rustc_error_messages/locales/en-US/driver.ftl b/compiler/rustc_error_messages/locales/en-US/driver.ftl index 57104612cc8e4..0a2f0e8f883e4 100644 --- a/compiler/rustc_error_messages/locales/en-US/driver.ftl +++ b/compiler/rustc_error_messages/locales/en-US/driver.ftl @@ -1,4 +1,4 @@ -driver_rlink_unable_to_read = failed to read rlink file: `{$error_message}` +driver_rlink_unable_to_read = failed to read rlink file: `{$err}` driver_rlink_unable_to_deserialize = could not deserialize .rlink file: `{$error_message}` From 3f883b850d81be5ba6a2a4039de33fd7dd7c188d Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Wed, 24 Aug 2022 19:15:44 +0200 Subject: [PATCH 45/49] Start adding enum errors for deserialize_rlink --- compiler/rustc_codegen_ssa/src/lib.rs | 26 ++++++++---- .../src/session_diagnostic.rs | 42 +++++++++++++++++++ compiler/rustc_driver/src/lib.rs | 4 +- .../rustc_driver/src/session_diagnostics.rs | 3 +- .../locales/en-US/codegen_ssa.ftl | 9 ++++ compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_macros/src/lib.rs | 1 + 7 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 compiler/rustc_codegen_ssa/src/session_diagnostic.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 1802eedf193aa..deabdca75cb54 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -21,6 +21,7 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; +use crate::session_diagnostic::{DeserializeRlinkError, DeserializeRlinkErrorSub}; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; @@ -49,6 +50,7 @@ pub mod glue; pub mod meth; pub mod mir; pub mod mono_item; +pub mod session_diagnostic; pub mod target_features; pub mod traits; @@ -212,30 +214,40 @@ impl CodegenResults { encoder.finish() } - pub fn deserialize_rlink(data: Vec) -> Result { + pub fn deserialize_rlink(data: Vec) -> Result { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { - return Err("The input does not look like a .rlink file".to_string()); + return Err(DeserializeRlinkError { sub: DeserializeRlinkErrorSub::WrongFileType }); } let data = &data[RLINK_MAGIC.len()..]; if data.len() < 4 { - return Err("The input does not contain version number".to_string()); + return Err(DeserializeRlinkError { + sub: DeserializeRlinkErrorSub::EmptyVersionNumber, + }); } let mut version_array: [u8; 4] = Default::default(); version_array.copy_from_slice(&data[..4]); if u32::from_be_bytes(version_array) != RLINK_VERSION { - return Err(".rlink file was produced with encoding version {version_array}, but the current version is {RLINK_VERSION}".to_string()); + return Err(DeserializeRlinkError { + sub: DeserializeRlinkErrorSub::EncodingVersionMismatch { + version_array: String::from_utf8_lossy(&version_array).to_string(), + rlink_version: RLINK_VERSION.to_string(), + }, + }); } let mut decoder = MemDecoder::new(&data[4..], 0); let rustc_version = decoder.read_str(); let current_version = RUSTC_VERSION.unwrap(); if rustc_version != current_version { - return Err(format!( - ".rlink file was produced by rustc version {rustc_version}, but the current version is {current_version}." - )); + return Err(DeserializeRlinkError { + sub: DeserializeRlinkErrorSub::RustcVersionMismatch { + rustc_version: rustc_version.to_string(), + current_version: current_version.to_string(), + }, + }); } let codegen_results = CodegenResults::decode(&mut decoder); diff --git a/compiler/rustc_codegen_ssa/src/session_diagnostic.rs b/compiler/rustc_codegen_ssa/src/session_diagnostic.rs new file mode 100644 index 0000000000000..ac7065ae23cd4 --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/session_diagnostic.rs @@ -0,0 +1,42 @@ +use rustc_errors::{fluent, DiagnosticArgValue, IntoDiagnosticArg}; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use std::borrow::Cow; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::error)] +pub struct DeserializeRlinkError { + #[subdiagnostic] + pub sub: DeserializeRlinkErrorSub, +} + +#[derive(SessionSubdiagnostic)] +pub enum DeserializeRlinkErrorSub { + #[note(codegen_ssa::wrong_file_type)] + WrongFileType, + + #[note(codegen_ssa::empty_version_number)] + EmptyVersionNumber, + + #[note(codegen_ssa::encoding_version_mismatch)] + EncodingVersionMismatch { version_array: String, rlink_version: String }, + + #[note(codegen_ssa::rustc_version_mismatch)] + RustcVersionMismatch { rustc_version: String, current_version: String }, +} + +impl IntoDiagnosticArg for DeserializeRlinkErrorSub { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Borrowed(match self { + DeserializeRlinkErrorSub::WrongFileType => fluent::codegen_ssa::wrong_file_type, + DeserializeRlinkErrorSub::EmptyVersionNumber => { + fluent::codegen_ssa::empty_version_number + } + DeserializeRlinkErrorSub::EncodingVersionMismatch { version_array, rlink_version } => { + fluent::codegen_ssa::encoding_version_mismatch + } + DeserializeRlinkErrorSub::RustcVersionMismatch { rustc_version, current_version } => { + fluent::codegen_ssa::rustc_version_mismatch + } + })) + } +} diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 90e4d629b61f5..99999909d573f 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -590,8 +590,8 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp }); let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) { Ok(codegen) => codegen, - Err(error_message) => { - sess.emit_fatal(RlinkUnableToDeserialize { error_message }); + Err(err) => { + sess.emit_fatal(RlinkUnableToDeserialize { err }); } }; let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs index a5dbef45475ea..86ee51bc97d71 100644 --- a/compiler/rustc_driver/src/session_diagnostics.rs +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -1,3 +1,4 @@ +use rustc_codegen_ssa::session_diagnostic::DeserializeRlinkError; use rustc_macros::SessionDiagnostic; #[derive(SessionDiagnostic)] @@ -9,7 +10,7 @@ pub(crate) struct RlinkUnableToRead { #[derive(SessionDiagnostic)] #[diag(driver::rlink_unable_to_deserialize)] pub(crate) struct RlinkUnableToDeserialize { - pub error_message: String, + pub err: DeserializeRlinkError, } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl new file mode 100644 index 0000000000000..f93ac354773a3 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -0,0 +1,9 @@ +codegen_ssa_error = Error while deserializing rlink file + +codegen_ssa_wrong_file_type = The input does not look like a .rlink file + +codegen_ssa_empty_version_number = The input does not contain version number + +codegen_ssa_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}` + +codegen_ssa_rustc_version_mismatch = .rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}` diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 2ea07ca1a487a..b4fd883d84578 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -35,6 +35,7 @@ fluent_messages! { ast_passes => "../locales/en-US/ast_passes.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", + codegen_ssa => "../locales/en-US/codegen_ssa.ftl", const_eval => "../locales/en-US/const_eval.ftl", driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 87d7ab6ed517b..bcf406bcb9572 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -163,6 +163,7 @@ decl_derive!( decl_derive!( [SessionSubdiagnostic, attributes( // struct/variant attributes + diag, label, help, note, From bf7ce6a1a605d897832783a3d0c830d2466d90be Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Thu, 25 Aug 2022 18:05:23 +0200 Subject: [PATCH 46/49] Replace spaghetti with a simple errors enum --- compiler/rustc_codegen_ssa/src/lib.rs | 33 +++++++-------- .../src/session_diagnostic.rs | 42 ------------------- compiler/rustc_driver/src/lib.rs | 26 ++++++++++-- .../rustc_driver/src/session_diagnostics.rs | 23 ++++++++-- .../locales/en-US/codegen_ssa.ftl | 9 ---- .../locales/en-US/driver.ftl | 8 +++- compiler/rustc_error_messages/src/lib.rs | 1 - 7 files changed, 65 insertions(+), 77 deletions(-) delete mode 100644 compiler/rustc_codegen_ssa/src/session_diagnostic.rs delete mode 100644 compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index deabdca75cb54..d6fa1a15373b5 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -21,7 +21,6 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; -use crate::session_diagnostic::{DeserializeRlinkError, DeserializeRlinkErrorSub}; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; @@ -50,7 +49,6 @@ pub mod glue; pub mod meth; pub mod mir; pub mod mono_item; -pub mod session_diagnostic; pub mod target_features; pub mod traits; @@ -170,6 +168,13 @@ pub struct CodegenResults { pub crate_info: CrateInfo, } +pub enum CodegenErrors { + WrongFileType, + EmptyVersionNumber, + EncodingVersionMismatch { version_array: String, rlink_version: String }, + RustcVersionMismatch { rustc_version: String, current_version: String }, +} + pub fn provide(providers: &mut Providers) { crate::back::symbol_export::provide(providers); crate::base::provide(providers); @@ -214,27 +219,23 @@ impl CodegenResults { encoder.finish() } - pub fn deserialize_rlink(data: Vec) -> Result { + pub fn deserialize_rlink(data: Vec) -> Result { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { - return Err(DeserializeRlinkError { sub: DeserializeRlinkErrorSub::WrongFileType }); + return Err(CodegenErrors::WrongFileType); } let data = &data[RLINK_MAGIC.len()..]; if data.len() < 4 { - return Err(DeserializeRlinkError { - sub: DeserializeRlinkErrorSub::EmptyVersionNumber, - }); + return Err(CodegenErrors::EmptyVersionNumber); } let mut version_array: [u8; 4] = Default::default(); version_array.copy_from_slice(&data[..4]); if u32::from_be_bytes(version_array) != RLINK_VERSION { - return Err(DeserializeRlinkError { - sub: DeserializeRlinkErrorSub::EncodingVersionMismatch { - version_array: String::from_utf8_lossy(&version_array).to_string(), - rlink_version: RLINK_VERSION.to_string(), - }, + return Err(CodegenErrors::EncodingVersionMismatch { + version_array: String::from_utf8_lossy(&version_array).to_string(), + rlink_version: RLINK_VERSION.to_string(), }); } @@ -242,11 +243,9 @@ impl CodegenResults { let rustc_version = decoder.read_str(); let current_version = RUSTC_VERSION.unwrap(); if rustc_version != current_version { - return Err(DeserializeRlinkError { - sub: DeserializeRlinkErrorSub::RustcVersionMismatch { - rustc_version: rustc_version.to_string(), - current_version: current_version.to_string(), - }, + return Err(CodegenErrors::RustcVersionMismatch { + rustc_version: rustc_version.to_string(), + current_version: current_version.to_string(), }); } diff --git a/compiler/rustc_codegen_ssa/src/session_diagnostic.rs b/compiler/rustc_codegen_ssa/src/session_diagnostic.rs deleted file mode 100644 index ac7065ae23cd4..0000000000000 --- a/compiler/rustc_codegen_ssa/src/session_diagnostic.rs +++ /dev/null @@ -1,42 +0,0 @@ -use rustc_errors::{fluent, DiagnosticArgValue, IntoDiagnosticArg}; -use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; -use std::borrow::Cow; - -#[derive(SessionDiagnostic)] -#[diag(codegen_ssa::error)] -pub struct DeserializeRlinkError { - #[subdiagnostic] - pub sub: DeserializeRlinkErrorSub, -} - -#[derive(SessionSubdiagnostic)] -pub enum DeserializeRlinkErrorSub { - #[note(codegen_ssa::wrong_file_type)] - WrongFileType, - - #[note(codegen_ssa::empty_version_number)] - EmptyVersionNumber, - - #[note(codegen_ssa::encoding_version_mismatch)] - EncodingVersionMismatch { version_array: String, rlink_version: String }, - - #[note(codegen_ssa::rustc_version_mismatch)] - RustcVersionMismatch { rustc_version: String, current_version: String }, -} - -impl IntoDiagnosticArg for DeserializeRlinkErrorSub { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Borrowed(match self { - DeserializeRlinkErrorSub::WrongFileType => fluent::codegen_ssa::wrong_file_type, - DeserializeRlinkErrorSub::EmptyVersionNumber => { - fluent::codegen_ssa::empty_version_number - } - DeserializeRlinkErrorSub::EncodingVersionMismatch { version_array, rlink_version } => { - fluent::codegen_ssa::encoding_version_mismatch - } - DeserializeRlinkErrorSub::RustcVersionMismatch { rustc_version, current_version } => { - fluent::codegen_ssa::rustc_version_mismatch - } - })) - } -} diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 99999909d573f..a193d5db6916a 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -18,7 +18,7 @@ extern crate tracing; pub extern crate rustc_plugin_impl as plugin; use rustc_ast as ast; -use rustc_codegen_ssa::{traits::CodegenBackend, CodegenResults}; +use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_data_structures::sync::SeqCst; use rustc_errors::registry::{InvalidErrorCode, Registry}; @@ -60,7 +60,10 @@ pub mod args; pub mod pretty; mod session_diagnostics; -use crate::session_diagnostics::{RlinkNotAFile, RlinkUnableToDeserialize, RlinkUnableToRead}; +use crate::session_diagnostics::{ + RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch, + RLinkWrongFileType, RlinkNotAFile, RlinkUnableToRead, +}; /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -591,7 +594,24 @@ pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Comp let codegen_results = match CodegenResults::deserialize_rlink(rlink_data) { Ok(codegen) => codegen, Err(err) => { - sess.emit_fatal(RlinkUnableToDeserialize { err }); + match err { + CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType), + CodegenErrors::EmptyVersionNumber => { + sess.emit_fatal(RLinkEmptyVersionNumber) + } + CodegenErrors::EncodingVersionMismatch { version_array, rlink_version } => { + sess.emit_fatal(RLinkEncodingVersionMismatch { + version_array, + rlink_version, + }) + } + CodegenErrors::RustcVersionMismatch { rustc_version, current_version } => { + sess.emit_fatal(RLinkRustcVersionMismatch { + rustc_version, + current_version, + }) + } + }; } }; let result = compiler.codegen_backend().link(sess, codegen_results, &outputs); diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs index 86ee51bc97d71..90197ad935e76 100644 --- a/compiler/rustc_driver/src/session_diagnostics.rs +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -1,4 +1,3 @@ -use rustc_codegen_ssa::session_diagnostic::DeserializeRlinkError; use rustc_macros::SessionDiagnostic; #[derive(SessionDiagnostic)] @@ -8,9 +7,25 @@ pub(crate) struct RlinkUnableToRead { } #[derive(SessionDiagnostic)] -#[diag(driver::rlink_unable_to_deserialize)] -pub(crate) struct RlinkUnableToDeserialize { - pub err: DeserializeRlinkError, +#[diag(driver::rlink_wrong_file_type)] +pub(crate) struct RLinkWrongFileType; + +#[derive(SessionDiagnostic)] +#[diag(driver::rlink_empty_version_number)] +pub(crate) struct RLinkEmptyVersionNumber; + +#[derive(SessionDiagnostic)] +#[diag(driver::rlink_encoding_version_mismatch)] +pub(crate) struct RLinkEncodingVersionMismatch { + pub version_array: String, + pub rlink_version: String, +} + +#[derive(SessionDiagnostic)] +#[diag(driver::rlink_rustc_version_mismatch)] +pub(crate) struct RLinkRustcVersionMismatch { + pub rustc_version: String, + pub current_version: String, } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl deleted file mode 100644 index f93ac354773a3..0000000000000 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ /dev/null @@ -1,9 +0,0 @@ -codegen_ssa_error = Error while deserializing rlink file - -codegen_ssa_wrong_file_type = The input does not look like a .rlink file - -codegen_ssa_empty_version_number = The input does not contain version number - -codegen_ssa_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}` - -codegen_ssa_rustc_version_mismatch = .rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}` diff --git a/compiler/rustc_error_messages/locales/en-US/driver.ftl b/compiler/rustc_error_messages/locales/en-US/driver.ftl index 0a2f0e8f883e4..73f084cf3290b 100644 --- a/compiler/rustc_error_messages/locales/en-US/driver.ftl +++ b/compiler/rustc_error_messages/locales/en-US/driver.ftl @@ -1,5 +1,11 @@ driver_rlink_unable_to_read = failed to read rlink file: `{$err}` -driver_rlink_unable_to_deserialize = could not deserialize .rlink file: `{$error_message}` +driver_rlink_wrong_file_type = The input does not look like a .rlink file + +driver_rlink_empty_version_number = The input does not contain version number + +driver_rlink_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}` + +driver_rlink_rustc_version_mismatch = .rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}` driver_rlink_no_a_file = rlink must be a file diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index b4fd883d84578..2ea07ca1a487a 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -35,7 +35,6 @@ fluent_messages! { ast_passes => "../locales/en-US/ast_passes.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", - codegen_ssa => "../locales/en-US/codegen_ssa.ftl", const_eval => "../locales/en-US/const_eval.ftl", driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", From d0401f7f475a2cad5c81114ff916b766b3cbd9c6 Mon Sep 17 00:00:00 2001 From: Adrian Tombu Date: Thu, 25 Aug 2022 19:04:00 +0200 Subject: [PATCH 47/49] Code cleaning --- compiler/rustc_codegen_ssa/src/lib.rs | 12 ++++++------ compiler/rustc_driver/src/session_diagnostics.rs | 6 +++--- compiler/rustc_macros/src/lib.rs | 1 - 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index d6fa1a15373b5..0faf51b062b4c 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -168,11 +168,11 @@ pub struct CodegenResults { pub crate_info: CrateInfo, } -pub enum CodegenErrors { +pub enum CodegenErrors<'a> { WrongFileType, EmptyVersionNumber, - EncodingVersionMismatch { version_array: String, rlink_version: String }, - RustcVersionMismatch { rustc_version: String, current_version: String }, + EncodingVersionMismatch { version_array: String, rlink_version: u32 }, + RustcVersionMismatch { rustc_version: String, current_version: &'a str }, } pub fn provide(providers: &mut Providers) { @@ -219,7 +219,7 @@ impl CodegenResults { encoder.finish() } - pub fn deserialize_rlink(data: Vec) -> Result { + pub fn deserialize_rlink<'a>(data: Vec) -> Result> { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { @@ -235,7 +235,7 @@ impl CodegenResults { if u32::from_be_bytes(version_array) != RLINK_VERSION { return Err(CodegenErrors::EncodingVersionMismatch { version_array: String::from_utf8_lossy(&version_array).to_string(), - rlink_version: RLINK_VERSION.to_string(), + rlink_version: RLINK_VERSION, }); } @@ -245,7 +245,7 @@ impl CodegenResults { if rustc_version != current_version { return Err(CodegenErrors::RustcVersionMismatch { rustc_version: rustc_version.to_string(), - current_version: current_version.to_string(), + current_version, }); } diff --git a/compiler/rustc_driver/src/session_diagnostics.rs b/compiler/rustc_driver/src/session_diagnostics.rs index 90197ad935e76..fe64d0fca9b20 100644 --- a/compiler/rustc_driver/src/session_diagnostics.rs +++ b/compiler/rustc_driver/src/session_diagnostics.rs @@ -18,14 +18,14 @@ pub(crate) struct RLinkEmptyVersionNumber; #[diag(driver::rlink_encoding_version_mismatch)] pub(crate) struct RLinkEncodingVersionMismatch { pub version_array: String, - pub rlink_version: String, + pub rlink_version: u32, } #[derive(SessionDiagnostic)] #[diag(driver::rlink_rustc_version_mismatch)] -pub(crate) struct RLinkRustcVersionMismatch { +pub(crate) struct RLinkRustcVersionMismatch<'a> { pub rustc_version: String, - pub current_version: String, + pub current_version: &'a str, } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index bcf406bcb9572..87d7ab6ed517b 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -163,7 +163,6 @@ decl_derive!( decl_derive!( [SessionSubdiagnostic, attributes( // struct/variant attributes - diag, label, help, note, From 622217da59ae7b4d1d5128255c9517aeb2174ea6 Mon Sep 17 00:00:00 2001 From: AndyJado <101876416+AndyJado@users.noreply.github.com> Date: Fri, 26 Aug 2022 10:32:59 +0800 Subject: [PATCH 48/49] diag-mig --- .../src/diagnostics/region_errors.rs | 93 ++++++-------- compiler/rustc_borrowck/src/lib.rs | 18 +-- .../src/region_infer/opaque_types.rs | 17 +-- .../rustc_borrowck/src/session_diagnostics.rs | 117 +++++++++++++++++- .../locales/en-US/borrowck.ftl | 42 +++++++ 5 files changed, 211 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 0dce5be953e1a..00fdf331ca60c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! Error reporting machinery for lifetime errors. use rustc_data_structures::fx::FxHashSet; @@ -23,7 +25,10 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use crate::borrowck_errors; -use crate::session_diagnostics::GenericDoesNotLiveLongEnough; +use crate::session_diagnostics::{ + FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifetimeOutliveErr, + LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote, +}; use super::{OutlivesSuggestionBuilder, RegionName}; use crate::region_infer::BlameConstraint; @@ -488,12 +493,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; - let mut diag = self - .infcx - .tcx - .sess - .struct_span_err(*span, "captured variable cannot escape `FnMut` closure body"); - let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; if let ty::Opaque(def_id, _) = *output_ty.kind() { output_ty = self.infcx.tcx.type_of(def_id) @@ -501,19 +500,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report_fnmut_error: output_ty={:?}", output_ty); - let message = match output_ty.kind() { - ty::Closure(_, _) => { - "returns a closure that contains a reference to a captured variable, which then \ - escapes the closure body" - } - ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => { - "returns an `async` block that contains a reference to a captured variable, which then \ - escapes the closure body" - } - _ => "returns a reference to a captured variable which escapes the closure body", + let err = FnMutError { + span: *span, + ty_err: match output_ty.kind() { + ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span }, + ty::Adt(def, _) + if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => + { + FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } + } + _ => FnMutReturnTypeErr::ReturnRef { span: *span }, + }, }; - diag.span_label(*span, message); + let mut diag = self.infcx.tcx.sess.create_err(err); if let ReturnConstraint::ClosureUpvar(upvar_field) = kind { let def_id = match self.regioncx.universal_regions().defining_ty { @@ -532,20 +532,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap(); let upvar_def_span = self.infcx.tcx.hir().span(def_hir); let upvar_span = upvars_map.get(&def_hir).unwrap().span; - diag.span_label(upvar_def_span, "variable defined here"); - diag.span_label(upvar_span, "variable captured here"); + diag.subdiagnostic(VarHereDenote::Defined { span: upvar_def_span }); + diag.subdiagnostic(VarHereDenote::Captured { span: upvar_span }); } } if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() { - diag.span_label(fr_span, "inferred to be a `FnMut` closure"); + diag.subdiagnostic(VarHereDenote::FnMutInferred { span: fr_span }); } - diag.note( - "`FnMut` closures only have access to their captured variables while they are \ - executing...", - ); - diag.note("...therefore, they cannot allow references to captured variables to escape"); self.suggest_move_on_borrowing_closure(&mut diag); diag @@ -681,39 +676,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .. } = errci; - let mut diag = - self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); - let (_, mir_def_name) = self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id()); + let err = LifetimeOutliveErr { span: *span }; + let mut diag = self.infcx.tcx.sess.create_err(err); + let fr_name = self.give_region_a_name(*fr).unwrap(); fr_name.highlight_region_name(&mut diag); let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap(); outlived_fr_name.highlight_region_name(&mut diag); - match (category, outlived_fr_is_local, fr_is_local) { - (ConstraintCategory::Return(_), true, _) => { - diag.span_label( - *span, - format!( - "{mir_def_name} was supposed to return data with lifetime `{outlived_fr_name}` but it is returning \ - data with lifetime `{fr_name}`", - ), - ); - } - _ => { - diag.span_label( - *span, - format!( - "{}requires that `{}` must outlive `{}`", - category.description(), - fr_name, - outlived_fr_name, - ), - ); - } - } + let err_category = match (category, outlived_fr_is_local, fr_is_local) { + (ConstraintCategory::Return(_), true, _) => LifetimeReturnCategoryErr::WrongReturn { + span: *span, + mir_def_name, + outlived_fr_name, + fr_name: &fr_name, + }, + _ => LifetimeReturnCategoryErr::ShortReturn { + span: *span, + category_desc: category.description(), + free_region_name: &fr_name, + outlived_fr_name, + }, + }; + + diag.subdiagnostic(err_category); self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr); @@ -862,7 +851,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ident.span, "calling this method introduces the `impl`'s 'static` requirement", ); - err.span_note(multi_span, "the used `impl` has a `'static` requirement"); + err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span }); err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement", diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4ad9a970bc1be..0f8afb038f455 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -18,7 +18,7 @@ extern crate tracing; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; @@ -50,6 +50,8 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveE use rustc_mir_dataflow::Analysis; use rustc_mir_dataflow::MoveDataParamEnv; +use crate::session_diagnostics::VarNeedNotMut; + use self::diagnostics::{AccessKind, RegionName}; use self::location::LocationTable; use self::prefixes::PrefixSet; @@ -424,17 +426,9 @@ fn do_mir_borrowck<'a, 'tcx>( continue; } - tcx.struct_span_lint_hir(UNUSED_MUT, lint_root, span, |lint| { - let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); - lint.build("variable does not need to be mutable") - .span_suggestion_short( - mut_span, - "remove this `mut`", - "", - Applicability::MachineApplicable, - ) - .emit(); - }) + let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); + + tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span }) } let tainted_by_errors = mbcx.emit_errors(); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index d6712b6a4799c..127cb4e408372 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -16,6 +16,8 @@ use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::TraitEngineExt as _; +use crate::session_diagnostics::ConstNotUsedTraitAlias; + use super::RegionInferenceContext; impl<'tcx> RegionInferenceContext<'tcx> { @@ -639,17 +641,10 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { Some(GenericArgKind::Const(c1)) => c1, Some(u) => panic!("const mapped to unexpected kind: {:?}", u), None => { - self.tcx - .sess - .struct_span_err( - self.span, - &format!( - "const parameter `{}` is part of concrete type but not \ - used in parameter list for the `impl Trait` type alias", - ct - ), - ) - .emit(); + self.tcx.sess.emit_err(ConstNotUsedTraitAlias { + ct: ct.to_string(), + span: self.span, + }); self.tcx().const_error(ct.ty()) } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 8c9676e4bfa85..5d750c6ca8c7b 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -1,7 +1,10 @@ -use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_errors::{IntoDiagnosticArg, MultiSpan}; +use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::Span; +use crate::diagnostics::RegionName; + #[derive(SessionDiagnostic)] #[diag(borrowck::move_unsized, code = "E0161")] pub(crate) struct MoveUnsized<'tcx> { @@ -42,3 +45,115 @@ pub(crate) struct GenericDoesNotLiveLongEnough { #[primary_span] pub span: Span, } + +#[derive(LintDiagnostic)] +#[diag(borrowck::var_does_not_need_mut)] +pub(crate) struct VarNeedNotMut { + #[suggestion_short(applicability = "machine-applicable", code = "")] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::const_not_used_in_type_alias)] +pub(crate) struct ConstNotUsedTraitAlias { + pub ct: String, + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::var_cannot_escape_closure)] +#[note] +#[note(borrowck::cannot_escape)] +pub(crate) struct FnMutError { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub ty_err: FnMutReturnTypeErr, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum VarHereDenote { + #[label(borrowck::var_here_captured)] + Captured { + #[primary_span] + span: Span, + }, + #[label(borrowck::var_here_defined)] + Defined { + #[primary_span] + span: Span, + }, + #[label(borrowck::closure_inferred_mut)] + FnMutInferred { + #[primary_span] + span: Span, + }, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum FnMutReturnTypeErr { + #[label(borrowck::returned_closure_escaped)] + ReturnClosure { + #[primary_span] + span: Span, + }, + #[label(borrowck::returned_async_block_escaped)] + ReturnAsyncBlock { + #[primary_span] + span: Span, + }, + #[label(borrowck::returned_ref_escaped)] + ReturnRef { + #[primary_span] + span: Span, + }, +} + +#[derive(SessionDiagnostic)] +#[diag(borrowck::lifetime_constraints_error)] +pub(crate) struct LifetimeOutliveErr { + #[primary_span] + pub span: Span, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum LifetimeReturnCategoryErr<'a> { + #[label(borrowck::returned_lifetime_wrong)] + WrongReturn { + #[primary_span] + span: Span, + mir_def_name: &'a str, + outlived_fr_name: RegionName, + fr_name: &'a RegionName, + }, + #[label(borrowck::returned_lifetime_short)] + ShortReturn { + #[primary_span] + span: Span, + category_desc: &'static str, + free_region_name: &'a RegionName, + outlived_fr_name: RegionName, + }, +} + +impl IntoDiagnosticArg for &RegionName { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + format!("{}", self).into_diagnostic_arg() + } +} + +impl IntoDiagnosticArg for RegionName { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + format!("{}", self).into_diagnostic_arg() + } +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum RequireStaticErr { + #[note(borrowck::used_impl_require_static)] + UsedImpl { + #[primary_span] + multi_span: MultiSpan, + }, +} diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index a96fe7c8a05d5..67f2156f32e50 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -16,3 +16,45 @@ borrowck_higher_ranked_subtype_error = borrowck_generic_does_not_live_long_enough = `{$kind}` does not live long enough + +borrowck_move_borrowed = + cannot move out of `{$desc}` beacause it is borrowed + +borrowck_var_does_not_need_mut = + variable does not need to be mutable + .suggestion = remove this `mut` + +borrowck_const_not_used_in_type_alias = + const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias + +borrowck_var_cannot_escape_closure = + captured variable cannot escape `FnMut` closure body + .note = `FnMut` closures only have access to their captured variables while they are executing... + .cannot_escape = ...therefore, they cannot allow references to captured variables to escape + +borrowck_var_here_defined = variable defined here + +borrowck_var_here_captured = variable captured here + +borrowck_closure_inferred_mut = inferred to be a `FnMut` closure + +borrowck_returned_closure_escaped = + returns a closure that contains a reference to a captured variable, which then escapes the closure body + +borrowck_returned_async_block_escaped = + returns an `async` block that contains a reference to a captured variable, which then escapes the closure body + +borrowck_returned_ref_escaped = + returns a reference to a captured variable which escapes the closure body + +borrowck_lifetime_constraints_error = + lifetime may not live long enough + +borrowck_returned_lifetime_wrong = + {$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}` + +borrowck_returned_lifetime_short = + {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}` + +borrowck_used_impl_require_static = + the used `impl` has a `'static` requirement From 01c1616b2568a712dfa3e4dc6af233f5152ff362 Mon Sep 17 00:00:00 2001 From: Peter Medus <16763503+Facel3ss1@users.noreply.github.com> Date: Fri, 19 Aug 2022 00:04:31 +0100 Subject: [PATCH 49/49] Migrate rustc_ty_utils to use SessionDiagnostic --- Cargo.lock | 1 + .../locales/en-US/ty_utils.ftl | 47 +++++ compiler/rustc_error_messages/src/lib.rs | 1 + compiler/rustc_ty_utils/Cargo.toml | 1 + compiler/rustc_ty_utils/src/consts.rs | 173 +++++++++--------- compiler/rustc_ty_utils/src/errors.rs | 69 +++++++ compiler/rustc_ty_utils/src/lib.rs | 3 + compiler/rustc_ty_utils/src/needs_drop.rs | 7 +- 8 files changed, 208 insertions(+), 94 deletions(-) create mode 100644 compiler/rustc_error_messages/locales/en-US/ty_utils.ftl create mode 100644 compiler/rustc_ty_utils/src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index 9464c87fc728b..790178668cee1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4601,6 +4601,7 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_infer", + "rustc_macros", "rustc_middle", "rustc_session", "rustc_span", diff --git a/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl b/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl new file mode 100644 index 0000000000000..1040ee1c97d81 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl @@ -0,0 +1,47 @@ +ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop + +ty_utils_generic_constant_too_complex = overly complex generic constant + .help = consider moving this anonymous constant into a `const` function + .maybe_supported = this operation may be supported in the future + +ty_utils_borrow_not_supported = borrowing is not supported in generic constants + +ty_utils_address_and_deref_not_supported = dereferencing or taking the address is not supported in generic constants + +ty_utils_array_not_supported = array construction is not supported in generic constants + +ty_utils_block_not_supported = blocks are not supported in generic constant + +ty_utils_never_to_any_not_supported = converting nevers to any is not supported in generic constant + +ty_utils_tuple_not_supported = tuple construction is not supported in generic constants + +ty_utils_index_not_supported = indexing is not supported in generic constant + +ty_utils_field_not_supported = field access is not supported in generic constant + +ty_utils_const_block_not_supported = const blocks are not supported in generic constant + +ty_utils_adt_not_supported = struct/enum construction is not supported in generic constants + +ty_utils_pointer_not_supported = pointer casts are not allowed in generic constants + +ty_utils_yield_not_supported = generator control flow is not allowed in generic constants + +ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants + +ty_utils_box_not_supported = allocations are not allowed in generic constants + +ty_utils_binary_not_supported = unsupported binary operation in generic constants + +ty_utils_logical_op_not_supported = unsupported operation in generic constants, short-circuiting operations would imply control flow + +ty_utils_assign_not_supported = assignment is not supported in generic constants + +ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants + +ty_utils_control_flow_not_supported = control flow is not supported in generic constants + +ty_utils_inline_asm_not_supported = assembly is not supported in generic constants + +ty_utils_operation_not_supported = unsupported operation in generic constant diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 2d001d445be02..28dca0ba00efd 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -44,6 +44,7 @@ fluent_messages! { plugin_impl => "../locales/en-US/plugin_impl.ftl", privacy => "../locales/en-US/privacy.ftl", save_analysis => "../locales/en-US/save_analysis.ftl", + ty_utils => "../locales/en-US/ty_utils.ftl", typeck => "../locales/en-US/typeck.ftl", } diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index caad2ed4274f8..52fbd3ae04773 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -10,6 +10,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } rustc_infer = { path = "../rustc_infer" } +rustc_macros = { path = "../rustc_macros" } rustc_span = { path = "../rustc_span" } rustc_session = { path = "../rustc_session" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index e8ce8e6f23ec9..16c4d429129a9 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -11,6 +11,8 @@ use rustc_target::abi::VariantIdx; use std::iter; +use crate::errors::{GenericConstantTooComplex, GenericConstantTooComplexSub}; + /// Destructures array, ADT or tuple constants into the constants /// of their fields. pub(crate) fn destructure_const<'tcx>( @@ -93,26 +95,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { self.body.exprs[self.body_id].span } - fn error(&mut self, span: Span, msg: &str) -> Result { - let reported = self - .tcx - .sess - .struct_span_err(self.root_span(), "overly complex generic constant") - .span_label(span, msg) - .help("consider moving this anonymous constant into a `const` function") - .emit(); + fn error(&mut self, sub: GenericConstantTooComplexSub) -> Result { + let reported = self.tcx.sess.emit_err(GenericConstantTooComplex { + span: self.root_span(), + maybe_supported: None, + sub, + }); Err(reported) } - fn maybe_supported_error(&mut self, span: Span, msg: &str) -> Result { - let reported = self - .tcx - .sess - .struct_span_err(self.root_span(), "overly complex generic constant") - .span_label(span, msg) - .help("consider moving this anonymous constant into a `const` function") - .note("this operation may be supported in the future") - .emit(); + + fn maybe_supported_error( + &mut self, + sub: GenericConstantTooComplexSub, + ) -> Result { + let reported = self.tcx.sess.emit_err(GenericConstantTooComplex { + span: self.root_span(), + maybe_supported: Some(()), + sub, + }); Err(reported) } @@ -243,22 +244,23 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { &ExprKind::Scope { value, .. } => self.recurse_build(value)?, &ExprKind::PlaceTypeAscription { source, .. } | &ExprKind::ValueTypeAscription { source, .. } => self.recurse_build(source)?, - &ExprKind::Literal { lit, neg} => { + &ExprKind::Literal { lit, neg } => { let sp = node.span; - let constant = - match self.tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) { - Ok(c) => c, - Err(LitToConstError::Reported) => { - self.tcx.const_error(node.ty) - } - Err(LitToConstError::TypeError) => { - bug!("encountered type error in lit_to_const") - } - }; + let constant = match self.tcx.at(sp).lit_to_const(LitToConstInput { + lit: &lit.node, + ty: node.ty, + neg, + }) { + Ok(c) => c, + Err(LitToConstError::Reported) => self.tcx.const_error(node.ty), + Err(LitToConstError::TypeError) => { + bug!("encountered type error in lit_to_const") + } + }; self.nodes.push(Node::Leaf(constant)) } - &ExprKind::NonHirLiteral { lit , user_ty: _} => { + &ExprKind::NonHirLiteral { lit, user_ty: _ } => { let val = ty::ValTree::from_scalar_int(lit); self.nodes.push(Node::Leaf(ty::Const::from_value(self.tcx, val, node.ty))) } @@ -269,19 +271,17 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { &ExprKind::NamedConst { def_id, substs, user_ty: _ } => { let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs); - let constant = self.tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Unevaluated(uneval), - ty: node.ty, - }); + let constant = self + .tcx + .mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty: node.ty }); self.nodes.push(Node::Leaf(constant)) } - ExprKind::ConstParam {param, ..} => { - let const_param = self.tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Param(*param), - ty: node.ty, - }); + ExprKind::ConstParam { param, .. } => { + let const_param = self + .tcx + .mk_const(ty::ConstS { kind: ty::ConstKind::Param(*param), ty: node.ty }); self.nodes.push(Node::Leaf(const_param)) } @@ -312,13 +312,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { // } // ``` ExprKind::Block { block } => { - if let thir::Block { stmts: box [], expr: Some(e), .. } = &self.body.blocks[*block] { + if let thir::Block { stmts: box [], expr: Some(e), .. } = &self.body.blocks[*block] + { self.recurse_build(*e)? } else { - self.maybe_supported_error( + self.maybe_supported_error(GenericConstantTooComplexSub::BlockNotSupported( node.span, - "blocks are not supported in generic constant", - )? + ))? } } // `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a @@ -332,7 +332,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { let arg = self.recurse_build(source)?; self.nodes.push(Node::Cast(CastKind::As, arg, node.ty)) } - ExprKind::Borrow{ arg, ..} => { + ExprKind::Borrow { arg, .. } => { let arg_node = &self.body.exprs[*arg]; // Skip reborrows for now until we allow Deref/Borrow/AddressOf @@ -341,76 +341,69 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { if let ExprKind::Deref { arg } = arg_node.kind { self.recurse_build(arg)? } else { - self.maybe_supported_error( + self.maybe_supported_error(GenericConstantTooComplexSub::BorrowNotSupported( node.span, - "borrowing is not supported in generic constants", - )? + ))? } } // FIXME(generic_const_exprs): We may want to support these. - ExprKind::AddressOf { .. } | ExprKind::Deref {..}=> self.maybe_supported_error( - node.span, - "dereferencing or taking the address is not supported in generic constants", + ExprKind::AddressOf { .. } | ExprKind::Deref { .. } => self.maybe_supported_error( + GenericConstantTooComplexSub::AddressAndDerefNotSupported(node.span), )?, - ExprKind::Repeat { .. } | ExprKind::Array { .. } => self.maybe_supported_error( - node.span, - "array construction is not supported in generic constants", + ExprKind::Repeat { .. } | ExprKind::Array { .. } => self.maybe_supported_error( + GenericConstantTooComplexSub::ArrayNotSupported(node.span), )?, ExprKind::NeverToAny { .. } => self.maybe_supported_error( - node.span, - "converting nevers to any is not supported in generic constant", + GenericConstantTooComplexSub::NeverToAnyNotSupported(node.span), )?, ExprKind::Tuple { .. } => self.maybe_supported_error( - node.span, - "tuple construction is not supported in generic constants", + GenericConstantTooComplexSub::TupleNotSupported(node.span), )?, ExprKind::Index { .. } => self.maybe_supported_error( - node.span, - "indexing is not supported in generic constant", + GenericConstantTooComplexSub::IndexNotSupported(node.span), )?, ExprKind::Field { .. } => self.maybe_supported_error( - node.span, - "field access is not supported in generic constant", + GenericConstantTooComplexSub::FieldNotSupported(node.span), )?, ExprKind::ConstBlock { .. } => self.maybe_supported_error( - node.span, - "const blocks are not supported in generic constant", - )?, - ExprKind::Adt(_) => self.maybe_supported_error( - node.span, - "struct/enum construction is not supported in generic constants", + GenericConstantTooComplexSub::ConstBlockNotSupported(node.span), )?, + ExprKind::Adt(_) => self + .maybe_supported_error(GenericConstantTooComplexSub::AdtNotSupported(node.span))?, // dont know if this is correct - ExprKind::Pointer { .. } => - self.error(node.span, "pointer casts are not allowed in generic constants")?, - ExprKind::Yield { .. } => - self.error(node.span, "generator control flow is not allowed in generic constants")?, - ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Loop { .. } => self - .error( - node.span, - "loops and loop control flow are not supported in generic constants", - )?, - ExprKind::Box { .. } => - self.error(node.span, "allocations are not allowed in generic constants")?, + ExprKind::Pointer { .. } => { + self.error(GenericConstantTooComplexSub::PointerNotSupported(node.span))? + } + ExprKind::Yield { .. } => { + self.error(GenericConstantTooComplexSub::YieldNotSupported(node.span))? + } + ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Loop { .. } => { + self.error(GenericConstantTooComplexSub::LoopNotSupported(node.span))? + } + ExprKind::Box { .. } => { + self.error(GenericConstantTooComplexSub::BoxNotSupported(node.span))? + } ExprKind::Unary { .. } => unreachable!(), // we handle valid unary/binary ops above - ExprKind::Binary { .. } => - self.error(node.span, "unsupported binary operation in generic constants")?, - ExprKind::LogicalOp { .. } => - self.error(node.span, "unsupported operation in generic constants, short-circuiting operations would imply control flow")?, + ExprKind::Binary { .. } => { + self.error(GenericConstantTooComplexSub::BinaryNotSupported(node.span))? + } + ExprKind::LogicalOp { .. } => { + self.error(GenericConstantTooComplexSub::LogicalOpNotSupported(node.span))? + } ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => { - self.error(node.span, "assignment is not supported in generic constants")? + self.error(GenericConstantTooComplexSub::AssignNotSupported(node.span))? + } + ExprKind::Closure { .. } | ExprKind::Return { .. } => { + self.error(GenericConstantTooComplexSub::ClosureAndReturnNotSupported(node.span))? } - ExprKind::Closure { .. } | ExprKind::Return { .. } => self.error( - node.span, - "closures and function keywords are not supported in generic constants", - )?, // let expressions imply control flow - ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } => - self.error(node.span, "control flow is not supported in generic constants")?, + ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } => { + self.error(GenericConstantTooComplexSub::ControlFlowNotSupported(node.span))? + } ExprKind::InlineAsm { .. } => { - self.error(node.span, "assembly is not supported in generic constants")? + self.error(GenericConstantTooComplexSub::InlineAsmNotSupported(node.span))? } // we dont permit let stmts so `VarRef` and `UpvarRef` cant happen @@ -418,7 +411,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { | ExprKind::UpvarRef { .. } | ExprKind::StaticRef { .. } | ExprKind::ThreadLocalRef(_) => { - self.error(node.span, "unsupported operation in generic constant")? + self.error(GenericConstantTooComplexSub::OperationNotSupported(node.span))? } }) } diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs new file mode 100644 index 0000000000000..3a8ef96c991f2 --- /dev/null +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -0,0 +1,69 @@ +//! Errors emitted by ty_utils + +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_middle::ty::Ty; +use rustc_span::Span; + +#[derive(SessionDiagnostic)] +#[diag(ty_utils::needs_drop_overflow)] +pub struct NeedsDropOverflow<'tcx> { + pub query_ty: Ty<'tcx>, +} + +#[derive(SessionDiagnostic)] +#[diag(ty_utils::generic_constant_too_complex)] +#[help] +pub struct GenericConstantTooComplex { + #[primary_span] + pub span: Span, + #[note(ty_utils::maybe_supported)] + pub maybe_supported: Option<()>, + #[subdiagnostic] + pub sub: GenericConstantTooComplexSub, +} + +#[derive(SessionSubdiagnostic)] +pub enum GenericConstantTooComplexSub { + #[label(ty_utils::borrow_not_supported)] + BorrowNotSupported(#[primary_span] Span), + #[label(ty_utils::address_and_deref_not_supported)] + AddressAndDerefNotSupported(#[primary_span] Span), + #[label(ty_utils::array_not_supported)] + ArrayNotSupported(#[primary_span] Span), + #[label(ty_utils::block_not_supported)] + BlockNotSupported(#[primary_span] Span), + #[label(ty_utils::never_to_any_not_supported)] + NeverToAnyNotSupported(#[primary_span] Span), + #[label(ty_utils::tuple_not_supported)] + TupleNotSupported(#[primary_span] Span), + #[label(ty_utils::index_not_supported)] + IndexNotSupported(#[primary_span] Span), + #[label(ty_utils::field_not_supported)] + FieldNotSupported(#[primary_span] Span), + #[label(ty_utils::const_block_not_supported)] + ConstBlockNotSupported(#[primary_span] Span), + #[label(ty_utils::adt_not_supported)] + AdtNotSupported(#[primary_span] Span), + #[label(ty_utils::pointer_not_supported)] + PointerNotSupported(#[primary_span] Span), + #[label(ty_utils::yield_not_supported)] + YieldNotSupported(#[primary_span] Span), + #[label(ty_utils::loop_not_supported)] + LoopNotSupported(#[primary_span] Span), + #[label(ty_utils::box_not_supported)] + BoxNotSupported(#[primary_span] Span), + #[label(ty_utils::binary_not_supported)] + BinaryNotSupported(#[primary_span] Span), + #[label(ty_utils::logical_op_not_supported)] + LogicalOpNotSupported(#[primary_span] Span), + #[label(ty_utils::assign_not_supported)] + AssignNotSupported(#[primary_span] Span), + #[label(ty_utils::closure_and_return_not_supported)] + ClosureAndReturnNotSupported(#[primary_span] Span), + #[label(ty_utils::control_flow_not_supported)] + ControlFlowNotSupported(#[primary_span] Span), + #[label(ty_utils::inline_asm_not_supported)] + InlineAsmNotSupported(#[primary_span] Span), + #[label(ty_utils::operation_not_supported)] + OperationNotSupported(#[primary_span] Span), +} diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 55d8269399403..6931b15b1ba57 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -10,6 +10,8 @@ #![feature(never_type)] #![feature(box_patterns)] #![recursion_limit = "256"] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_middle; @@ -21,6 +23,7 @@ use rustc_middle::ty::query::Providers; mod assoc; mod common_traits; mod consts; +mod errors; mod implied_bounds; pub mod instance; mod needs_drop; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 9ad44d14d6180..ab5a3d8ae4892 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -9,6 +9,8 @@ use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; use rustc_session::Limit; use rustc_span::{sym, DUMMY_SP}; +use crate::errors::NeedsDropOverflow; + type NeedsDropResult = Result; fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { @@ -90,10 +92,7 @@ where if !self.recursion_limit.value_within_limit(level) { // Not having a `Span` isn't great. But there's hopefully some other // recursion limit error as well. - tcx.sess.span_err( - DUMMY_SP, - &format!("overflow while checking whether `{}` requires drop", self.query_ty), - ); + tcx.sess.emit_err(NeedsDropOverflow { query_ty: self.query_ty }); return Some(Err(AlwaysRequiresDrop)); }