mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-03 02:40:40 +00:00
convert the optimize
attribute to a new parser
This commit is contained in:
parent
1bb335244c
commit
b64fd13a04
@ -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)>),
|
||||
|
||||
|
40
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Normal file
40
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Normal 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))
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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]`
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -290,6 +290,7 @@ fn emit_malformed_attribute(
|
||||
| sym::rustc_confusables
|
||||
| sym::repr
|
||||
| sym::deprecated
|
||||
| sym::optimize
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -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() {}
|
||||
|
@ -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`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user