convert the optimize attribute to a new parser

This commit is contained in:
Jana Dönszelmann 2025-03-09 23:46:47 +01:00
parent 1bb335244c
commit b64fd13a04
No known key found for this signature in database
13 changed files with 72 additions and 58 deletions

View File

@ -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)>),

View File

@ -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<S: Stage> SingleAttributeParser<S> for OptimizeParser {
const PATH: &[rustc_span::Symbol] = &[sym::optimize];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const TEMPLATE: AttributeTemplate = template!(List: "size|speed|none");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
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))
}
}

View File

@ -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;

View File

@ -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<ConstStabilityIndirectParser>,
Single<DeprecationParser>,
Single<InlineParser>,
Single<OptimizeParser>,
Single<RustcForceInlineParser>,
Single<TransparencyParser>,
// tidy-alphabetical-end

View File

@ -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]`

View File

@ -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
//

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -290,6 +290,7 @@ fn emit_malformed_attribute(
| sym::rustc_confusables
| sym::repr
| sym::deprecated
| sym::optimize
) {
return;
}

View File

@ -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,
});

View File

@ -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() {}

View File

@ -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`.