about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZalathar <Zalathar@users.noreply.github.com>2024-12-25 14:57:21 +1100
committerZalathar <Zalathar@users.noreply.github.com>2024-12-25 16:17:09 +1100
commit399620939844d7b2e4a93e450f8c578960d0b6f2 (patch)
treeb83ad750522f061f1dae7093fdb8c0860f0bded8
parent9124662da3e0d573703c9bb07d5e3cf8d06f1b20 (diff)
downloadrust-399620939844d7b2e4a93e450f8c578960d0b6f2.tar.gz
rust-399620939844d7b2e4a93e450f8c578960d0b6f2.zip
Overhaul error messages for disallowed coverage attributes
-rw-r--r--compiler/rustc_passes/messages.ftl8
-rw-r--r--compiler/rustc_passes/src/check_attr.rs25
-rw-r--r--compiler/rustc_passes/src/errors.rs16
-rw-r--r--tests/ui/coverage-attr/allowed-positions.stderr102
-rw-r--r--tests/ui/coverage-attr/name-value.stderr42
-rw-r--r--tests/ui/coverage-attr/word-only.stderr42
6 files changed, 160 insertions, 75 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index ba3101e9058..f39bea2a56f 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -112,9 +112,11 @@ passes_coroutine_on_non_closure =
     attribute should be applied to closures
     .label = not a closure
 
-passes_coverage_not_fn_or_closure =
-    attribute should be applied to a function definition or closure
-    .label = not a function or closure
+passes_coverage_attribute_not_allowed =
+    coverage attribute not allowed here
+    .not_fn_impl_mod = not a function, impl block, or module
+    .no_body = function has no body
+    .help = coverage attribute can be applied to a function (with body), impl block, or module
 
 passes_dead_codes =
     { $multiple ->
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 8cf20a378d4..12f715a0fe4 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -432,21 +432,34 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
 
     /// Checks that `#[coverage(..)]` is applied to a function/closure/method,
     /// or to an impl block or module.
-    fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) {
+    fn check_coverage(&self, attr: &Attribute, target_span: Span, target: Target) {
+        let mut not_fn_impl_mod = None;
+        let mut no_body = None;
+
         match target {
             Target::Fn
             | Target::Closure
             | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
             | Target::Impl
-            | Target::Mod => {}
+            | Target::Mod => return,
+
+            // These are "functions", but they aren't allowed because they don't
+            // have a body, so the usual explanation would be confusing.
+            Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
+                no_body = Some(target_span);
+            }
 
             _ => {
-                self.dcx().emit_err(errors::CoverageNotFnOrClosure {
-                    attr_span: attr.span,
-                    defn_span: span,
-                });
+                not_fn_impl_mod = Some(target_span);
             }
         }
+
+        self.dcx().emit_err(errors::CoverageAttributeNotAllowed {
+            attr_span: attr.span,
+            not_fn_impl_mod,
+            no_body,
+            help: (),
+        });
     }
 
     /// Checks that `#[optimize(..)]` is applied to a function/closure/method,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 163325f2a3c..d95fa5db0ce 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -71,13 +71,21 @@ pub(crate) struct InlineNotFnOrClosure {
     pub defn_span: Span,
 }
 
+/// "coverage attribute not allowed here"
 #[derive(Diagnostic)]
-#[diag(passes_coverage_not_fn_or_closure, code = E0788)]
-pub(crate) struct CoverageNotFnOrClosure {
+#[diag(passes_coverage_attribute_not_allowed, code = E0788)]
+pub(crate) struct CoverageAttributeNotAllowed {
     #[primary_span]
     pub attr_span: Span,
-    #[label]
-    pub defn_span: Span,
+    /// "not a function, impl block, or module"
+    #[label(passes_not_fn_impl_mod)]
+    pub not_fn_impl_mod: Option<Span>,
+    /// "function has no body"
+    #[label(passes_no_body)]
+    pub no_body: Option<Span>,
+    /// "coverage attribute can be applied to a function (with body), impl block, or module"
+    #[help]
+    pub help: (),
 }
 
 #[derive(Diagnostic)]
diff --git a/tests/ui/coverage-attr/allowed-positions.stderr b/tests/ui/coverage-attr/allowed-positions.stderr
index 08a578ddd83..34562a4da1b 100644
--- a/tests/ui/coverage-attr/allowed-positions.stderr
+++ b/tests/ui/coverage-attr/allowed-positions.stderr
@@ -8,15 +8,17 @@ LL |     let _closure_expr = #[coverage(off)] || ();
    = help: add `#![feature(stmt_expr_attributes)]` 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[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:14:1
    |
 LL | #[coverage(off)]
    | ^^^^^^^^^^^^^^^^
 LL | type MyTypeAlias = ();
-   | ---------------------- not a function or closure
+   | ---------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:17:1
    |
 LL |   #[coverage(off)]
@@ -27,9 +29,11 @@ LL | |     const TRAIT_ASSOC_CONST: u32;
 ...  |
 LL | |     fn trait_assoc_fn();
 LL | | }
-   | |_- not a function or closure
+   | |_- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:61:1
    |
 LL |   #[coverage(off)]
@@ -38,119 +42,149 @@ LL | / struct MyStruct {
 LL | |     #[coverage(off)]
 LL | |     field: u32,
 LL | | }
-   | |_- not a function or closure
+   | |_- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:63:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     field: u32,
-   |     ---------- not a function or closure
+   |     ---------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:88:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     let _ = ();
-   |     ----------- not a function or closure
+   |     ----------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:94:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     let _let_closure = || ();
-   |     ------------------------- not a function or closure
+   |     ------------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:110:9
    |
 LL |         #[coverage(off)]
    |         ^^^^^^^^^^^^^^^^
 LL |         () => (),
-   |         -------- not a function or closure
+   |         -------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:114:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     return ();
-   |     --------- not a function or closure
+   |     --------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:19:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     const TRAIT_ASSOC_CONST: u32;
-   |     ----------------------------- not a function or closure
+   |     ----------------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:22:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     type TraitAssocType;
-   |     -------------------- not a function or closure
+   |     -------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:25:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     fn trait_method(&self);
-   |     ----------------------- not a function or closure
+   |     ----------------------- function has no body
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:31:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     fn trait_assoc_fn();
-   |     -------------------- not a function or closure
+   |     -------------------- function has no body
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:39:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     type TraitAssocType = Self;
-   |     --------------------------- not a function or closure
+   |     --------------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:56:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     type T = impl Copy;
-   |     ------------------- not a function or closure
+   |     ------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:76:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     static X: u32;
-   |     -------------- not a function or closure
+   |     -------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:79:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     type T;
-   |     ------- not a function or closure
+   |     ------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/allowed-positions.rs:82:5
    |
 LL |     #[coverage(off)]
    |     ^^^^^^^^^^^^^^^^
 LL |     fn foreign_fn();
-   |     ---------------- not a function or closure
+   |     ---------------- function has no body
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
 error: aborting due to 18 previous errors
 
diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr
index 84a57f575f9..bfd22ed5451 100644
--- a/tests/ui/coverage-attr/name-value.stderr
+++ b/tests/ui/coverage-attr/name-value.stderr
@@ -154,16 +154,18 @@ LL | #[coverage(off)]
 LL | #[coverage(on)]
    |
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/name-value.rs:21:1
    |
 LL | #[coverage = "off"]
    | ^^^^^^^^^^^^^^^^^^^
 ...
 LL | struct MyStruct;
-   | ---------------- not a function or closure
+   | ---------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/name-value.rs:35:1
    |
 LL |   #[coverage = "off"]
@@ -174,52 +176,64 @@ LL | |     #[coverage = "off"]
 ...  |
 LL | |     type T;
 LL | | }
-   | |_- not a function or closure
+   | |_- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/name-value.rs:39:5
    |
 LL |     #[coverage = "off"]
    |     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     const X: u32;
-   |     ------------- not a function or closure
+   |     ------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/name-value.rs:44:5
    |
 LL |     #[coverage = "off"]
    |     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     type T;
-   |     ------- not a function or closure
+   |     ------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/name-value.rs:29:5
    |
 LL |     #[coverage = "off"]
    |     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     const X: u32 = 7;
-   |     ----------------- not a function or closure
+   |     ----------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/name-value.rs:53:5
    |
 LL |     #[coverage = "off"]
    |     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     const X: u32 = 8;
-   |     ----------------- not a function or closure
+   |     ----------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/name-value.rs:58:5
    |
 LL |     #[coverage = "off"]
    |     ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     type T = ();
-   |     ------------ not a function or closure
+   |     ------------ not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
 error: aborting due to 19 previous errors
 
diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr
index 97a0723988f..bad50b0c961 100644
--- a/tests/ui/coverage-attr/word-only.stderr
+++ b/tests/ui/coverage-attr/word-only.stderr
@@ -154,16 +154,18 @@ LL | #[coverage(off)]
 LL | #[coverage(on)]
    |
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/word-only.rs:21:1
    |
 LL | #[coverage]
    | ^^^^^^^^^^^
 ...
 LL | struct MyStruct;
-   | ---------------- not a function or closure
+   | ---------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/word-only.rs:35:1
    |
 LL |   #[coverage]
@@ -174,52 +176,64 @@ LL | |     #[coverage]
 ...  |
 LL | |     type T;
 LL | | }
-   | |_- not a function or closure
+   | |_- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/word-only.rs:39:5
    |
 LL |     #[coverage]
    |     ^^^^^^^^^^^
 ...
 LL |     const X: u32;
-   |     ------------- not a function or closure
+   |     ------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/word-only.rs:44:5
    |
 LL |     #[coverage]
    |     ^^^^^^^^^^^
 ...
 LL |     type T;
-   |     ------- not a function or closure
+   |     ------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/word-only.rs:29:5
    |
 LL |     #[coverage]
    |     ^^^^^^^^^^^
 ...
 LL |     const X: u32 = 7;
-   |     ----------------- not a function or closure
+   |     ----------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/word-only.rs:53:5
    |
 LL |     #[coverage]
    |     ^^^^^^^^^^^
 ...
 LL |     const X: u32 = 8;
-   |     ----------------- not a function or closure
+   |     ----------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
-error[E0788]: attribute should be applied to a function definition or closure
+error[E0788]: coverage attribute not allowed here
   --> $DIR/word-only.rs:58:5
    |
 LL |     #[coverage]
    |     ^^^^^^^^^^^
 ...
 LL |     type T = ();
-   |     ------------ not a function or closure
+   |     ------------ not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
 
 error: aborting due to 19 previous errors