E0785: include_str!("./error_codes/E0785.md"),
E0786: include_str!("./error_codes/E0786.md"),
E0787: include_str!("./error_codes/E0787.md"),
+E0788: include_str!("./error_codes/E0788.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
--- /dev/null
+A `#[no_coverage]` attribute was incorrectly placed on something that couldn't
+be covered.
+
+Example of erroneous code:
+
+```compile_fail,E0788
+#[no_coverage]
+struct Foo;
+
+#[no_coverage]
+const FOO: Foo = Foo;
+```
+
+`#[no_coverage]` 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 `#[no_coverage]` attribute.
for attr in attrs {
let attr_is_valid = match attr.name_or_empty() {
sym::inline => self.check_inline(hir_id, attr, span, target),
+ sym::no_coverage => self.check_no_coverage(hir_id, attr, span, target),
sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target),
sym::marker => self.check_marker(hir_id, attr, span, target),
sym::rustc_must_implement_one_of => {
}
}
+ /// Checks if a `#[no_coverage]` is applied directly to a function
+ fn check_no_coverage(
+ &self,
+ hir_id: HirId,
+ attr: &Attribute,
+ span: Span,
+ target: Target,
+ ) -> bool {
+ match target {
+ // no_coverage on function is fine
+ Target::Fn
+ | Target::Closure
+ | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
+
+ // function prototypes can't be covered
+ Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
+ self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+ lint.build("`#[no_coverage]` is ignored on function prototypes").emit();
+ });
+ true
+ }
+
+ Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => {
+ self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+ lint.build("`#[no_coverage]` cannot be done recursively and must be applied to functions directly").emit();
+ });
+ true
+ }
+
+ Target::Expression | Target::Statement | Target::Arm => {
+ self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+ lint.build("`#[no_coverage]` can only be applied at the function level, not on code directly").emit();
+ });
+ true
+ }
+
+ _ => {
+ struct_span_err!(
+ self.tcx.sess,
+ attr.span,
+ E0788,
+ "`#[no_coverage]` must be applied to coverable code",
+ )
+ .span_label(span, "not coverable code")
+ .emit();
+ false
+ }
+ }
+ }
+
fn check_generic_attr(
&self,
hir_id: HirId,
--- /dev/null
+#![feature(extern_types)]
+#![feature(no_coverage)]
+#![feature(type_alias_impl_trait)]
+#![warn(unused_attributes)]
+
+trait Trait {
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ const X: u32;
+
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ type T;
+
+ type U;
+}
+
+impl Trait for () {
+ const X: u32 = 0;
+
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ type T = Self;
+
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ type U = impl Trait; //~ ERROR unconstrained opaque type
+}
+
+extern "C" {
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ static X: u32;
+
+ #[no_coverage] //~ ERROR `#[no_coverage]` must be applied to coverable code
+ type T;
+}
+
+#[no_coverage]
+fn main() {
+ #[no_coverage] //~ WARN `#[no_coverage]` can only be applied at the function level, not on code directly
+ let _ = ();
+
+ match () {
+ #[no_coverage] //~ WARN `#[no_coverage]` can only be applied at the function level, not on code directly
+ () => (),
+ }
+
+ #[no_coverage] //~ WARN `#[no_coverage]` can only be applied at the function level, not on code directly
+ return ();
+}
--- /dev/null
+warning: `#[no_coverage]` can only be applied at the function level, not on code directly
+ --> $DIR/no-coverage.rs:36:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/no-coverage.rs:4:9
+ |
+LL | #![warn(unused_attributes)]
+ | ^^^^^^^^^^^^^^^^^
+
+warning: `#[no_coverage]` can only be applied at the function level, not on code directly
+ --> $DIR/no-coverage.rs:40:9
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+
+warning: `#[no_coverage]` can only be applied at the function level, not on code directly
+ --> $DIR/no-coverage.rs:44:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:7:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | const X: u32;
+ | ------------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:10:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | type T;
+ | ------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:19:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | type T = Self;
+ | -------------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:22:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | type U = impl Trait;
+ | -------------------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:27:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | static X: u32;
+ | -------------- not coverable code
+
+error[E0788]: `#[no_coverage]` must be applied to coverable code
+ --> $DIR/no-coverage.rs:30:5
+ |
+LL | #[no_coverage]
+ | ^^^^^^^^^^^^^^
+LL | type T;
+ | ------- not coverable code
+
+error: unconstrained opaque type
+ --> $DIR/no-coverage.rs:23:14
+ |
+LL | type U = impl Trait;
+ | ^^^^^^^^^^
+ |
+ = note: `U` must be used in combination with a concrete type within the same module
+
+error: aborting due to 7 previous errors; 3 warnings emitted
+
+For more information about this error, try `rustc --explain E0788`.