about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-12-25 11:25:55 +0000
committerbors <bors@rust-lang.org>2024-12-25 11:25:55 +0000
commitf432d5dcb52db23aec88a1a22cc76f00addaf914 (patch)
treea751bc315122bacfe63f82b370aeab75781fc4fa
parenta0a5c423463e4f6f82ced50b15fe5afab296b560 (diff)
parentd04f8bd00c3921c184c83fc8ff73b70e3d5fb2d6 (diff)
Auto merge of #134756 - jieyouxu:rollup-suec48x, r=jieyouxu
Rollup of 3 pull requests

Successful merges:

 - #134743 (Default to short backtraces for dev builds of rustc itself)
 - #134750 (Update `#[coverage(..)]` attribute error messages to match the current implementation)
 - #134751 (Enable LSX feature for LoongArch OpenHarmony target)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs6
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0788.md36
-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--compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs2
-rw-r--r--tests/ui/coverage-attr/allowed-positions.rs116
-rw-r--r--tests/ui/coverage-attr/allowed-positions.stderr192
-rw-r--r--tests/ui/coverage-attr/name-value.rs14
-rw-r--r--tests/ui/coverage-attr/name-value.stderr42
-rw-r--r--tests/ui/coverage-attr/no-coverage.rs60
-rw-r--r--tests/ui/coverage-attr/no-coverage.stderr112
-rw-r--r--tests/ui/coverage-attr/word-only.rs14
-rw-r--r--tests/ui/coverage-attr/word-only.stderr42
14 files changed, 437 insertions, 248 deletions
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 3dc39fc131a..b13cc4d0b06 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -1388,7 +1388,11 @@ pub fn install_ice_hook(
     // opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE"
     // (e.g. `RUST_BACKTRACE=1`)
     if env::var_os("RUST_BACKTRACE").is_none() {
-        panic::set_backtrace_style(panic::BacktraceStyle::Full);
+        if env!("CFG_RELEASE_CHANNEL") == "dev" {
+            panic::set_backtrace_style(panic::BacktraceStyle::Short);
+        } else {
+            panic::set_backtrace_style(panic::BacktraceStyle::Full);
+        }
     }
 
     let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default());
diff --git a/compiler/rustc_error_codes/src/error_codes/E0788.md b/compiler/rustc_error_codes/src/error_codes/E0788.md
index d655e51fa66..ba138aed2d1 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0788.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0788.md
@@ -1,26 +1,24 @@
-A `#[coverage]` attribute was applied to something which does not show up
-in code coverage, or is too granular to be excluded from the coverage report.
+A `#[coverage(off|on)]` attribute was found in a position where it is not
+allowed.
 
-For now, this attribute can only be applied to function, method, and closure
-definitions. In the future, it may be added to statements, blocks, and
-expressions, and for the time being, using this attribute in those places
-will just emit an `unused_attributes` lint instead of this error.
+Coverage attributes can be applied to:
+- Function and method declarations that have a body, including trait methods
+  that have a default implementation.
+- Closure expressions, in situations where attributes can be applied to
+  expressions.
+- `impl` blocks (inherent or trait), and modules.
 
 Example of erroneous code:
 
 ```compile_fail,E0788
-#[coverage(off)]
-struct Foo;
-
-#[coverage(on)]
-const FOO: Foo = Foo;
+unsafe extern "C" {
+    #[coverage(off)]
+    fn foreign_fn();
+}
 ```
 
-`#[coverage(off)]` tells the compiler to not generate coverage instrumentation
-for a piece of code when the `-C instrument-coverage` flag is passed. Things
-like structs and consts are not coverable code, and thus cannot do anything
-with this attribute.
-
-If you wish to apply this attribute to all methods in an impl or module,
-manually annotate each method; it is not possible to annotate the entire impl
-with a `#[coverage]` attribute.
+When using the `-C instrument-coverage` flag, coverage attributes act as a
+hint to the compiler that it should instrument or not instrument the
+corresponding function or enclosed functions. The precise effect of applying
+a coverage attribute is not guaranteed and may change in future compiler
+versions.
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/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs
index 12e026294cf..11d05db6b0a 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_ohos.rs
@@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic".into(),
-            features: "+f,+d".into(),
+            features: "+f,+d,+lsx".into(),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             supported_sanitizers: SanitizerSet::ADDRESS
diff --git a/tests/ui/coverage-attr/allowed-positions.rs b/tests/ui/coverage-attr/allowed-positions.rs
new file mode 100644
index 00000000000..f1169fa6570
--- /dev/null
+++ b/tests/ui/coverage-attr/allowed-positions.rs
@@ -0,0 +1,116 @@
+//! Tests where the `#[coverage(..)]` attribute can and cannot be used.
+
+//@ reference: attributes.coverage.allowed-positions
+
+#![feature(coverage_attribute)]
+#![feature(extern_types)]
+#![feature(impl_trait_in_assoc_type)]
+#![warn(unused_attributes)]
+#![coverage(off)]
+
+#[coverage(off)]
+mod submod {}
+
+#[coverage(off)] //~ ERROR coverage attribute not allowed here [E0788]
+type MyTypeAlias = ();
+
+#[coverage(off)] //~ ERROR [E0788]
+trait MyTrait {
+    #[coverage(off)] //~ ERROR [E0788]
+    const TRAIT_ASSOC_CONST: u32;
+
+    #[coverage(off)] //~ ERROR [E0788]
+    type TraitAssocType;
+
+    #[coverage(off)] //~ ERROR [E0788]
+    fn trait_method(&self);
+
+    #[coverage(off)]
+    fn trait_method_with_default(&self) {}
+
+    #[coverage(off)] //~ ERROR [E0788]
+    fn trait_assoc_fn();
+}
+
+#[coverage(off)]
+impl MyTrait for () {
+    const TRAIT_ASSOC_CONST: u32 = 0;
+
+    #[coverage(off)] //~ ERROR [E0788]
+    type TraitAssocType = Self;
+
+    #[coverage(off)]
+    fn trait_method(&self) {}
+    #[coverage(off)]
+    fn trait_method_with_default(&self) {}
+    #[coverage(off)]
+    fn trait_assoc_fn() {}
+}
+
+trait HasAssocType {
+    type T;
+    fn constrain_assoc_type() -> Self::T;
+}
+
+impl HasAssocType for () {
+    #[coverage(off)] //~ ERROR [E0788]
+    type T = impl Copy;
+    fn constrain_assoc_type() -> Self::T {}
+}
+
+#[coverage(off)] //~ ERROR [E0788]
+struct MyStruct {
+    #[coverage(off)] //~ ERROR [E0788]
+    field: u32,
+}
+
+#[coverage(off)]
+impl MyStruct {
+    #[coverage(off)]
+    fn method(&self) {}
+    #[coverage(off)]
+    fn assoc_fn() {}
+}
+
+extern "C" {
+    #[coverage(off)] //~ ERROR [E0788]
+    static X: u32;
+
+    #[coverage(off)] //~ ERROR [E0788]
+    type T;
+
+    #[coverage(off)] //~ ERROR [E0788]
+    fn foreign_fn();
+}
+
+#[coverage(off)]
+fn main() {
+    #[coverage(off)] //~ ERROR [E0788]
+    let _ = ();
+
+    // Currently not allowed on let statements, even if they bind to a closure.
+    // It might be nice to support this as a special case someday, but trying
+    // to define the precise boundaries of that special case might be tricky.
+    #[coverage(off)] //~ ERROR [E0788]
+    let _let_closure = || ();
+
+    // In situations where attributes can already be applied to expressions,
+    // the coverage attribute is allowed on closure expressions.
+    let _closure_tail_expr = {
+        #[coverage(off)]
+        || ()
+    };
+
+    // Applying attributes to arbitrary expressions requires an unstable
+    // feature, but if that feature were enabled then this would be allowed.
+    let _closure_expr = #[coverage(off)] || ();
+    //~^ ERROR attributes on expressions are experimental [E0658]
+
+    match () {
+        #[coverage(off)] //~ ERROR [E0788]
+        () => (),
+    }
+
+    #[coverage(off)] //~ ERROR [E0788]
+    return ();
+}
diff --git a/tests/ui/coverage-attr/allowed-positions.stderr b/tests/ui/coverage-attr/allowed-positions.stderr
new file mode 100644
index 00000000000..34562a4da1b
--- /dev/null
+++ b/tests/ui/coverage-attr/allowed-positions.stderr
@@ -0,0 +1,192 @@
+error[E0658]: attributes on expressions are experimental
+  --> $DIR/allowed-positions.rs:106:25
+   |
+LL |     let _closure_expr = #[coverage(off)] || ();
+   |                         ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+   = 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]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:14:1
+   |
+LL | #[coverage(off)]
+   | ^^^^^^^^^^^^^^^^
+LL | type MyTypeAlias = ();
+   | ---------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:17:1
+   |
+LL |   #[coverage(off)]
+   |   ^^^^^^^^^^^^^^^^
+LL | / trait MyTrait {
+LL | |     #[coverage(off)]
+LL | |     const TRAIT_ASSOC_CONST: u32;
+...  |
+LL | |     fn trait_assoc_fn();
+LL | | }
+   | |_- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:61:1
+   |
+LL |   #[coverage(off)]
+   |   ^^^^^^^^^^^^^^^^
+LL | / struct MyStruct {
+LL | |     #[coverage(off)]
+LL | |     field: u32,
+LL | | }
+   | |_- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:63:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     field: u32,
+   |     ---------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:88:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     let _ = ();
+   |     ----------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:94:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     let _let_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]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:110:9
+   |
+LL |         #[coverage(off)]
+   |         ^^^^^^^^^^^^^^^^
+LL |         () => (),
+   |         -------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:114:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     return ();
+   |     --------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+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, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:22:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     type TraitAssocType;
+   |     -------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:25:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     fn trait_method(&self);
+   |     ----------------------- function has no body
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:31:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     fn trait_assoc_fn();
+   |     -------------------- function has no body
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:39:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     type TraitAssocType = Self;
+   |     --------------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:56:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     type T = impl Copy;
+   |     ------------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:76:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     static X: u32;
+   |     -------------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:79:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     type T;
+   |     ------- not a function, impl block, or module
+   |
+   = help: coverage attribute can be applied to a function (with body), impl block, or module
+
+error[E0788]: coverage attribute not allowed here
+  --> $DIR/allowed-positions.rs:82:5
+   |
+LL |     #[coverage(off)]
+   |     ^^^^^^^^^^^^^^^^
+LL |     fn foreign_fn();
+   |     ---------------- 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
+
+Some errors have detailed explanations: E0658, E0788.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/tests/ui/coverage-attr/name-value.rs b/tests/ui/coverage-attr/name-value.rs
index e5df5bc3da0..ffd9afe2ce1 100644
--- a/tests/ui/coverage-attr/name-value.rs
+++ b/tests/ui/coverage-attr/name-value.rs
@@ -20,7 +20,7 @@ mod my_mod_inner {
 
 #[coverage = "off"]
 //~^ ERROR malformed `coverage` attribute input
-//~| ERROR attribute should be applied to a function definition or closure
+//~| ERROR [E0788]
 struct MyStruct;
 
 #[coverage = "off"]
@@ -28,22 +28,22 @@ struct MyStruct;
 impl MyStruct {
     #[coverage = "off"]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     const X: u32 = 7;
 }
 
 #[coverage = "off"]
 //~^ ERROR malformed `coverage` attribute input
-//~| ERROR attribute should be applied to a function definition or closure
+//~| ERROR [E0788]
 trait MyTrait {
     #[coverage = "off"]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     const X: u32;
 
     #[coverage = "off"]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     type T;
 }
 
@@ -52,12 +52,12 @@ trait MyTrait {
 impl MyTrait for MyStruct {
     #[coverage = "off"]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     const X: u32 = 8;
 
     #[coverage = "off"]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     type T = ();
 }
 
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/no-coverage.rs b/tests/ui/coverage-attr/no-coverage.rs
deleted file mode 100644
index c386f25816e..00000000000
--- a/tests/ui/coverage-attr/no-coverage.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-//@ reference: attributes.coverage.allowed-positions
-
-#![feature(extern_types)]
-#![feature(coverage_attribute)]
-#![feature(impl_trait_in_assoc_type)]
-#![warn(unused_attributes)]
-#![coverage(off)]
-
-#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-trait Trait {
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    const X: u32;
-
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    type T;
-
-    type U;
-
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    fn f(&self);
-
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    fn g();
-}
-
-#[coverage(off)]
-impl Trait for () {
-    const X: u32 = 0;
-
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    type T = Self;
-
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    type U = impl Trait; //~ ERROR unconstrained opaque type
-
-    fn f(&self) {}
-    fn g() {}
-}
-
-extern "C" {
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    static X: u32;
-
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    type T;
-}
-
-#[coverage(off)]
-fn main() {
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    let _ = ();
-
-    match () {
-        #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-        () => (),
-    }
-
-    #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure
-    return ();
-}
diff --git a/tests/ui/coverage-attr/no-coverage.stderr b/tests/ui/coverage-attr/no-coverage.stderr
deleted file mode 100644
index f5a44ecec74..00000000000
--- a/tests/ui/coverage-attr/no-coverage.stderr
+++ /dev/null
@@ -1,112 +0,0 @@
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:9:1
-   |
-LL |   #[coverage(off)]
-   |   ^^^^^^^^^^^^^^^^
-LL | / trait Trait {
-LL | |     #[coverage(off)]
-LL | |     const X: u32;
-...  |
-LL | |     fn g();
-LL | | }
-   | |_- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:50:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     let _ = ();
-   |     ----------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:54:9
-   |
-LL |         #[coverage(off)]
-   |         ^^^^^^^^^^^^^^^^
-LL |         () => (),
-   |         -------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:58:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     return ();
-   |     --------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:11:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     const X: u32;
-   |     ------------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:14:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     type T;
-   |     ------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:19:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     fn f(&self);
-   |     ------------ not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:22:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     fn g();
-   |     ------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:30:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     type T = Self;
-   |     -------------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:33:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     type U = impl Trait;
-   |     -------------------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:41:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     static X: u32;
-   |     -------------- not a function or closure
-
-error[E0788]: attribute should be applied to a function definition or closure
-  --> $DIR/no-coverage.rs:44:5
-   |
-LL |     #[coverage(off)]
-   |     ^^^^^^^^^^^^^^^^
-LL |     type T;
-   |     ------- not a function or closure
-
-error: unconstrained opaque type
-  --> $DIR/no-coverage.rs:34:14
-   |
-LL |     type U = impl Trait;
-   |              ^^^^^^^^^^
-   |
-   = note: `U` must be used in combination with a concrete type within the same impl
-
-error: aborting due to 13 previous errors
-
-For more information about this error, try `rustc --explain E0788`.
diff --git a/tests/ui/coverage-attr/word-only.rs b/tests/ui/coverage-attr/word-only.rs
index add225cdb93..d0f743938f3 100644
--- a/tests/ui/coverage-attr/word-only.rs
+++ b/tests/ui/coverage-attr/word-only.rs
@@ -20,7 +20,7 @@ mod my_mod_inner {
 
 #[coverage]
 //~^ ERROR malformed `coverage` attribute input
-//~| ERROR attribute should be applied to a function definition or closure
+//~| ERROR [E0788]
 struct MyStruct;
 
 #[coverage]
@@ -28,22 +28,22 @@ struct MyStruct;
 impl MyStruct {
     #[coverage]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     const X: u32 = 7;
 }
 
 #[coverage]
 //~^ ERROR malformed `coverage` attribute input
-//~| ERROR attribute should be applied to a function definition or closure
+//~| ERROR [E0788]
 trait MyTrait {
     #[coverage]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     const X: u32;
 
     #[coverage]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     type T;
 }
 
@@ -52,12 +52,12 @@ trait MyTrait {
 impl MyTrait for MyStruct {
     #[coverage]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     const X: u32 = 8;
 
     #[coverage]
     //~^ ERROR malformed `coverage` attribute input
-    //~| ERROR attribute should be applied to a function definition or closure
+    //~| ERROR [E0788]
     type T = ();
 }
 
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