From b5dfeba0e14c00c5cc91c935bad5633fa2df8461 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 19 Jun 2024 17:02:19 +1000 Subject: [PATCH 1/4] coverage: Forbid multiple `#[coverage(..)]` attributes It might make sense to allow this in the future, if we add values that aren't mutually exclusive, but for now having multiple coverage attributes on one item is useless. --- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 5e83e0d27e198..7185240d24511 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -479,7 +479,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), gated!( coverage, Normal, template!(Word, List: "on|off"), - WarnFollowing, EncodeCrossCrate::No, + ErrorPreceding, EncodeCrossCrate::No, coverage_attribute, experimental!(coverage) ), From a000fa8b54c7502df36546d9344880062c622a3c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 20 Jun 2024 17:44:11 +1000 Subject: [PATCH 2/4] coverage: Tighten validation of `#[coverage(off)]` and `#[coverage(on)]` --- compiler/rustc_codegen_ssa/messages.ftl | 2 -- .../rustc_codegen_ssa/src/codegen_attrs.rs | 11 ++++----- compiler/rustc_codegen_ssa/src/errors.rs | 7 ------ compiler/rustc_feature/src/builtin_attrs.rs | 24 +++++++++++-------- compiler/rustc_parse/src/validate_attr.rs | 13 +++++++--- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 1a851ad04a1f0..000fe2e3ce0f5 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -27,8 +27,6 @@ codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error} -codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)` - codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` 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 diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 15955170e8736..fb71cdaa8ff2a 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -15,11 +15,7 @@ use rustc_span::{sym, Span}; use rustc_target::spec::{abi, SanitizerSet}; use crate::errors; -use crate::target_features::from_target_feature; -use crate::{ - errors::{ExpectedCoverageSymbol, ExpectedUsedSymbol}, - target_features::check_target_feature_trait_unsafe, -}; +use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature}; fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage { use rustc_middle::mir::mono::Linkage::*; @@ -139,7 +135,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // coverage on a smaller scope within an excluded larger scope. } Some(_) | None => { - tcx.dcx().emit_err(ExpectedCoverageSymbol { span: attr.span }); + tcx.dcx() + .span_delayed_bug(attr.span, "unexpected value of coverage attribute"); } } } @@ -174,7 +171,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; } Some(_) => { - tcx.dcx().emit_err(ExpectedUsedSymbol { span: attr.span }); + tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span }); } None => { // Unfortunately, unconditionally using `llvm.used` causes diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index e6ba31c516508..e9d31db92541b 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -564,13 +564,6 @@ pub struct UnknownArchiveKind<'a> { pub kind: &'a str, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_expected_coverage_symbol)] -pub struct ExpectedCoverageSymbol { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(codegen_ssa_expected_used_symbol)] pub struct ExpectedUsedSymbol { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 7185240d24511..4ce400fc49f6b 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -105,6 +105,9 @@ pub struct AttributeTemplate { pub word: bool, /// If `Some`, the attribute is allowed to take a list of items like `#[allow(..)]`. pub list: Option<&'static str>, + /// If non-empty, the attribute is allowed to take a list containing exactly + /// one of the listed words, like `#[coverage(off)]`. + pub one_of: &'static [Symbol], /// If `Some`, the attribute is allowed to be a name/value pair where the /// value is a string, like `#[must_use = "reason"]`. pub name_value_str: Option<&'static str>, @@ -165,19 +168,20 @@ pub enum AttributeDuplicates { /// E.g., `template!(Word, List: "description")` means that the attribute /// supports forms `#[attr]` and `#[attr(description)]`. macro_rules! template { - (Word) => { template!(@ true, None, None) }; - (List: $descr: expr) => { template!(@ false, Some($descr), None) }; - (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) }; - (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) }; - (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) }; + (Word) => { template!(@ true, None, &[], None) }; + (List: $descr: expr) => { template!(@ false, Some($descr), &[], None) }; + (OneOf: $one_of: expr) => { template!(@ false, None, $one_of, None) }; + (NameValueStr: $descr: expr) => { template!(@ false, None, &[], Some($descr)) }; + (Word, List: $descr: expr) => { template!(@ true, Some($descr), &[], None) }; + (Word, NameValueStr: $descr: expr) => { template!(@ true, None, &[], Some($descr)) }; (List: $descr1: expr, NameValueStr: $descr2: expr) => { - template!(@ false, Some($descr1), Some($descr2)) + template!(@ false, Some($descr1), &[], Some($descr2)) }; (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => { - template!(@ true, Some($descr1), Some($descr2)) + template!(@ true, Some($descr1), &[], Some($descr2)) }; - (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate { - word: $word, list: $list, name_value_str: $name_value_str + (@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr) => { AttributeTemplate { + word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str } }; } @@ -478,7 +482,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, experimental!(no_sanitize) ), gated!( - coverage, Normal, template!(Word, List: "on|off"), + coverage, Normal, template!(OneOf: &[sym::off, sym::on]), ErrorPreceding, EncodeCrossCrate::No, coverage_attribute, experimental!(coverage) ), diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index bcb1131cc1961..3d5e6371f4ce6 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -4,8 +4,10 @@ use crate::{errors, parse_in}; use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; -use rustc_ast::MetaItemKind; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety}; +use rustc_ast::{ + self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemKind, + NestedMetaItem, Safety, +}; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::{ AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP, @@ -184,9 +186,13 @@ pub(super) fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim /// Checks that the given meta-item is compatible with this `AttributeTemplate`. fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool { + let is_one_allowed_subword = |items: &[NestedMetaItem]| match items { + [item] => item.is_word() && template.one_of.iter().any(|&word| item.has_name(word)), + _ => false, + }; match meta { MetaItemKind::Word => template.word, - MetaItemKind::List(..) => template.list.is_some(), + MetaItemKind::List(items) => template.list.is_some() || is_one_allowed_subword(items), MetaItemKind::NameValue(lit) if lit.kind.is_str() => template.name_value_str.is_some(), MetaItemKind::NameValue(..) => false, } @@ -230,6 +236,7 @@ fn emit_malformed_attribute( if let Some(descr) = template.list { suggestions.push(format!("#{inner}[{name}({descr})]")); } + suggestions.extend(template.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]"))); if let Some(descr) = template.name_value_str { suggestions.push(format!("#{inner}[{name} = \"{descr}\"]")); } From b7c057c9b2a00558594b854a3d01211d1767cfc6 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 19 Jun 2024 17:11:27 +1000 Subject: [PATCH 3/4] coverage: Always error on `#[coverage(..)]` in unexpected places This upgrades some warnings to errors, and also catches cases where the attribute was silently ignored. --- compiler/rustc_passes/messages.ftl | 15 ++------- compiler/rustc_passes/src/check_attr.rs | 42 +++---------------------- compiler/rustc_passes/src/errors.rs | 16 ++-------- 3 files changed, 10 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 9a830b0f49bac..5a560325ab950 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -103,18 +103,9 @@ passes_continue_labeled_block = .label = labeled blocks cannot be `continue`'d .block_label = labeled block the `continue` points to -passes_coverage_fn_defn = - `#[coverage]` may only be applied to function definitions - -passes_coverage_ignored_function_prototype = - `#[coverage]` is ignored on function prototypes - -passes_coverage_not_coverable = - `#[coverage]` must be applied to coverable code - .label = not coverable code - -passes_coverage_propagate = - `#[coverage]` does not propagate into items and must be applied to the contained functions directly +passes_coverage_not_fn_or_closure = + attribute should be applied to a function definition or closure + .label = not a function or closure passes_dead_codes = { $multiple -> diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2ed5bba85c60b..d33f12a973fdc 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -122,7 +122,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_unimplemented(attr.span, hir_id, target) } [sym::inline] => self.check_inline(hir_id, attr, span, target), - [sym::coverage] => self.check_coverage(hir_id, attr, span, target), + [sym::coverage] => self.check_coverage(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::target_feature] => { @@ -369,47 +369,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if a `#[coverage]` is applied directly to a function - fn check_coverage(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks that `#[coverage(..)]` is applied to a function or closure. + fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool { match target { - // #[coverage] on function is fine + // #[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.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoverageFnProto, - ); - true - } - - Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoveragePropagate, - ); - true - } - - Target::Expression | Target::Statement | Target::Arm => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredCoverageFnDefn, - ); - true - } - _ => { - self.dcx().emit_err(errors::IgnoredCoverageNotCoverable { + self.dcx().emit_err(errors::CoverageNotFnOrClosure { attr_span: attr.span, defn_span: span, }); diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f05965680920a..7734dba367046 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -60,21 +60,9 @@ pub struct InlineNotFnOrClosure { pub defn_span: Span, } -#[derive(LintDiagnostic)] -#[diag(passes_coverage_ignored_function_prototype)] -pub struct IgnoredCoverageFnProto; - -#[derive(LintDiagnostic)] -#[diag(passes_coverage_propagate)] -pub struct IgnoredCoveragePropagate; - -#[derive(LintDiagnostic)] -#[diag(passes_coverage_fn_defn)] -pub struct IgnoredCoverageFnDefn; - #[derive(Diagnostic)] -#[diag(passes_coverage_not_coverable, code = E0788)] -pub struct IgnoredCoverageNotCoverable { +#[diag(passes_coverage_not_fn_or_closure, code = E0788)] +pub struct CoverageNotFnOrClosure { #[primary_span] pub attr_span: Span, #[label] From 1852141219b39b2a6bb13ad273c96371d58a41e0 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 20 Jun 2024 18:13:48 +1000 Subject: [PATCH 4/4] coverage: Bless coverage attribute tests --- tests/ui/coverage-attr/bad-syntax.rs | 39 ++-- tests/ui/coverage-attr/bad-syntax.stderr | 137 ++++++++--- tests/ui/coverage-attr/name-value.rs | 51 ++-- tests/ui/coverage-attr/name-value.stderr | 194 ++++++++++------ tests/ui/coverage-attr/no-coverage.rs | 30 +-- tests/ui/coverage-attr/no-coverage.stderr | 103 +++++---- tests/ui/coverage-attr/subword.rs | 8 +- tests/ui/coverage-attr/subword.stderr | 36 ++- tests/ui/coverage-attr/word-only.rs | 45 ++-- tests/ui/coverage-attr/word-only.stderr | 270 ++++++++++++++++++++-- 10 files changed, 648 insertions(+), 265 deletions(-) diff --git a/tests/ui/coverage-attr/bad-syntax.rs b/tests/ui/coverage-attr/bad-syntax.rs index 127179877e55a..c8c92de8c380f 100644 --- a/tests/ui/coverage-attr/bad-syntax.rs +++ b/tests/ui/coverage-attr/bad-syntax.rs @@ -1,58 +1,45 @@ #![feature(coverage_attribute)] +//@ edition: 2021 // Tests the error messages produced (or not produced) by various unusual // uses of the `#[coverage(..)]` attribute. -// FIXME(#126658): Multiple coverage attributes with the same value are useless, -// and should probably produce a diagnostic. -#[coverage(off)] +#[coverage(off)] //~ ERROR multiple `coverage` attributes #[coverage(off)] fn multiple_consistent() {} -// FIXME(#126658): When there are multiple inconsistent coverage attributes, -// it's unclear which one will prevail. -#[coverage(off)] +#[coverage(off)] //~ ERROR multiple `coverage` attributes #[coverage(on)] fn multiple_inconsistent() {} -#[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage] //~ ERROR malformed `coverage` attribute input fn bare_word() {} -// FIXME(#126658): This shows as multiple different errors, one of which suggests -// writing bare `#[coverage]`, which is not allowed. -#[coverage = true] -//~^ ERROR expected `coverage(off)` or `coverage(on)` -//~| ERROR malformed `coverage` attribute input -//~| HELP the following are the possible correct uses -//~| SUGGESTION #[coverage(on|off)] +#[coverage = true] //~ ERROR malformed `coverage` attribute input fn key_value() {} -#[coverage()] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage()] //~ ERROR malformed `coverage` attribute input fn list_empty() {} -#[coverage(off, off)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(off, off)] //~ ERROR malformed `coverage` attribute input fn list_consistent() {} -#[coverage(off, on)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(off, on)] //~ ERROR malformed `coverage` attribute input fn list_inconsistent() {} -#[coverage(bogus)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(bogus)] //~ ERROR malformed `coverage` attribute input fn bogus_word() {} -#[coverage(bogus, off)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(bogus, off)] //~ ERROR malformed `coverage` attribute input fn bogus_word_before() {} -#[coverage(off, bogus)] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(off, bogus)] //~ ERROR malformed `coverage` attribute input fn bogus_word_after() {} -#[coverage(off,)] +#[coverage(off,)] // (OK!) fn comma_after() {} -// FIXME(#126658): This shows as multiple different errors. -#[coverage(,off)] -//~^ ERROR expected identifier, found `,` -//~| HELP remove this comma -//~| ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(,off)] //~ ERROR expected identifier, found `,` fn comma_before() {} fn main() {} diff --git a/tests/ui/coverage-attr/bad-syntax.stderr b/tests/ui/coverage-attr/bad-syntax.stderr index f6181d12a9466..a5868fcf19cff 100644 --- a/tests/ui/coverage-attr/bad-syntax.stderr +++ b/tests/ui/coverage-attr/bad-syntax.stderr @@ -1,78 +1,139 @@ error: malformed `coverage` attribute input - --> $DIR/bad-syntax.rs:23:1 - | -LL | #[coverage = true] - | ^^^^^^^^^^^^^^^^^^ - | -help: the following are the possible correct uses - | -LL | #[coverage(on|off)] + --> $DIR/bad-syntax.rs:15:1 | LL | #[coverage] + | ^^^^^^^^^^^ | - -error: expected identifier, found `,` - --> $DIR/bad-syntax.rs:52:12 +help: the following are the possible correct uses | -LL | #[coverage(,off)] - | ^ - | | - | expected identifier - | help: remove this comma +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:18:1 | -LL | #[coverage] - | ^^^^^^^^^^^ - -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:23:1 - | LL | #[coverage = true] | ^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:30:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:21:1 | LL | #[coverage()] | ^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:33:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:24:1 | LL | #[coverage(off, off)] | ^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:36:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:27:1 | LL | #[coverage(off, on)] | ^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:39:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:30:1 | LL | #[coverage(bogus)] | ^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:42:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:33:1 | LL | #[coverage(bogus, off)] | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:45:1 +error: malformed `coverage` attribute input + --> $DIR/bad-syntax.rs:36:1 | LL | #[coverage(off, bogus)] | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/bad-syntax.rs:52:1 +error: expected identifier, found `,` + --> $DIR/bad-syntax.rs:42:12 | LL | #[coverage(,off)] - | ^^^^^^^^^^^^^^^^^ + | ^ + | | + | expected identifier + | help: remove this comma + +error: multiple `coverage` attributes + --> $DIR/bad-syntax.rs:7:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/bad-syntax.rs:8:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ + +error: multiple `coverage` attributes + --> $DIR/bad-syntax.rs:11:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/bad-syntax.rs:12:1 + | +LL | #[coverage(on)] + | ^^^^^^^^^^^^^^^ error: aborting due to 11 previous errors diff --git a/tests/ui/coverage-attr/name-value.rs b/tests/ui/coverage-attr/name-value.rs index 24c329780c59c..cfd78a03e438a 100644 --- a/tests/ui/coverage-attr/name-value.rs +++ b/tests/ui/coverage-attr/name-value.rs @@ -8,57 +8,62 @@ // and in places that cannot have a coverage attribute, to demonstrate the // interaction between multiple errors. -// FIXME(#126658): The error messages for using this syntax are inconsistent -// with the error message in other cases. They also sometimes appear together -// with other errors, and they suggest using the incorrect `#[coverage]` syntax. - -#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +#[coverage = "off"] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure mod my_mod {} mod my_mod_inner { - #![coverage = "off"] //~ ERROR malformed `coverage` attribute input + #![coverage = "off"] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure } #[coverage = "off"] -//~^ ERROR `#[coverage]` must be applied to coverable code -//~| ERROR malformed `coverage` attribute input +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure struct MyStruct; -#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +#[coverage = "off"] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure impl MyStruct { #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32 = 7; } -#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +#[coverage = "off"] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure trait MyTrait { #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32; #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure type T; } -#[coverage = "off"] //~ ERROR malformed `coverage` attribute input +#[coverage = "off"] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure impl MyTrait for MyStruct { #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32 = 8; #[coverage = "off"] - //~^ ERROR `#[coverage]` must be applied to coverable code - //~| ERROR malformed `coverage` attribute input + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure type T = (); } #[coverage = "off"] -//~^ ERROR expected `coverage(off)` or `coverage(on)` -//~| ERROR malformed `coverage` attribute input +//~^ ERROR malformed `coverage` attribute input fn main() {} diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr index 90bc3a3b53b3e..caac687c94d01 100644 --- a/tests/ui/coverage-attr/name-value.stderr +++ b/tests/ui/coverage-attr/name-value.stderr @@ -1,28 +1,28 @@ error: malformed `coverage` attribute input - --> $DIR/name-value.rs:15:1 + --> $DIR/name-value.rs:11:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~ -LL | #[coverage] - | ~~~~~~~~~~~ +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:19:5 + --> $DIR/name-value.rs:17:5 | LL | #![coverage = "off"] | ^^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #![coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~~ -LL | #![coverage] - | ~~~~~~~~~~~~ +LL | #![coverage(off)] + | +LL | #![coverage(on)] + | error: malformed `coverage` attribute input --> $DIR/name-value.rs:22:1 @@ -32,22 +32,22 @@ LL | #[coverage = "off"] | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:29:5 + --> $DIR/name-value.rs:31:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input @@ -58,162 +58,220 @@ LL | #[coverage = "off"] | help: the following are the possible correct uses | -LL | #[coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~ -LL | #[coverage] - | ~~~~~~~~~~~ +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:37:5 + --> $DIR/name-value.rs:41:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:42:5 + --> $DIR/name-value.rs:46:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:35:1 + --> $DIR/name-value.rs:37:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~ -LL | #[coverage] - | ~~~~~~~~~~~ +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:50:5 + --> $DIR/name-value.rs:56:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:55:5 + --> $DIR/name-value.rs:61:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:48:1 + --> $DIR/name-value.rs:52:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] - | ~~~~~~~~~~~~~~~~~~~ -LL | #[coverage] - | ~~~~~~~~~~~ +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | error: malformed `coverage` attribute input - --> $DIR/name-value.rs:61:1 + --> $DIR/name-value.rs:67:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | help: the following are the possible correct uses | -LL | #[coverage(on|off)] +LL | #[coverage(off)] | -LL | #[coverage] +LL | #[coverage(on)] + | + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:11:1 | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | mod my_mod {} + | ------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:17:5 + | +LL | / mod my_mod_inner { +LL | | #![coverage = "off"] + | | ^^^^^^^^^^^^^^^^^^^^ +LL | | +LL | | +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure --> $DIR/name-value.rs:22:1 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | struct MyStruct; - | ---------------- not coverable code + | ---------------- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:27:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | / impl MyStruct { +LL | | #[coverage = "off"] +LL | | +LL | | +LL | | const X: u32 = 7; +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:37:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | / trait MyTrait { +LL | | #[coverage = "off"] +LL | | +LL | | +... | +LL | | type T; +LL | | } + | |_- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:37:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:52:1 + | +LL | #[coverage = "off"] + | ^^^^^^^^^^^^^^^^^^^ +... +LL | / impl MyTrait for MyStruct { +LL | | #[coverage = "off"] +LL | | +LL | | +... | +LL | | type T = (); +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:41:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | const X: u32; - | ------------- not coverable code + | ------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:42:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:46:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | type T; - | ------- not coverable code + | ------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:29:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:31:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | const X: u32 = 7; - | ----------------- not coverable code + | ----------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:50:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:56:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | const X: u32 = 8; - | ----------------- not coverable code + | ----------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/name-value.rs:55:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/name-value.rs:61:5 | LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ ... LL | type T = (); - | ------------ not coverable code - -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/name-value.rs:61:1 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ------------ not a function or closure -error: aborting due to 19 previous errors +error: aborting due to 23 previous errors For more information about this error, try `rustc --explain E0788`. diff --git a/tests/ui/coverage-attr/no-coverage.rs b/tests/ui/coverage-attr/no-coverage.rs index 907d25d333e20..5290fccca6100 100644 --- a/tests/ui/coverage-attr/no-coverage.rs +++ b/tests/ui/coverage-attr/no-coverage.rs @@ -2,54 +2,48 @@ #![feature(coverage_attribute)] #![feature(impl_trait_in_assoc_type)] #![warn(unused_attributes)] -#![coverage(off)] -//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly +#![coverage(off)] //~ ERROR attribute should be applied to a function definition or closure -#[coverage(off)] -//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly +#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure trait Trait { - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure const X: u32; - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure type T; type U; } -#[coverage(off)] -//~^ WARN: `#[coverage]` does not propagate into items and must be applied to the contained functions directly +#[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure impl Trait for () { const X: u32 = 0; - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure type T = Self; - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure type U = impl Trait; //~ ERROR unconstrained opaque type } extern "C" { - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure static X: u32; - #[coverage(off)] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure type T; } #[coverage(off)] fn main() { - #[coverage(off)] - //~^ WARN `#[coverage]` may only be applied to function definitions + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure let _ = (); match () { - #[coverage(off)] - //~^ WARN `#[coverage]` may only be applied to function definitions + #[coverage(off)] //~ ERROR attribute should be applied to a function definition or closure () => (), } - #[coverage(off)] - //~^ WARN `#[coverage]` may only be applied to function definitions + #[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 index a87b0fb49f00e..c5e3b0922cb42 100644 --- a/tests/ui/coverage-attr/no-coverage.stderr +++ b/tests/ui/coverage-attr/no-coverage.stderr @@ -1,101 +1,116 @@ -warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly - --> $DIR/no-coverage.rs:8:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/no-coverage.rs:4:9 - | -LL | #![warn(unused_attributes)] - | ^^^^^^^^^^^^^^^^^ +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:7:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ +LL | / trait Trait { +LL | | #[coverage(off)] +LL | | const X: u32; +... | +LL | | type U; +LL | | } + | |_- not a function or closure -warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly - --> $DIR/no-coverage.rs:20:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:18:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ +LL | / impl Trait for () { +LL | | const X: u32 = 0; +LL | | +LL | | #[coverage(off)] +... | +LL | | type U = impl Trait; +LL | | } + | |_- not a function or closure -warning: `#[coverage]` may only be applied to function definitions - --> $DIR/no-coverage.rs:42:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:39:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ +LL | let _ = (); + | ----------- not a function or closure -warning: `#[coverage]` may only be applied to function definitions - --> $DIR/no-coverage.rs:47:9 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:43:9 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ +LL | () => (), + | -------- not a function or closure -warning: `#[coverage]` may only be applied to function definitions - --> $DIR/no-coverage.rs:52:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:47:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ +LL | return (); + | --------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:11:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:9:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | const X: u32; - | ------------- not coverable code + | ------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:14:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:12:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | type T; - | ------- not coverable code + | ------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:25:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:22:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | type T = Self; - | -------------- not coverable code + | -------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:28:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:25:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | type U = impl Trait; - | -------------------- not coverable code + | -------------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:33:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:30:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | static X: u32; - | -------------- not coverable code + | -------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/no-coverage.rs:36:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/no-coverage.rs:33:5 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ LL | type T; - | ------- not coverable code + | ------- not a function or closure -warning: `#[coverage]` does not propagate into items and must be applied to the contained functions directly +error[E0788]: attribute should be applied to a function definition or closure --> $DIR/no-coverage.rs:5:1 | LL | #![coverage(off)] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ not a function or closure error: unconstrained opaque type - --> $DIR/no-coverage.rs:29:14 + --> $DIR/no-coverage.rs:26: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 7 previous errors; 6 warnings emitted +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0788`. diff --git a/tests/ui/coverage-attr/subword.rs b/tests/ui/coverage-attr/subword.rs index 98b8c25113cbf..16582240b6908 100644 --- a/tests/ui/coverage-attr/subword.rs +++ b/tests/ui/coverage-attr/subword.rs @@ -4,16 +4,16 @@ // Check that yes/no in `#[coverage(yes)]` and `#[coverage(no)]` must be bare // words, not part of a more complicated substructure. -#[coverage(yes(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(yes(milord))] //~ ERROR malformed `coverage` attribute input fn yes_list() {} -#[coverage(no(milord))] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(no(milord))] //~ ERROR malformed `coverage` attribute input fn no_list() {} -#[coverage(yes = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(yes = "milord")] //~ ERROR malformed `coverage` attribute input fn yes_key() {} -#[coverage(no = "milord")] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage(no = "milord")] //~ ERROR malformed `coverage` attribute input fn no_key() {} fn main() {} diff --git a/tests/ui/coverage-attr/subword.stderr b/tests/ui/coverage-attr/subword.stderr index 561573b8ada64..3a106898f8b9c 100644 --- a/tests/ui/coverage-attr/subword.stderr +++ b/tests/ui/coverage-attr/subword.stderr @@ -1,26 +1,54 @@ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/subword.rs:7:1 | LL | #[coverage(yes(milord))] | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/subword.rs:10:1 | LL | #[coverage(no(milord))] | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/subword.rs:13:1 | LL | #[coverage(yes = "milord")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ -error: expected `coverage(off)` or `coverage(on)` +error: malformed `coverage` attribute input --> $DIR/subword.rs:16:1 | LL | #[coverage(no = "milord")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | ~~~~~~~~~~~~~~~~ +LL | #[coverage(on)] + | ~~~~~~~~~~~~~~~ error: aborting due to 4 previous errors diff --git a/tests/ui/coverage-attr/word-only.rs b/tests/ui/coverage-attr/word-only.rs index 5c723b1b6b61e..0a61d1e709f51 100644 --- a/tests/ui/coverage-attr/word-only.rs +++ b/tests/ui/coverage-attr/word-only.rs @@ -8,47 +8,62 @@ // and in places that cannot have a coverage attribute, to demonstrate the // interaction between multiple errors. -// FIXME(#126658): The error messages for using this syntax give the impression -// that it is legal, even though it should never be legal. - -// FIXME(#126658): This is silently allowed, but should not be. #[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure mod my_mod {} -// FIXME(#126658): This is silently allowed, but should not be. mod my_mod_inner { #![coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure } -#[coverage] //~ ERROR `#[coverage]` must be applied to coverable code +#[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure struct MyStruct; -// FIXME(#126658): This is silently allowed, but should not be. #[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure impl MyStruct { - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32 = 7; } -// FIXME(#126658): This is silently allowed, but should not be. #[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure trait MyTrait { - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32; - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure type T; } -// FIXME(#126658): This is silently allowed, but should not be. #[coverage] +//~^ ERROR malformed `coverage` attribute input +//~| ERROR attribute should be applied to a function definition or closure impl MyTrait for MyStruct { - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure const X: u32 = 8; - #[coverage] //~ ERROR `#[coverage]` must be applied to coverable code + #[coverage] + //~^ ERROR malformed `coverage` attribute input + //~| ERROR attribute should be applied to a function definition or closure type T = (); } -#[coverage] //~ ERROR expected `coverage(off)` or `coverage(on)` +#[coverage] +//~^ ERROR malformed `coverage` attribute input fn main() {} diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr index bcafc23bc8d7d..18b5fed748476 100644 --- a/tests/ui/coverage-attr/word-only.stderr +++ b/tests/ui/coverage-attr/word-only.stderr @@ -1,57 +1,277 @@ -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:23:1 +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:11:1 | LL | #[coverage] | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:17:5 + | +LL | #![coverage] + | ^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #![coverage(off)] + | +LL | #![coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:22:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:31:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:27:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:41:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:46:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:37:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:56:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:61:5 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:52:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error: malformed `coverage` attribute input + --> $DIR/word-only.rs:67:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +LL | #[coverage(on)] + | + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:11:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... +LL | mod my_mod {} + | ------------- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:17:5 + | +LL | / mod my_mod_inner { +LL | | #![coverage] + | | ^^^^^^^^^^^^ +LL | | +LL | | +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:22:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... LL | struct MyStruct; - | ---------------- not coverable code + | ---------------- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:27:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... +LL | / impl MyStruct { +LL | | #[coverage] +LL | | +LL | | +LL | | const X: u32 = 7; +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:37:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... +LL | / trait MyTrait { +LL | | #[coverage] +LL | | +LL | | +... | +LL | | type T; +LL | | } + | |_- not a function or closure + +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:52:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ +... +LL | / impl MyTrait for MyStruct { +LL | | #[coverage] +LL | | +LL | | +... | +LL | | type T = (); +LL | | } + | |_- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:36:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:41:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | const X: u32; - | ------------- not coverable code + | ------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:39:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:46:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | type T; - | ------- not coverable code + | ------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:29:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:31:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | const X: u32 = 7; - | ----------------- not coverable code + | ----------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:46:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:56:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | const X: u32 = 8; - | ----------------- not coverable code + | ----------------- not a function or closure -error[E0788]: `#[coverage]` must be applied to coverable code - --> $DIR/word-only.rs:49:5 +error[E0788]: attribute should be applied to a function definition or closure + --> $DIR/word-only.rs:61:5 | LL | #[coverage] | ^^^^^^^^^^^ +... LL | type T = (); - | ------------ not coverable code - -error: expected `coverage(off)` or `coverage(on)` - --> $DIR/word-only.rs:53:1 - | -LL | #[coverage] - | ^^^^^^^^^^^ + | ------------ not a function or closure -error: aborting due to 7 previous errors +error: aborting due to 23 previous errors For more information about this error, try `rustc --explain E0788`.