about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_passes/messages.ftl6
-rw-r--r--compiler/rustc_passes/src/check_attr.rs30
-rw-r--r--compiler/rustc_passes/src/errors.rs12
-rw-r--r--tests/ui/attributes/optimize.rs22
-rw-r--r--tests/ui/attributes/optimize.stderr38
-rw-r--r--tests/ui/coroutine/other-attribute-on-gen.rs40
-rw-r--r--tests/ui/feature-gates/feature-gate-optimize_attribute.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-optimize_attribute.stderr30
8 files changed, 115 insertions, 69 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index e5a14f6a156..3613b7b862d 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -553,9 +553,9 @@ passes_only_has_effect_on =
         *[unspecified] (unspecified--this is a compiler bug)
     }
 
-passes_optimize_not_fn_or_closure =
-    attribute should be applied to function or closure
-    .label = not a function or closure
+passes_optimize_invalid_target =
+    attribute applied to an invalid target
+    .label = invalid target
 
 passes_outer_crate_level_attr =
     crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 4516ea94cad..8b30546d5cc 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -124,7 +124,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 }
                 [sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
                 [sym::coverage, ..] => self.check_coverage(attr, span, target),
-                [sym::optimize, ..] => self.check_optimize(hir_id, attr, target),
+                [sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target),
                 [sym::no_sanitize, ..] => {
                     self.check_applied_to_fn_or_method(hir_id, attr, span, target)
                 }
@@ -433,23 +433,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
 
     /// Checks that `#[optimize(..)]` is applied to a function/closure/method,
     /// or to an impl block or module.
-    // FIXME(#128488): this should probably be elevated to an error?
-    fn check_optimize(&self, hir_id: HirId, attr: &Attribute, target: Target) {
-        match target {
+    fn check_optimize(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
+        let is_valid = matches!(
+            target,
             Target::Fn
-            | Target::Closure
-            | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
-            | Target::Impl
-            | Target::Mod => {}
-
-            _ => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr.span,
-                    errors::OptimizeNotFnOrClosure,
-                );
-            }
+                | Target::Closure
+                | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
+        );
+        if !is_valid {
+            self.dcx().emit_err(errors::OptimizeInvalidTarget {
+                attr_span: attr.span,
+                defn_span: span,
+                on_crate: hir_id == CRATE_HIR_ID,
+            });
         }
     }
 
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 6dc3dfba58f..f01ddbd47ef 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -76,9 +76,15 @@ pub(crate) struct CoverageNotFnOrClosure {
     pub defn_span: Span,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_optimize_not_fn_or_closure)]
-pub(crate) struct OptimizeNotFnOrClosure;
+#[derive(Diagnostic)]
+#[diag(passes_optimize_invalid_target)]
+pub(crate) struct OptimizeInvalidTarget {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub defn_span: Span,
+    pub on_crate: bool,
+}
 
 #[derive(Diagnostic)]
 #[diag(passes_should_be_applied_to_fn)]
diff --git a/tests/ui/attributes/optimize.rs b/tests/ui/attributes/optimize.rs
index b01806165c1..7a1cc1be9ee 100644
--- a/tests/ui/attributes/optimize.rs
+++ b/tests/ui/attributes/optimize.rs
@@ -3,11 +3,13 @@
 #![deny(unused_attributes)]
 #![allow(dead_code)]
 
-#[optimize(speed)] //~ ERROR attribute should be applied to function or closure
+//@ edition: 2018
+
+#[optimize(speed)] //~ ERROR attribute applied to an invalid target
 struct F;
 
 fn invalid() {
-    #[optimize(speed)] //~ ERROR attribute should be applied to function or closure
+    #[optimize(speed)] //~ ERROR attribute applied to an invalid target
     {
         1
     };
@@ -16,13 +18,25 @@ fn invalid() {
 #[optimize(speed)]
 fn valid() {}
 
-#[optimize(speed)]
+#[optimize(speed)] //~ ERROR attribute applied to an invalid target
 mod valid_module {}
 
-#[optimize(speed)]
+#[optimize(speed)] //~ ERROR attribute applied to an invalid target
 impl F {}
 
 fn main() {
     let _ = #[optimize(speed)]
     (|| 1);
 }
+
+use std::future::Future;
+
+fn async_block() -> impl Future<Output = ()> {
+    #[optimize(speed)]
+    async { }
+}
+
+#[optimize(speed)]
+async fn async_fn() {
+    ()
+}
diff --git a/tests/ui/attributes/optimize.stderr b/tests/ui/attributes/optimize.stderr
index 3c445d73c2e..ad9309d27a5 100644
--- a/tests/ui/attributes/optimize.stderr
+++ b/tests/ui/attributes/optimize.stderr
@@ -1,20 +1,36 @@
-error: attribute should be applied to function or closure
-  --> $DIR/optimize.rs:6:1
+error: attribute applied to an invalid target
+  --> $DIR/optimize.rs:8:1
    |
 LL | #[optimize(speed)]
    | ^^^^^^^^^^^^^^^^^^
+LL | struct F;
+   | --------- invalid target
+
+error: attribute applied to an invalid target
+  --> $DIR/optimize.rs:12:5
    |
-note: the lint level is defined here
-  --> $DIR/optimize.rs:3:9
+LL |       #[optimize(speed)]
+   |       ^^^^^^^^^^^^^^^^^^
+LL | /     {
+LL | |         1
+LL | |     };
+   | |_____- invalid target
+
+error: attribute applied to an invalid target
+  --> $DIR/optimize.rs:21:1
    |
-LL | #![deny(unused_attributes)]
-   |         ^^^^^^^^^^^^^^^^^
+LL | #[optimize(speed)]
+   | ^^^^^^^^^^^^^^^^^^
+LL | mod valid_module {}
+   | ------------------- invalid target
 
-error: attribute should be applied to function or closure
-  --> $DIR/optimize.rs:10:5
+error: attribute applied to an invalid target
+  --> $DIR/optimize.rs:24:1
    |
-LL |     #[optimize(speed)]
-   |     ^^^^^^^^^^^^^^^^^^
+LL | #[optimize(speed)]
+   | ^^^^^^^^^^^^^^^^^^
+LL | impl F {}
+   | --------- invalid target
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/coroutine/other-attribute-on-gen.rs b/tests/ui/coroutine/other-attribute-on-gen.rs
new file mode 100644
index 00000000000..0f26dc6860d
--- /dev/null
+++ b/tests/ui/coroutine/other-attribute-on-gen.rs
@@ -0,0 +1,40 @@
+//@ edition: 2024
+//@ compile-flags: -Zunstable-options
+//@ run-pass
+#![feature(gen_blocks)]
+#![feature(optimize_attribute)]
+#![feature(stmt_expr_attributes)]
+#![feature(async_iterator)]
+#![allow(dead_code)]
+
+// make sure that other attributes e.g. `optimize` can be applied to gen blocks and functions
+
+fn main() { }
+
+fn optimize_gen_block() -> impl Iterator<Item = ()> {
+    #[optimize(speed)]
+    gen { yield (); }
+}
+
+#[optimize(speed)]
+gen fn optimize_gen_fn() -> i32 {
+    yield 1;
+    yield 2;
+    yield 3;
+}
+
+#[optimize(speed)]
+async gen fn optimize_async_gen_fn() -> i32 {
+    yield 1;
+    yield 2;
+    yield 3;
+}
+
+use std::async_iter::AsyncIterator;
+
+pub fn deduce() -> impl AsyncIterator<Item = ()> {
+    #[optimize(size)]
+    async gen {
+        yield ();
+    }
+}
diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
index 15aa3a6af4c..7f9cada6a47 100644
--- a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
+++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
@@ -1,8 +1,4 @@
 #![crate_type="rlib"]
-#![optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature
-
-#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature
-mod module {
 
 #[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 fn size() {}
@@ -14,5 +10,3 @@ fn speed() {}
 //~^ ERROR the `#[optimize]` attribute is an experimental feature
 //~| ERROR E0722
 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 609526150ba..ca8f4a078f0 100644
--- a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
+++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
@@ -1,25 +1,5 @@
 error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:2:1
-   |
-LL | #![optimize(speed)]
-   | ^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
-   = 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[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:4:1
-   |
-LL | #[optimize(size)]
-   | ^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
-   = 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[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:7:1
+  --> $DIR/feature-gate-optimize_attribute.rs:3:1
    |
 LL | #[optimize(size)]
    | ^^^^^^^^^^^^^^^^^
@@ -29,7 +9,7 @@ LL | #[optimize(size)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:10:1
+  --> $DIR/feature-gate-optimize_attribute.rs:6:1
    |
 LL | #[optimize(speed)]
    | ^^^^^^^^^^^^^^^^^^
@@ -39,7 +19,7 @@ LL | #[optimize(speed)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[optimize]` attribute is an experimental feature
-  --> $DIR/feature-gate-optimize_attribute.rs:13:1
+  --> $DIR/feature-gate-optimize_attribute.rs:9:1
    |
 LL | #[optimize(banana)]
    | ^^^^^^^^^^^^^^^^^^^
@@ -49,12 +29,12 @@ LL | #[optimize(banana)]
    = 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:13:12
+  --> $DIR/feature-gate-optimize_attribute.rs:9:12
    |
 LL | #[optimize(banana)]
    |            ^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0658, E0722.
 For more information about an error, try `rustc --explain E0658`.