Skip to content

Commit dfe3c6d

Browse files
committed
convert the optimize attribute to a new parser
1 parent d275cc3 commit dfe3c6d

File tree

13 files changed

+72
-58
lines changed

13 files changed

+72
-58
lines changed

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ pub enum InstructionSetAttr {
3838
ArmT32,
3939
}
4040

41-
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic, Default)]
41+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default, PrintAttribute)]
42+
#[derive(Encodable, Decodable, HashStable_Generic)]
4243
pub enum OptimizeAttr {
4344
/// No `#[optimize(..)]` attribute
4445
#[default]
@@ -199,7 +200,8 @@ pub enum AttributeKind {
199200
/// Represents `#[rustc_macro_transparency]`.
200201
Inline(InlineAttr, Span),
201202
MacroTransparency(Transparency),
202-
203+
/// Represents `#[optimize(size|speed)]`
204+
Optimize(OptimizeAttr, Span),
203205
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
204206
Repr(ThinVec<(ReprAttr, Span)>),
205207
/// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use rustc_attr_data_structures::{AttributeKind, OptimizeAttr};
2+
use rustc_feature::{AttributeTemplate, template};
3+
use rustc_span::sym;
4+
5+
use super::{AttributeOrder, OnDuplicate, SingleAttributeParser};
6+
use crate::context::{AcceptContext, Stage};
7+
use crate::parser::ArgParser;
8+
9+
pub(crate) struct OptimizeParser;
10+
11+
impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
12+
const PATH: &[rustc_span::Symbol] = &[sym::optimize];
13+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
14+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
15+
const TEMPLATE: AttributeTemplate = template!(List: "size|speed|none");
16+
17+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
18+
let Some(list) = args.list() else {
19+
cx.expected_list(cx.attr_span);
20+
return None;
21+
};
22+
23+
let Some(single) = list.single() else {
24+
cx.expected_single_argument(list.span);
25+
return None;
26+
};
27+
28+
let res = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) {
29+
Some(sym::size) => OptimizeAttr::Size,
30+
Some(sym::speed) => OptimizeAttr::Speed,
31+
Some(sym::none) => OptimizeAttr::DoNotOptimize,
32+
_ => {
33+
cx.expected_specific_argument(single.span(), vec!["size", "speed", "none"]);
34+
OptimizeAttr::Default
35+
}
36+
};
37+
38+
Some(AttributeKind::Optimize(res, cx.attr_span))
39+
}
40+
}

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use crate::session_diagnostics::UnusedMultiple;
2828

2929
pub(crate) mod allow_unstable;
3030
pub(crate) mod cfg;
31+
pub(crate) mod codegen_attrs;
3132
pub(crate) mod confusables;
3233
pub(crate) mod deprecation;
3334
pub(crate) mod inline;

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_session::Session;
1515
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
1616

1717
use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
18+
use crate::attributes::codegen_attrs::OptimizeParser;
1819
use crate::attributes::confusables::ConfusablesParser;
1920
use crate::attributes::deprecation::DeprecationParser;
2021
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
@@ -105,6 +106,7 @@ attribute_groups!(
105106
Single<ConstStabilityIndirectParser>,
106107
Single<DeprecationParser>,
107108
Single<InlineParser>,
109+
Single<OptimizeParser>,
108110
Single<RustcForceInlineParser>,
109111
Single<TransparencyParser>,
110112
// tidy-alphabetical-end

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ codegen_ssa_error_writing_def_file =
4848
4949
codegen_ssa_expected_name_value_pair = expected name value pair
5050
51-
codegen_ssa_expected_one_argument = expected one argument
52-
5351
codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
5452
5553
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 =
8684
8785
codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient.
8886
89-
codegen_ssa_invalid_argument = invalid argument
90-
.help = valid inline arguments are `always` and `never`
91-
9287
codegen_ssa_invalid_instruction_set = invalid instruction set specified
9388
9489
codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]`

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -465,33 +465,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
465465
codegen_fn_attrs.inline = InlineAttr::Never;
466466
}
467467

468-
codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::Default, |ia, attr| {
469-
if !attr.has_name(sym::optimize) {
470-
return ia;
471-
}
472-
if attr.is_word() {
473-
tcx.dcx().emit_err(errors::ExpectedOneArgumentOptimize { span: attr.span() });
474-
return ia;
475-
}
476-
let Some(ref items) = attr.meta_item_list() else {
477-
return OptimizeAttr::Default;
478-
};
479-
480-
let [item] = &items[..] else {
481-
tcx.dcx().emit_err(errors::ExpectedOneArgumentOptimize { span: attr.span() });
482-
return OptimizeAttr::Default;
483-
};
484-
if item.has_name(sym::size) {
485-
OptimizeAttr::Size
486-
} else if item.has_name(sym::speed) {
487-
OptimizeAttr::Speed
488-
} else if item.has_name(sym::none) {
489-
OptimizeAttr::DoNotOptimize
490-
} else {
491-
tcx.dcx().emit_err(errors::InvalidArgumentOptimize { span: item.span() });
492-
OptimizeAttr::Default
493-
}
494-
});
468+
codegen_fn_attrs.optimize =
469+
find_attr!(attrs, AttributeKind::Optimize(i, _) => *i).unwrap_or(OptimizeAttr::Default);
495470

496471
// #73631: closures inherit `#[target_feature]` annotations
497472
//

compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,6 @@ pub(crate) struct OutOfRangeInteger {
208208
pub span: Span,
209209
}
210210

211-
#[derive(Diagnostic)]
212-
#[diag(codegen_ssa_expected_one_argument, code = E0722)]
213-
pub(crate) struct ExpectedOneArgumentOptimize {
214-
#[primary_span]
215-
pub span: Span,
216-
}
217-
218-
#[derive(Diagnostic)]
219-
#[diag(codegen_ssa_invalid_argument, code = E0722)]
220-
pub(crate) struct InvalidArgumentOptimize {
221-
#[primary_span]
222-
pub span: Span,
223-
}
224-
225211
#[derive(Diagnostic)]
226212
#[diag(codegen_ssa_copy_path_buf)]
227213
pub(crate) struct CopyPathBuf {

compiler/rustc_error_codes/src/error_codes/E0722.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
#### Note: this error code is no longer emitted by the compiler
2+
3+
This is because it was too specific to the `optimize` attribute.
4+
Similar diagnostics occur for other attributes too.
5+
The example here will now emit `E0539`
6+
17
The `optimize` attribute was malformed.
28

39
Erroneous code example:
410

5-
```compile_fail,E0722
11+
```compile_fail,E0539
612
#![feature(optimize_attribute)]
713
814
#[optimize(something)] // error: invalid argument

compiler/rustc_error_codes/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ E0804: 0804,
685685
// E0707, // multiple elided lifetimes used in arguments of `async fn`
686686
// E0709, // multiple different lifetimes used in arguments of `async fn`
687687
// E0721, // `await` keyword
688+
// E0722, // replaced with a generic attribute input check
688689
// E0723, // unstable feature in `const` context
689690
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
690691
// E0744, // merged into E0728

compiler/rustc_parse/src/validate_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ fn emit_malformed_attribute(
285285
| sym::rustc_confusables
286286
| sym::repr
287287
| sym::deprecated
288+
| sym::optimize
288289
) {
289290
return;
290291
}

compiler/rustc_passes/src/check_attr.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
128128
Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => {
129129
self.check_inline(hir_id, *attr_span, span, kind, target)
130130
}
131+
Attribute::Parsed(AttributeKind::Optimize(_, attr_span)) => {
132+
self.check_optimize(hir_id, *attr_span, span, target)
133+
}
131134
Attribute::Parsed(AttributeKind::AllowInternalUnstable(syms)) => self
132135
.check_allow_internal_unstable(
133136
hir_id,
@@ -160,7 +163,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
160163
self.check_diagnostic_on_unimplemented(attr.span(), hir_id, target)
161164
}
162165
[sym::coverage, ..] => self.check_coverage(attr, span, target),
163-
[sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target),
164166
[sym::no_sanitize, ..] => {
165167
self.check_no_sanitize(attr, span, target)
166168
}
@@ -525,7 +527,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
525527

526528
/// Checks that `#[optimize(..)]` is applied to a function/closure/method,
527529
/// or to an impl block or module.
528-
fn check_optimize(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
530+
fn check_optimize(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
529531
let is_valid = matches!(
530532
target,
531533
Target::Fn
@@ -534,7 +536,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
534536
);
535537
if !is_valid {
536538
self.dcx().emit_err(errors::OptimizeInvalidTarget {
537-
attr_span: attr.span(),
539+
attr_span,
538540
defn_span: span,
539541
on_crate: hir_id == CRATE_HIR_ID,
540542
});

tests/ui/feature-gates/feature-gate-optimize_attribute.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ fn none() {}
1111

1212
#[optimize(banana)]
1313
//~^ ERROR the `#[optimize]` attribute is an experimental feature
14-
//~| ERROR E0722
14+
//~| ERROR malformed `optimize` attribute input [E0539]
1515
fn not_known() {}

tests/ui/feature-gates/feature-gate-optimize_attribute.stderr

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@ LL | #[optimize(banana)]
3838
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
3939
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
4040

41-
error[E0722]: invalid argument
42-
--> $DIR/feature-gate-optimize_attribute.rs:12:12
41+
error[E0539]: malformed `optimize` attribute input
42+
--> $DIR/feature-gate-optimize_attribute.rs:12:1
4343
|
4444
LL | #[optimize(banana)]
45-
| ^^^^^^
45+
| ^^^^^^^^^^^------^^
46+
| | |
47+
| | valid arguments are `size`, `speed` or `none`
48+
| help: must be of the form: `#[optimize(size|speed|none)]`
4649

4750
error: aborting due to 5 previous errors
4851

49-
Some errors have detailed explanations: E0658, E0722.
50-
For more information about an error, try `rustc --explain E0658`.
52+
Some errors have detailed explanations: E0539, E0658.
53+
For more information about an error, try `rustc --explain E0539`.

0 commit comments

Comments
 (0)