From 5ab5f8a24a99cdbb178c886487d4c1971b86a32b Mon Sep 17 00:00:00 2001 From: Jana Dönszelmann Date: Sat, 8 Mar 2025 18:58:05 +0100 Subject: make error codes reflect reality better --- .../rustc_error_codes/src/error_codes/E0534.md | 8 +++++- .../rustc_error_codes/src/error_codes/E0535.md | 9 +++++-- .../rustc_error_codes/src/error_codes/E0539.md | 29 ++++++++++++++++++++-- .../rustc_error_codes/src/error_codes/E0565.md | 7 +++--- .../rustc_error_codes/src/error_codes/E0805.md | 26 +++++++++++++++++++ compiler/rustc_error_codes/src/lib.rs | 1 + 6 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0805.md (limited to 'compiler/rustc_error_codes/src') diff --git a/compiler/rustc_error_codes/src/error_codes/E0534.md b/compiler/rustc_error_codes/src/error_codes/E0534.md index 1ca9411b8d4..023c38c730c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0534.md +++ b/compiler/rustc_error_codes/src/error_codes/E0534.md @@ -1,8 +1,14 @@ +#### Note: this error code is no longer emitted by the compiler + +This is because it was too specific to the `inline` attribute. +Similar diagnostics occur for other attributes too. +The example here will now emit `E0805` + The `inline` attribute was malformed. Erroneous code example: -```compile_fail,E0534 +```compile_fail,E0805 #[inline()] // error: expected one argument pub fn something() {} diff --git a/compiler/rustc_error_codes/src/error_codes/E0535.md b/compiler/rustc_error_codes/src/error_codes/E0535.md index 0cf3118b02c..93e2ba53826 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0535.md +++ b/compiler/rustc_error_codes/src/error_codes/E0535.md @@ -1,8 +1,13 @@ -An unknown argument was given to the `inline` attribute. +#### Note: this error code is no longer emitted by the compiler + +This is because it was too specific to the `inline` attribute. +Similar diagnostics occur for other attributes too. +The example here will now emit `E0539` + Erroneous code example: -```compile_fail,E0535 +```compile_fail,E0539 #[inline(unknown)] // error: invalid argument pub fn something() {} diff --git a/compiler/rustc_error_codes/src/error_codes/E0539.md b/compiler/rustc_error_codes/src/error_codes/E0539.md index 6b2e23ba2d8..c76b60ac108 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0539.md +++ b/compiler/rustc_error_codes/src/error_codes/E0539.md @@ -24,8 +24,7 @@ struct Stable; const fn stable_fn() {} ``` -Meta items are the key-value pairs inside of an attribute. -To fix these issues you need to give required key-value pairs. +To fix the above example, you can write the following: ``` #![feature(staged_api)] @@ -49,3 +48,29 @@ struct Stable; #[rustc_const_stable(feature = "stable_fn", since = "1.39.0")] // ok! const fn stable_fn() {} ``` + +Several causes of this are, +an attribute may have expected you to give a list but you gave a +`name = value` pair: + +```compile_fail,E0539 +// wrong, should be `#[repr(C)]` +#[repr = "C"] +struct Foo {} +``` + +Or a `name = value` pair, but you gave a list: + +```compile_fail,E0539 +// wrong, should be `note = "reason"` +#[deprecated(since = "1.0.0", note("reason"))] +struct Foo {} +``` + +Or it expected some specific word but you gave an unexpected one: + +```compile_fail,E0539 +// should be `always` or `never` +#[inline(maybe_if_you_feel_like_it)] +fn foo() {} +``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0565.md b/compiler/rustc_error_codes/src/error_codes/E0565.md index d5bba941c1d..34152eb7cfe 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0565.md +++ b/compiler/rustc_error_codes/src/error_codes/E0565.md @@ -9,10 +9,9 @@ struct Repr {} fn main() {} ``` -Literals in attributes are new and largely unsupported in built-in attributes. -Work to support literals where appropriate is ongoing. Try using an unquoted -name instead: - +Not all attributes support literals in their input, +and in some cases they expect an identifier instead. +That would be the solution in the case of `repr`: ``` #[repr(C)] // ok! struct Repr {} diff --git a/compiler/rustc_error_codes/src/error_codes/E0805.md b/compiler/rustc_error_codes/src/error_codes/E0805.md new file mode 100644 index 00000000000..b1ed3a11d48 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0805.md @@ -0,0 +1,26 @@ +An attribute was given an invalid number of arguments + +Erroneous code example: + +```compile_fail,E0805 +#[inline()] // error! should either have a single argument, or no parentheses +fn foo() {} + +#[inline(always, never)] // error! should have only one argument, not two +fn bar() {} +``` + +To fix this, either give the right number of arguments the attribute needs. +In the case of inline, this could be none at all: + +``` +#[inline] +fn foo() {} +``` + +or only one: + +``` +#[inline(always)] +fn foo() {} +``` diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 2488d870899..6f5e4829802 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -547,6 +547,7 @@ E0801: 0801, E0802: 0802, E0803: 0803, E0804: 0804, +E0805: 0805, ); ) } -- cgit 1.4.1-3-g733a5 From b64fd13a04e03bd260b550430daa6fbdf1fb27c9 Mon Sep 17 00:00:00 2001 From: Jana Dönszelmann Date: Sun, 9 Mar 2025 23:46:47 +0100 Subject: convert the `optimize` attribute to a new parser --- .../rustc_attr_data_structures/src/attributes.rs | 6 ++-- .../src/attributes/codegen_attrs.rs | 40 ++++++++++++++++++++++ compiler/rustc_attr_parsing/src/attributes/mod.rs | 1 + compiler/rustc_attr_parsing/src/context.rs | 2 ++ compiler/rustc_codegen_ssa/messages.ftl | 5 --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 29 ++-------------- compiler/rustc_codegen_ssa/src/errors.rs | 14 -------- .../rustc_error_codes/src/error_codes/E0722.md | 8 ++++- compiler/rustc_error_codes/src/lib.rs | 1 + compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 8 +++-- .../feature-gate-optimize_attribute.rs | 2 +- .../feature-gate-optimize_attribute.stderr | 13 ++++--- 13 files changed, 72 insertions(+), 58 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs (limited to 'compiler/rustc_error_codes/src') diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index d4c43456049..e0b0015f365 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -38,7 +38,8 @@ pub enum InstructionSetAttr { ArmT32, } -#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic, Default)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default, PrintAttribute)] +#[derive(Encodable, Decodable, HashStable_Generic)] pub enum OptimizeAttr { /// No `#[optimize(..)]` attribute #[default] @@ -226,7 +227,8 @@ pub enum AttributeKind { /// Represents `#[rustc_macro_transparency]`. MacroTransparency(Transparency), - + /// Represents `#[optimize(size|speed)]` + Optimize(OptimizeAttr, Span), /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr(ThinVec<(ReprAttr, Span)>), diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs new file mode 100644 index 00000000000..ddcf82cbf7c --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -0,0 +1,40 @@ +use rustc_attr_data_structures::{AttributeKind, OptimizeAttr}; +use rustc_feature::{AttributeTemplate, template}; +use rustc_span::sym; + +use super::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::context::{AcceptContext, Stage}; +use crate::parser::ArgParser; + +pub(crate) struct OptimizeParser; + +impl SingleAttributeParser for OptimizeParser { + const PATH: &[rustc_span::Symbol] = &[sym::optimize]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const TEMPLATE: AttributeTemplate = template!(List: "size|speed|none"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let Some(list) = args.list() else { + cx.expected_list(cx.attr_span); + return None; + }; + + let Some(single) = list.single() else { + cx.expected_single_argument(list.span); + return None; + }; + + let res = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) { + Some(sym::size) => OptimizeAttr::Size, + Some(sym::speed) => OptimizeAttr::Speed, + Some(sym::none) => OptimizeAttr::DoNotOptimize, + _ => { + cx.expected_specific_argument(single.span(), vec!["size", "speed", "none"]); + OptimizeAttr::Default + } + }; + + Some(AttributeKind::Optimize(res, cx.attr_span)) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index fa2a6087506..3bb4c163d32 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -28,6 +28,7 @@ use crate::session_diagnostics::UnusedMultiple; pub(crate) mod allow_unstable; pub(crate) mod cfg; +pub(crate) mod codegen_attrs; pub(crate) mod confusables; pub(crate) mod deprecation; pub(crate) mod inline; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 51c1760da30..18ed98d4a25 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -15,6 +15,7 @@ use rustc_session::Session; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; +use crate::attributes::codegen_attrs::OptimizeParser; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; @@ -107,6 +108,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, // tidy-alphabetical-end diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 5322fe58cf3..e4734b18093 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -48,8 +48,6 @@ codegen_ssa_error_writing_def_file = codegen_ssa_expected_name_value_pair = expected name value pair -codegen_ssa_expected_one_argument = expected one argument - codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified @@ -86,9 +84,6 @@ codegen_ssa_incorrect_cgu_reuse_type = codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. -codegen_ssa_invalid_argument = invalid argument - .help = valid inline arguments are `always` and `never` - codegen_ssa_invalid_instruction_set = invalid instruction set specified codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]` diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 188a9a98ce7..33c457ead30 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -465,33 +465,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.inline = InlineAttr::Never; } - codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::Default, |ia, attr| { - if !attr.has_name(sym::optimize) { - return ia; - } - if attr.is_word() { - tcx.dcx().emit_err(errors::ExpectedOneArgumentOptimize { span: attr.span() }); - return ia; - } - let Some(ref items) = attr.meta_item_list() else { - return OptimizeAttr::Default; - }; - - let [item] = &items[..] else { - tcx.dcx().emit_err(errors::ExpectedOneArgumentOptimize { span: attr.span() }); - return OptimizeAttr::Default; - }; - if item.has_name(sym::size) { - OptimizeAttr::Size - } else if item.has_name(sym::speed) { - OptimizeAttr::Speed - } else if item.has_name(sym::none) { - OptimizeAttr::DoNotOptimize - } else { - tcx.dcx().emit_err(errors::InvalidArgumentOptimize { span: item.span() }); - OptimizeAttr::Default - } - }); + codegen_fn_attrs.optimize = + find_attr!(attrs, AttributeKind::Optimize(i, _) => *i).unwrap_or(OptimizeAttr::Default); // #73631: closures inherit `#[target_feature]` annotations // diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 5387b2a7f81..c60661a1410 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -208,20 +208,6 @@ pub(crate) struct OutOfRangeInteger { pub span: Span, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_expected_one_argument, code = E0722)] -pub(crate) struct ExpectedOneArgumentOptimize { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_invalid_argument, code = E0722)] -pub(crate) struct InvalidArgumentOptimize { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(codegen_ssa_copy_path_buf)] pub(crate) struct CopyPathBuf { diff --git a/compiler/rustc_error_codes/src/error_codes/E0722.md b/compiler/rustc_error_codes/src/error_codes/E0722.md index 570717a92bd..1799458d46c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0722.md +++ b/compiler/rustc_error_codes/src/error_codes/E0722.md @@ -1,8 +1,14 @@ +#### Note: this error code is no longer emitted by the compiler + +This is because it was too specific to the `optimize` attribute. +Similar diagnostics occur for other attributes too. +The example here will now emit `E0539` + The `optimize` attribute was malformed. Erroneous code example: -```compile_fail,E0722 +```compile_fail,E0539 #![feature(optimize_attribute)] #[optimize(something)] // error: invalid argument diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 6f5e4829802..22cc1e894da 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -686,6 +686,7 @@ E0805: 0805, // E0707, // multiple elided lifetimes used in arguments of `async fn` // E0709, // multiple different lifetimes used in arguments of `async fn` // E0721, // `await` keyword +// E0722, // replaced with a generic attribute input check // E0723, // unstable feature in `const` context // E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`. // E0744, // merged into E0728 diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index b3096e46b09..1fbc970e2a7 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -290,6 +290,7 @@ fn emit_malformed_attribute( | sym::rustc_confusables | sym::repr | sym::deprecated + | sym::optimize ) { return; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5ce803aa1f8..98e8b47127b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -128,6 +128,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => { self.check_inline(hir_id, *attr_span, span, kind, target) } + Attribute::Parsed(AttributeKind::Optimize(_, attr_span)) => { + self.check_optimize(hir_id, *attr_span, span, target) + } Attribute::Parsed(AttributeKind::AllowInternalUnstable(syms)) => self .check_allow_internal_unstable( hir_id, @@ -163,7 +166,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_unimplemented(attr.span(), hir_id, target) } [sym::coverage, ..] => self.check_coverage(attr, span, target), - [sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target), [sym::no_sanitize, ..] => { self.check_no_sanitize(attr, span, target) } @@ -525,7 +527,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks that `#[optimize(..)]` is applied to a function/closure/method, /// or to an impl block or module. - fn check_optimize(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { + fn check_optimize(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) { let is_valid = matches!( target, Target::Fn @@ -534,7 +536,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ); if !is_valid { self.dcx().emit_err(errors::OptimizeInvalidTarget { - attr_span: attr.span(), + attr_span, defn_span: span, on_crate: hir_id == CRATE_HIR_ID, }); diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs index 77cc307c9f4..ed5a11270f8 100644 --- a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs +++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs @@ -11,5 +11,5 @@ fn none() {} #[optimize(banana)] //~^ ERROR the `#[optimize]` attribute is an experimental feature -//~| ERROR E0722 +//~| ERROR malformed `optimize` attribute input [E0539] fn not_known() {} diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr index 4e6e4ac2703..e7e62b4f989 100644 --- a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr +++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr @@ -38,13 +38,16 @@ LL | #[optimize(banana)] = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0722]: invalid argument - --> $DIR/feature-gate-optimize_attribute.rs:12:12 +error[E0539]: malformed `optimize` attribute input + --> $DIR/feature-gate-optimize_attribute.rs:12:1 | LL | #[optimize(banana)] - | ^^^^^^ + | ^^^^^^^^^^^------^^ + | | | + | | valid arguments are `size`, `speed` or `none` + | help: must be of the form: `#[optimize(size|speed|none)]` error: aborting due to 5 previous errors -Some errors have detailed explanations: E0658, E0722. -For more information about an error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0539, E0658. +For more information about an error, try `rustc --explain E0539`. -- cgit 1.4.1-3-g733a5