passes: migrate half of check_attr

Migrate half of the `rustc_passes::check_attr` diagnostics to using
diagnostic derives and being translatable.
This commit is contained in:
David Wood 2022-07-11 18:59:04 +01:00
parent 81cf2294b4
commit 78b19a90b7
27 changed files with 844 additions and 524 deletions

View file

@ -4239,6 +4239,7 @@ dependencies = [
"rustc_hir", "rustc_hir",
"rustc_index", "rustc_index",
"rustc_lexer", "rustc_lexer",
"rustc_macros",
"rustc_middle", "rustc_middle",
"rustc_serialize", "rustc_serialize",
"rustc_session", "rustc_session",

View file

@ -0,0 +1,151 @@
-passes-previously-accepted =
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-passes-see-issue =
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
passes-outer-crate-level-attr =
crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
passes-inner-crate-level-attr =
crate-level attribute should be in the root module
passes-ignored-attr-with-macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
.warn = {-passes-previously-accepted}
.note = {-passes-see-issue(issue: "80564")}
passes-ignored-attr = `#[{$sym}]` is ignored on struct fields and match arms
.warn = {-passes-previously-accepted}
.note = {-passes-see-issue(issue: "80564")}
passes-inline-ignored-function-prototype = `#[inline]` is ignored on function prototypes
passes-inline-ignored-constants = `#[inline]` is ignored on constants
.warn = {-passes-previously-accepted}
.note = {-passes-see-issue(issue: "65833")}
passes-inline-not-fn-or-closure = attribute should be applied to function or closure
.label = not a function or closure
passes-no-coverage-ignored-function-prototype = `#[no_coverage]` is ignored on function prototypes
passes-no-coverage-propagate =
`#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
passes-no-coverage-fn-defn = `#[no_coverage]` may only be applied to function definitions
passes-no-coverage-not-coverable = `#[no_coverage]` must be applied to coverable code
.label = not coverable code
passes-should-be-applied-to-fn = attribute should be applied to a function definition
.label = not a function definition
passes-naked-tracked-caller = cannot use `#[track_caller]` with `#[naked]`
passes-should-be-applied-to-struct-enum = attribute should be applied to a struct or enum
.label = not a struct or enum
passes-should-be-applied-to-trait = attribute should be applied to a trait
.label = not a trait
passes-target-feature-on-statement = {passes-should-be-applied-to-fn}
.warn = {-passes-previously-accepted}
.label = {passes-should-be-applied-to-fn.label}
passes-should-be-applied-to-static = attribute should be applied to a static
.label = not a static
passes-doc-expect-str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
passes-doc-alias-empty = {$attr_str} attribute cannot have empty value
passes-doc-alias-bad-char = {$char_} character isn't allowed in {$attr_str}
passes-doc-alias-start-end = {$attr_str} cannot start or end with ' '
passes-doc-alias-bad-location = {$attr_str} isn't allowed on {$location}
passes-doc-alias-not-an-alias = {$attr_str} is the same as the item's name
passes-doc-alias-duplicated = doc alias is duplicated
.label = first defined here
passes-doc-alias-not-string-literal = `#[doc(alias("a"))]` expects string literals
passes-doc-alias-malformed =
doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]`
passes-doc-keyword-empty-mod = `#[doc(keyword = "...")]` should be used on empty modules
passes-doc-keyword-not-mod = `#[doc(keyword = "...")]` should be used on modules
passes-doc-keyword-invalid-ident = `{$doc_keyword}` is not a valid identifier
passes-doc-tuple-variadic-not-first =
`#[doc(tuple_variadic)]` must be used on the first of a set of tuple trait impls with varying arity
passes-doc-keyword-only-impl = `#[doc(keyword = "...")]` should be used on impl blocks
passes-doc-inline-conflict-first = this attribute...
passes-doc-inline-conflict-second = ...conflicts with this attribute
passes-doc-inline-conflict = conflicting doc inlining attributes
.help = remove one of the conflicting attributes
passes-doc-inline-only-use = this attribute can only be applied to a `use` item
.label = only applicable on `use` items
.not-a-use-item-label = not a `use` item
.note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
passes-doc-attr-not-crate-level =
`#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute
passes-attr-crate-level = this attribute can only be applied at the crate level
.suggestion = to apply to the crate, use an inner attribute
.help = to apply to the crate, use an inner attribute
.note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
passes-doc-test-unknown = unknown `doc(test)` attribute `{$path}`
passes-doc-test-takes-list = `#[doc(test(...)]` takes a list of attributes
passes-doc-primitive = `doc(primitive)` should never have been stable
passes-doc-test-unknown-any = unknown `doc` attribute `{$path}`
passes-doc-test-unknown-spotlight = unknown `doc` attribute `{$path}`
.note = `doc(spotlight)` was renamed to `doc(notable_trait)`
.suggestion = use `notable_trait` instead
.no-op-note = `doc(spotlight)` is now a no-op
passes-doc-test-unknown-include = unknown `doc` attribute `{$path}`
.suggestion = use `doc = include_str!` instead
passes-doc-invalid = invalid `doc` attribute
passes-pass-by-value = `pass_by_value` attribute should be applied to a struct, enum or type alias
.label = is not a struct, enum or type alias
passes-allow-incoherent-impl =
`rustc_allow_incoherent_impl` attribute should be applied to impl items.
.label = the only currently supported targets are inherent methods
passes-has-incoherent-inherent-impl =
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
.label = only adts, extern types and traits are supported
passes-must-use-async =
`must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
.label = this attribute does nothing, the `Future`s returned by async functions are already `must_use`
passes-must-use-no-effect = `#[must_use]` has no effect when applied to {$article} {$target}
passes-must-not-suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
.label = is not a struct, enum, or trait
passes-cold = {passes-should-be-applied-to-fn}
.warn = {-passes-previously-accepted}
.label = {passes-should-be-applied-to-fn.label}
passes-link = attribute should be applied to an `extern` block with non-Rust ABI
.warn = {-passes-previously-accepted}
.label = not an `extern` block

View file

@ -37,6 +37,7 @@ fluent_messages! {
expand => "../locales/en-US/expand.ftl", expand => "../locales/en-US/expand.ftl",
lint => "../locales/en-US/lint.ftl", lint => "../locales/en-US/lint.ftl",
parser => "../locales/en-US/parser.ftl", parser => "../locales/en-US/parser.ftl",
passes => "../locales/en-US/passes.ftl",
privacy => "../locales/en-US/privacy.ftl", privacy => "../locales/en-US/privacy.ftl",
typeck => "../locales/en-US/typeck.ftl", typeck => "../locales/en-US/typeck.ftl",
} }

View file

@ -64,6 +64,7 @@ into_diagnostic_arg_using_display!(
i128, i128,
u128, u128,
std::num::NonZeroU32, std::num::NonZeroU32,
hir::Target,
Edition, Edition,
Ident, Ident,
); );

View file

@ -15,6 +15,7 @@ rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" } rustc_index = { path = "../rustc_index" }
rustc_session = { path = "../rustc_session" } rustc_session = { path = "../rustc_session" }
rustc_target = { path = "../rustc_target" } rustc_target = { path = "../rustc_target" }
rustc_macros = { path = "../rustc_macros" }
rustc_ast = { path = "../rustc_ast" } rustc_ast = { path = "../rustc_ast" }
rustc_serialize = { path = "../rustc_serialize" } rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" } rustc_span = { path = "../rustc_span" }

View file

@ -4,9 +4,10 @@
//! conflicts between multiple such attributes attached to the same //! conflicts between multiple such attributes attached to the same
//! item. //! item.
use crate::errors;
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem}; use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; use rustc_errors::{fluent, pluralize, struct_span_err, Applicability, MultiSpan};
use rustc_expand::base::resolve_path; use rustc_expand::base::resolve_path;
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
use rustc_hir as hir; use rustc_hir as hir;
@ -175,16 +176,20 @@ impl CheckAttrVisitor<'_> {
if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) = if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) =
attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name))
{ {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { match attr.style {
let msg = match attr.style { ast::AttrStyle::Outer => self.tcx.emit_spanned_lint(
ast::AttrStyle::Outer => { UNUSED_ATTRIBUTES,
"crate-level attribute should be an inner attribute: add an exclamation \ hir_id,
mark: `#![foo]`" attr.span,
errors::OuterCrateLevelAttr,
),
ast::AttrStyle::Inner => self.tcx.emit_spanned_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr.span,
errors::InnerCrateLevelAttr,
),
} }
ast::AttrStyle::Inner => "crate-level attribute should be in the root module",
};
lint.build(msg).emit();
});
} }
} }
@ -209,37 +214,21 @@ impl CheckAttrVisitor<'_> {
} }
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build(&format!( UNUSED_ATTRIBUTES,
"`#[{sym}]` is ignored on struct fields, match arms and macro defs", hir_id,
)) attr.span,
.warn( errors::IgnoredAttrWithMacro { sym },
"this was previously accepted by the compiler but is \ );
being phased out; it will become a hard error in \
a future release!",
)
.note(
"see issue #80564 <https://github.com/rust-lang/rust/issues/80564> \
for more information",
)
.emit();
});
} }
fn inline_attr_str_error_without_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { fn inline_attr_str_error_without_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build(&format!("`#[{sym}]` is ignored on struct fields and match arms")) UNUSED_ATTRIBUTES,
.warn( hir_id,
"this was previously accepted by the compiler but is \ attr.span,
being phased out; it will become a hard error in \ errors::IgnoredAttr { sym },
a future release!", );
)
.note(
"see issue #80564 <https://github.com/rust-lang/rust/issues/80564> \
for more information",
)
.emit();
});
} }
/// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid.
@ -249,9 +238,12 @@ impl CheckAttrVisitor<'_> {
| Target::Closure | Target::Closure
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build("`#[inline]` is ignored on function prototypes").emit(); UNUSED_ATTRIBUTES,
}); hir_id,
attr.span,
errors::IgnoredInlineAttrFnProto,
);
true true
} }
// FIXME(#65833): We permit associated consts to have an `#[inline]` attribute with // FIXME(#65833): We permit associated consts to have an `#[inline]` attribute with
@ -259,19 +251,12 @@ impl CheckAttrVisitor<'_> {
// accidentally, to to be compatible with crates depending on them, we can't throw an // accidentally, to to be compatible with crates depending on them, we can't throw an
// error here. // error here.
Target::AssocConst => { Target::AssocConst => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build("`#[inline]` is ignored on constants") UNUSED_ATTRIBUTES,
.warn( hir_id,
"this was previously accepted by the compiler but is \ attr.span,
being phased out; it will become a hard error in \ errors::IgnoredInlineAttrConstants,
a future release!", );
)
.note(
"see issue #65833 <https://github.com/rust-lang/rust/issues/65833> \
for more information",
)
.emit();
});
true true
} }
// FIXME(#80564): Same for fields, arms, and macro defs // FIXME(#80564): Same for fields, arms, and macro defs
@ -280,14 +265,10 @@ impl CheckAttrVisitor<'_> {
true true
} }
_ => { _ => {
struct_span_err!( self.tcx.sess.emit_err(errors::InlineNotFnOrClosure {
self.tcx.sess, attr_span: attr.span,
attr.span, defn_span: span,
E0518, });
"attribute should be applied to function or closure",
)
.span_label(span, "not a function or closure")
.emit();
false false
} }
} }
@ -309,36 +290,40 @@ impl CheckAttrVisitor<'_> {
// function prototypes can't be covered // function prototypes can't be covered
Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build("`#[no_coverage]` is ignored on function prototypes").emit(); UNUSED_ATTRIBUTES,
}); hir_id,
attr.span,
errors::IgnoredNoCoverageFnProto,
);
true true
} }
Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => { Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build("`#[no_coverage]` does not propagate into items and must be applied to the contained functions directly").emit(); UNUSED_ATTRIBUTES,
}); hir_id,
attr.span,
errors::IgnoredNoCoveragePropagate,
);
true true
} }
Target::Expression | Target::Statement | Target::Arm => { Target::Expression | Target::Statement | Target::Arm => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build("`#[no_coverage]` may only be applied to function definitions") UNUSED_ATTRIBUTES,
.emit(); hir_id,
}); attr.span,
errors::IgnoredNoCoverageFnDefn,
);
true true
} }
_ => { _ => {
struct_span_err!( self.tcx.sess.emit_err(errors::IgnoredNoCoverageNotCoverable {
self.tcx.sess, attr_span: attr.span,
attr.span, defn_span: span,
E0788, });
"`#[no_coverage]` must be applied to coverable code",
)
.span_label(span, "not coverable code")
.emit();
false false
} }
} }
@ -389,14 +374,10 @@ impl CheckAttrVisitor<'_> {
true true
} }
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
.sess attr_span: attr.span,
.struct_span_err( defn_span: span,
attr.span, });
"attribute should be applied to a function definition",
)
.span_label(span, "not a function definition")
.emit();
false false
} }
} }
@ -408,14 +389,10 @@ impl CheckAttrVisitor<'_> {
Target::Fn Target::Fn
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
.sess attr_span: attr.span,
.struct_span_err( defn_span: span,
attr.span, });
"attribute should be applied to a function definition",
)
.span_label(span, "not a function definition")
.emit();
false false
} }
} }
@ -432,13 +409,7 @@ impl CheckAttrVisitor<'_> {
) -> bool { ) -> bool {
match target { match target {
_ if attrs.iter().any(|attr| attr.has_name(sym::naked)) => { _ if attrs.iter().any(|attr| attr.has_name(sym::naked)) => {
struct_span_err!( self.tcx.sess.emit_err(errors::NakedTrackedCaller { attr_span });
self.tcx.sess,
attr_span,
E0736,
"cannot use `#[track_caller]` with `#[naked]`",
)
.emit();
false false
} }
Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true, Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true,
@ -453,14 +424,9 @@ impl CheckAttrVisitor<'_> {
true true
} }
_ => { _ => {
struct_span_err!( self.tcx
self.tcx.sess, .sess
attr_span, .emit_err(errors::TrackedCallerWrongLocation { attr_span, defn_span: span });
E0739,
"attribute should be applied to function"
)
.span_label(span, "not a function")
.emit();
false false
} }
} }
@ -485,14 +451,10 @@ impl CheckAttrVisitor<'_> {
true true
} }
_ => { _ => {
struct_span_err!( self.tcx.sess.emit_err(errors::NonExhaustiveWrongLocation {
self.tcx.sess, attr_span: attr.span,
attr.span, defn_span: span,
E0701, });
"attribute can only be applied to a struct or enum"
)
.span_label(span, "not a struct or enum")
.emit();
false false
} }
} }
@ -511,11 +473,10 @@ impl CheckAttrVisitor<'_> {
true true
} }
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToTrait {
.sess attr_span: attr.span,
.struct_span_err(attr.span, "attribute can only be applied to a trait") defn_span: span,
.span_label(span, "not a trait") });
.emit();
false false
} }
} }
@ -531,11 +492,10 @@ impl CheckAttrVisitor<'_> {
match target { match target {
Target::Trait => true, Target::Trait => true,
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToTrait {
.sess attr_span: attr.span,
.struct_span_err(attr.span, "attribute can only be applied to a trait") defn_span: span,
.span_label(span, "not a trait") });
.emit();
false false
} }
} }
@ -555,16 +515,12 @@ impl CheckAttrVisitor<'_> {
// FIXME: #[target_feature] was previously erroneously allowed on statements and some // FIXME: #[target_feature] was previously erroneously allowed on statements and some
// crates used this, so only emit a warning. // crates used this, so only emit a warning.
Target::Statement => { Target::Statement => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build("attribute should be applied to a function") UNUSED_ATTRIBUTES,
.warn( hir_id,
"this was previously accepted by the compiler but is \ attr.span,
being phased out; it will become a hard error in \ errors::TargetFeatureOnStatement,
a future release!", );
)
.span_label(span, "not a function")
.emit();
});
true true
} }
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
@ -576,11 +532,10 @@ impl CheckAttrVisitor<'_> {
true true
} }
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
.sess attr_span: attr.span,
.struct_span_err(attr.span, "attribute should be applied to a function") defn_span: span,
.span_label(span, "not a function") });
.emit();
false false
} }
} }
@ -591,24 +546,17 @@ impl CheckAttrVisitor<'_> {
match target { match target {
Target::ForeignStatic | Target::Static => true, Target::ForeignStatic | Target::Static => true,
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToStatic {
.sess attr_span: attr.span,
.struct_span_err(attr.span, "attribute should be applied to a static") defn_span: span,
.span_label(span, "not a static") });
.emit();
false false
} }
} }
} }
fn doc_attr_str_error(&self, meta: &NestedMetaItem, attr_name: &str) { fn doc_attr_str_error(&self, meta: &NestedMetaItem, attr_name: &str) {
self.tcx self.tcx.sess.emit_err(errors::DocExpectStr { attr_span: meta.span(), attr_name });
.sess
.struct_span_err(
meta.span(),
&format!("doc {0} attribute expects a string: #[doc({0} = \"a\")]", attr_name),
)
.emit();
} }
fn check_doc_alias_value( fn check_doc_alias_value(
@ -621,22 +569,12 @@ impl CheckAttrVisitor<'_> {
aliases: &mut FxHashMap<String, Span>, aliases: &mut FxHashMap<String, Span>,
) -> bool { ) -> bool {
let tcx = self.tcx; let tcx = self.tcx;
let err_fn = move |span: Span, msg: &str| { let span = meta.name_value_literal_span().unwrap_or_else(|| meta.span());
tcx.sess.span_err( let attr_str =
span, &format!("`#[doc(alias{})]`", if is_list { "(\"...\")" } else { " = \"...\"" });
&format!(
"`#[doc(alias{})]` {}",
if is_list { "(\"...\")" } else { " = \"...\"" },
msg,
),
);
false
};
if doc_alias == kw::Empty { if doc_alias == kw::Empty {
return err_fn( tcx.sess.emit_err(errors::DocAliasEmpty { span, attr_str });
meta.name_value_literal_span().unwrap_or_else(|| meta.span()), return false;
"attribute cannot have empty value",
);
} }
let doc_alias_str = doc_alias.as_str(); let doc_alias_str = doc_alias.as_str();
@ -644,23 +582,16 @@ impl CheckAttrVisitor<'_> {
.chars() .chars()
.find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' ')) .find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' '))
{ {
self.tcx.sess.span_err( tcx.sess.emit_err(errors::DocAliasBadChar { span, attr_str, char_: c });
meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
&format!(
"{:?} character isn't allowed in `#[doc(alias{})]`",
c,
if is_list { "(\"...\")" } else { " = \"...\"" },
),
);
return false; return false;
} }
if doc_alias_str.starts_with(' ') || doc_alias_str.ends_with(' ') { if doc_alias_str.starts_with(' ') || doc_alias_str.ends_with(' ') {
return err_fn( tcx.sess.emit_err(errors::DocAliasStartEnd { span, attr_str });
meta.name_value_literal_span().unwrap_or_else(|| meta.span()), return false;
"cannot start or end with ' '",
);
} }
if let Some(err) = match target {
let span = meta.span();
if let Some(location) = match target {
Target::Impl => Some("implementation block"), Target::Impl => Some("implementation block"),
Target::ForeignMod => Some("extern block"), Target::ForeignMod => Some("extern block"),
Target::AssocTy => { Target::AssocTy => {
@ -686,19 +617,21 @@ impl CheckAttrVisitor<'_> {
Target::Param => return false, Target::Param => return false,
_ => None, _ => None,
} { } {
return err_fn(meta.span(), &format!("isn't allowed on {}", err)); tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location });
return false;
} }
let item_name = self.tcx.hir().name(hir_id); let item_name = self.tcx.hir().name(hir_id);
if item_name == doc_alias { if item_name == doc_alias {
return err_fn(meta.span(), "is the same as the item's name"); tcx.sess.emit_err(errors::DocAliasNotAnAlias { span, attr_str });
return false;
} }
let span = meta.span();
if let Err(entry) = aliases.try_insert(doc_alias_str.to_owned(), span) { if let Err(entry) = aliases.try_insert(doc_alias_str.to_owned(), span) {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, span, |lint| { self.tcx.emit_spanned_lint(
lint.build("doc alias is duplicated") UNUSED_ATTRIBUTES,
.span_label(*entry.entry.get(), "first defined here") hir_id,
.emit(); span,
}); errors::DocAliasDuplicated { first_defn: *entry.entry.get() },
);
} }
true true
} }
@ -723,22 +656,12 @@ impl CheckAttrVisitor<'_> {
_ => { _ => {
self.tcx self.tcx
.sess .sess
.struct_span_err( .emit_err(errors::DocAliasNotStringLiteral { span: v.span() });
v.span(),
"`#[doc(alias(\"a\"))]` expects string literals",
)
.emit();
errors += 1; errors += 1;
} }
}, },
None => { None => {
self.tcx self.tcx.sess.emit_err(errors::DocAliasNotStringLiteral { span: v.span() });
.sess
.struct_span_err(
v.span(),
"`#[doc(alias(\"a\"))]` expects string literals",
)
.emit();
errors += 1; errors += 1;
} }
} }
@ -747,14 +670,7 @@ impl CheckAttrVisitor<'_> {
} else if let Some(doc_alias) = meta.value_str() { } else if let Some(doc_alias) = meta.value_str() {
self.check_doc_alias_value(meta, doc_alias, hir_id, target, false, aliases) self.check_doc_alias_value(meta, doc_alias, hir_id, target, false, aliases)
} else { } else {
self.tcx self.tcx.sess.emit_err(errors::DocAliasMalformed { span: meta.span() });
.sess
.struct_span_err(
meta.span(),
"doc alias attribute expects a string `#[doc(alias = \"a\")]` or a list of \
strings `#[doc(alias(\"a\", \"b\"))]`",
)
.emit();
false false
} }
} }
@ -771,35 +687,20 @@ impl CheckAttrVisitor<'_> {
}) { }) {
Some(ItemKind::Mod(ref module)) => { Some(ItemKind::Mod(ref module)) => {
if !module.item_ids.is_empty() { if !module.item_ids.is_empty() {
self.tcx self.tcx.sess.emit_err(errors::DocKeywordEmptyMod { span: meta.span() });
.sess
.struct_span_err(
meta.span(),
"`#[doc(keyword = \"...\")]` can only be used on empty modules",
)
.emit();
return false; return false;
} }
} }
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::DocKeywordNotMod { span: meta.span() });
.sess
.struct_span_err(
meta.span(),
"`#[doc(keyword = \"...\")]` can only be used on modules",
)
.emit();
return false; return false;
} }
} }
if !rustc_lexer::is_ident(doc_keyword.as_str()) { if !rustc_lexer::is_ident(doc_keyword.as_str()) {
self.tcx self.tcx.sess.emit_err(errors::DocKeywordInvalidIdent {
.sess span: meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
.struct_span_err( doc_keyword,
meta.name_value_literal_span().unwrap_or_else(|| meta.span()), });
&format!("`{doc_keyword}` is not a valid identifier"),
)
.emit();
return false; return false;
} }
true true
@ -812,24 +713,12 @@ impl CheckAttrVisitor<'_> {
}) { }) {
Some(ItemKind::Impl(ref i)) => { Some(ItemKind::Impl(ref i)) => {
if !matches!(&i.self_ty.kind, hir::TyKind::Tup([_])) { if !matches!(&i.self_ty.kind, hir::TyKind::Tup([_])) {
self.tcx self.tcx.sess.emit_err(errors::DocTupleVariadicNotFirst { span: meta.span() });
.sess
.struct_span_err(
meta.span(),
"`#[doc(tuple_variadic)]` must be used on the first of a set of tuple trait impls with varying arity",
)
.emit();
return false; return false;
} }
} }
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::DocKeywordOnlyImpl { span: meta.span() });
.sess
.struct_span_err(
meta.span(),
"`#[doc(keyword = \"...\")]` can only be used on impl blocks",
)
.emit();
return false; return false;
} }
} }
@ -858,13 +747,9 @@ impl CheckAttrVisitor<'_> {
if let Some((prev_inline, prev_span)) = *specified_inline { if let Some((prev_inline, prev_span)) = *specified_inline {
if do_inline != prev_inline { if do_inline != prev_inline {
let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]); let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]);
spans.push_span_label(prev_span, "this attribute..."); spans.push_span_label(prev_span, fluent::passes::doc_inline_conflict_first);
spans.push_span_label(meta.span(), "...conflicts with this attribute"); spans.push_span_label(meta.span(), fluent::passes::doc_inline_conflict_second);
self.tcx self.tcx.sess.emit_err(errors::DocKeywordConflict { spans });
.sess
.struct_span_err(spans, "conflicting doc inlining attributes")
.help("remove one of the conflicting attributes")
.emit();
return false; return false;
} }
true true
@ -873,23 +758,14 @@ impl CheckAttrVisitor<'_> {
true true
} }
} else { } else {
self.tcx.struct_span_lint_hir( self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
meta.span(), meta.span(),
|lint| { errors::DocInlineOnlyUse {
let mut err = lint.build( attr_span: meta.span(),
"this attribute can only be applied to a `use` item", item_span: (attr.style == AttrStyle::Outer)
); .then(|| self.tcx.hir().span(hir_id)),
err.span_label(meta.span(), "only applicable on `use` items");
if attr.style == AttrStyle::Outer {
err.span_label(
self.tcx.hir().span(hir_id),
"not a `use` item",
);
}
err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information")
.emit();
}, },
); );
false false
@ -904,15 +780,7 @@ impl CheckAttrVisitor<'_> {
attr_name: &str, attr_name: &str,
) -> bool { ) -> bool {
if CRATE_HIR_ID == hir_id { if CRATE_HIR_ID == hir_id {
self.tcx self.tcx.sess.emit_err(errors::DocAttrNotCrateLevel { span: meta.span(), attr_name });
.sess
.struct_span_err(
meta.span(),
&format!(
"`#![doc({attr_name} = \"...\")]` isn't allowed as a crate-level attribute",
),
)
.emit();
return false; return false;
} }
true true
@ -926,36 +794,25 @@ impl CheckAttrVisitor<'_> {
hir_id: HirId, hir_id: HirId,
) -> bool { ) -> bool {
if hir_id != CRATE_HIR_ID { if hir_id != CRATE_HIR_ID {
self.tcx.struct_span_lint_hir( self.tcx.struct_span_lint_hir(INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), |lint| {
INVALID_DOC_ATTRIBUTES, let mut err = lint.build(fluent::passes::attr_crate_level);
hir_id, if attr.style == AttrStyle::Outer
meta.span(), && self.tcx.hir().get_parent_item(hir_id) == CRATE_DEF_ID
|lint| {
let mut err = lint.build(
"this attribute can only be applied at the crate level",
);
if attr.style == AttrStyle::Outer && self.tcx.hir().get_parent_item(hir_id) == CRATE_DEF_ID {
if let Ok(mut src) =
self.tcx.sess.source_map().span_to_snippet(attr.span)
{ {
if let Ok(mut src) = self.tcx.sess.source_map().span_to_snippet(attr.span) {
src.insert(1, '!'); src.insert(1, '!');
err.span_suggestion_verbose( err.span_suggestion_verbose(
attr.span, attr.span,
"to apply to the crate, use an inner attribute", fluent::passes::suggestion,
src, src,
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} else { } else {
err.span_help( err.span_help(attr.span, fluent::passes::help);
attr.span,
"to apply to the crate, use an inner attribute",
);
} }
} }
err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information") err.note(fluent::passes::note).emit();
.emit(); });
},
);
return false; return false;
} }
true true
@ -970,18 +827,14 @@ impl CheckAttrVisitor<'_> {
match i_meta.name_or_empty() { match i_meta.name_or_empty() {
sym::attr | sym::no_crate_inject => {} sym::attr | sym::no_crate_inject => {}
_ => { _ => {
self.tcx.struct_span_lint_hir( self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
i_meta.span(), i_meta.span(),
|lint| { errors::DocTestUnknown {
lint.build(&format!( path: rustc_ast_pretty::pprust::path_to_string(
"unknown `doc(test)` attribute `{}`", &i_meta.meta_item().unwrap().path,
rustc_ast_pretty::pprust::path_to_string(
&i_meta.meta_item().unwrap().path
), ),
))
.emit();
}, },
); );
is_valid = false; is_valid = false;
@ -989,9 +842,12 @@ impl CheckAttrVisitor<'_> {
} }
} }
} else { } else {
self.tcx.struct_span_lint_hir(INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), |lint| { self.tcx.emit_spanned_lint(
lint.build("`#[doc(test(...)]` takes a list of attributes").emit(); INVALID_DOC_ATTRIBUTES,
}); hir_id,
meta.span(),
errors::DocTestTakesList,
);
is_valid = false; is_valid = false;
} }
is_valid is_valid
@ -1093,79 +949,66 @@ impl CheckAttrVisitor<'_> {
sym::primitive => { sym::primitive => {
if !self.tcx.features().rustdoc_internals { if !self.tcx.features().rustdoc_internals {
self.tcx.struct_span_lint_hir( self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
i_meta.span, i_meta.span,
|lint| { errors::DocPrimitive,
let mut diag = lint.build(
"`doc(primitive)` should never have been stable",
);
diag.emit();
},
); );
} }
} }
_ => { _ => {
self.tcx.struct_span_lint_hir( let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path);
if i_meta.has_name(sym::spotlight) {
self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
i_meta.span, i_meta.span,
|lint| { errors::DocTestUnknownSpotlight {
let mut diag = lint.build(&format!( path,
"unknown `doc` attribute `{}`", span: i_meta.span
rustc_ast_pretty::pprust::path_to_string(&i_meta.path),
));
if i_meta.has_name(sym::spotlight) {
diag.note(
"`doc(spotlight)` was renamed to `doc(notable_trait)`",
);
diag.span_suggestion_short(
i_meta.span,
"use `notable_trait` instead",
"notable_trait",
Applicability::MachineApplicable,
);
diag.note("`doc(spotlight)` is now a no-op");
} }
if i_meta.has_name(sym::include) { );
if let Some(value) = i_meta.value_str() { } else if i_meta.has_name(sym::include) &&
// if there are multiple attributes, the suggestion would suggest deleting all of them, which is incorrect let Some(value) = i_meta.value_str() {
let applicability = if list.len() == 1 { let applicability = if list.len() == 1 {
Applicability::MachineApplicable Applicability::MachineApplicable
} else { } else {
Applicability::MaybeIncorrect Applicability::MaybeIncorrect
}; };
let inner = if attr.style == AttrStyle::Inner { // If there are multiple attributes, the suggestion would suggest
"!" // deleting all of them, which is incorrect.
self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES,
hir_id,
i_meta.span,
errors::DocTestUnknownInclude {
path,
value: value.to_string(),
inner: (attr.style == AttrStyle::Inner)
.then_some("!")
.unwrap_or(""),
sugg: (attr.meta().unwrap().span, applicability),
}
);
} else { } else {
"" self.tcx.emit_spanned_lint(
}; INVALID_DOC_ATTRIBUTES,
diag.span_suggestion( hir_id,
attr.meta().unwrap().span, i_meta.span,
"use `doc = include_str!` instead", errors::DocTestUnknownAny { path }
format!(
"#{inner}[doc = include_str!(\"{value}\")]",
),
applicability,
); );
} }
}
diag.emit();
},
);
is_valid = false; is_valid = false;
} }
} }
} else { } else {
self.tcx.struct_span_lint_hir( self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
hir_id, hir_id,
meta.span(), meta.span(),
|lint| { errors::DocInvalid,
lint.build("invalid `doc` attribute").emit();
},
); );
is_valid = false; is_valid = false;
} }
@ -1180,14 +1023,7 @@ impl CheckAttrVisitor<'_> {
match target { match target {
Target::Struct | Target::Enum | Target::TyAlias => true, Target::Struct | Target::Enum | Target::TyAlias => true,
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::PassByValue { attr_span: attr.span, span });
.sess
.struct_span_err(
attr.span,
"`pass_by_value` attribute should be applied to a struct, enum or type alias.",
)
.span_label(span, "is not a struct, enum or type alias")
.emit();
false false
} }
} }
@ -1197,14 +1033,7 @@ impl CheckAttrVisitor<'_> {
match target { match target {
Target::Method(MethodKind::Inherent) => true, Target::Method(MethodKind::Inherent) => true,
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::AllowIncoherentImpl { attr_span: attr.span, span });
.sess
.struct_span_err(
attr.span,
"`rustc_allow_incoherent_impl` attribute should be applied to impl items.",
)
.span_label(span, "the only currently supported targets are inherent methods")
.emit();
false false
} }
} }
@ -1223,12 +1052,7 @@ impl CheckAttrVisitor<'_> {
_ => { _ => {
self.tcx self.tcx
.sess .sess
.struct_span_err( .emit_err(errors::HasIncoherentInherentImpl { attr_span: attr.span, span });
attr.span,
"`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.",
)
.span_label(span, "only adts, extern types and traits are supported")
.emit();
false false
} }
} }
@ -1238,19 +1062,12 @@ impl CheckAttrVisitor<'_> {
fn check_must_use(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { fn check_must_use(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
let node = self.tcx.hir().get(hir_id); let node = self.tcx.hir().get(hir_id);
if let Some(kind) = node.fn_kind() && let rustc_hir::IsAsync::Async = kind.asyncness() { if let Some(kind) = node.fn_kind() && let rustc_hir::IsAsync::Async = kind.asyncness() {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build( UNUSED_ATTRIBUTES,
"`must_use` attribute on `async` functions \ hir_id,
applies to the anonymous `Future` returned by the \ attr.span,
function, not the value within", errors::MustUseAsync { span }
) );
.span_label(
span,
"this attribute does nothing, the `Future`s \
returned by async functions are already `must_use`",
)
.emit();
});
} }
if !matches!( if !matches!(
@ -1278,12 +1095,12 @@ impl CheckAttrVisitor<'_> {
_ => "a", _ => "a",
}; };
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build(&format!( UNUSED_ATTRIBUTES,
"`#[must_use]` has no effect when applied to {article} {target}" hir_id,
)) attr.span,
.emit(); errors::MustUseNoEffect { article, target },
}); );
} }
// For now, its always valid // For now, its always valid
@ -1295,11 +1112,7 @@ impl CheckAttrVisitor<'_> {
match target { match target {
Target::Struct | Target::Enum | Target::Union | Target::Trait => true, Target::Struct | Target::Enum | Target::Union | Target::Trait => true,
_ => { _ => {
self.tcx self.tcx.sess.emit_err(errors::MustNotSuspend { attr_span: attr.span, span });
.sess
.struct_span_err(attr.span, "`must_not_suspend` attribute should be applied to a struct, enum, or trait")
.span_label(span, "is not a struct, enum, or trait")
.emit();
false false
} }
} }
@ -1319,16 +1132,12 @@ impl CheckAttrVisitor<'_> {
_ => { _ => {
// FIXME: #[cold] was previously allowed on non-functions and some crates used // FIXME: #[cold] was previously allowed on non-functions and some crates used
// this, so only emit a warning. // this, so only emit a warning.
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
lint.build("attribute should be applied to a function") UNUSED_ATTRIBUTES,
.warn( hir_id,
"this was previously accepted by the compiler but is \ attr.span,
being phased out; it will become a hard error in \ errors::Cold { span },
a future release!", );
)
.span_label(span, "not a function")
.emit();
});
} }
} }
} }
@ -1343,19 +1152,12 @@ impl CheckAttrVisitor<'_> {
return; return;
} }
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.emit_spanned_lint(
let mut diag = UNUSED_ATTRIBUTES,
lint.build("attribute should be applied to an `extern` block with non-Rust ABI"); hir_id,
diag.warn( attr.span,
"this was previously accepted by the compiler but is \ errors::Link { span: (target != Target::ForeignMod).then_some(span) },
being phased out; it will become a hard error in \
a future release!",
); );
if target != Target::ForeignMod {
diag.span_label(span, "not an `extern` block");
}
diag.emit();
});
} }
/// Checks if `#[link_name]` is applied to an item other than a foreign function or static. /// Checks if `#[link_name]` is applied to an item other than a foreign function or static.

View file

@ -0,0 +1,362 @@
use rustc_errors::{Applicability, MultiSpan};
use rustc_macros::{LintDiagnostic, SessionDiagnostic};
use rustc_span::{Span, Symbol};
#[derive(LintDiagnostic)]
#[lint(passes::outer_crate_level_attr)]
pub struct OuterCrateLevelAttr;
#[derive(LintDiagnostic)]
#[lint(passes::inner_crate_level_attr)]
pub struct InnerCrateLevelAttr;
#[derive(LintDiagnostic)]
#[lint(passes::ignored_attr_with_macro)]
pub struct IgnoredAttrWithMacro<'a> {
pub sym: &'a str,
}
#[derive(LintDiagnostic)]
#[lint(passes::ignored_attr)]
pub struct IgnoredAttr<'a> {
pub sym: &'a str,
}
#[derive(LintDiagnostic)]
#[lint(passes::inline_ignored_function_prototype)]
pub struct IgnoredInlineAttrFnProto;
#[derive(LintDiagnostic)]
#[lint(passes::inline_ignored_constants)]
#[warn_]
#[note]
pub struct IgnoredInlineAttrConstants;
#[derive(SessionDiagnostic)]
#[error(passes::inline_not_fn_or_closure, code = "E0518")]
pub struct InlineNotFnOrClosure {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(LintDiagnostic)]
#[lint(passes::no_coverage_ignored_function_prototype)]
pub struct IgnoredNoCoverageFnProto;
#[derive(LintDiagnostic)]
#[lint(passes::no_coverage_propagate)]
pub struct IgnoredNoCoveragePropagate;
#[derive(LintDiagnostic)]
#[lint(passes::no_coverage_fn_defn)]
pub struct IgnoredNoCoverageFnDefn;
#[derive(SessionDiagnostic)]
#[error(passes::no_coverage_not_coverable, code = "E0788")]
pub struct IgnoredNoCoverageNotCoverable {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::should_be_applied_to_fn)]
pub struct AttrShouldBeAppliedToFn {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::naked_tracked_caller, code = "E0736")]
pub struct NakedTrackedCaller {
#[primary_span]
pub attr_span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::should_be_applied_to_fn, code = "E0739")]
pub struct TrackedCallerWrongLocation {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::should_be_applied_to_struct_enum, code = "E0701")]
pub struct NonExhaustiveWrongLocation {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::should_be_applied_to_trait)]
pub struct AttrShouldBeAppliedToTrait {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(LintDiagnostic)]
#[lint(passes::target_feature_on_statement)]
pub struct TargetFeatureOnStatement;
#[derive(SessionDiagnostic)]
#[error(passes::should_be_applied_to_static)]
pub struct AttrShouldBeAppliedToStatic {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_expect_str)]
pub struct DocExpectStr<'a> {
#[primary_span]
pub attr_span: Span,
pub attr_name: &'a str,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_alias_empty)]
pub struct DocAliasEmpty<'a> {
#[primary_span]
pub span: Span,
pub attr_str: &'a str,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_alias_bad_char)]
pub struct DocAliasBadChar<'a> {
#[primary_span]
pub span: Span,
pub attr_str: &'a str,
pub char_: char,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_alias_start_end)]
pub struct DocAliasStartEnd<'a> {
#[primary_span]
pub span: Span,
pub attr_str: &'a str,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_alias_bad_location)]
pub struct DocAliasBadLocation<'a> {
#[primary_span]
pub span: Span,
pub attr_str: &'a str,
pub location: &'a str,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_alias_not_an_alias)]
pub struct DocAliasNotAnAlias<'a> {
#[primary_span]
pub span: Span,
pub attr_str: &'a str,
}
#[derive(LintDiagnostic)]
#[lint(passes::doc_alias_duplicated)]
pub struct DocAliasDuplicated {
#[label]
pub first_defn: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_alias_not_string_literal)]
pub struct DocAliasNotStringLiteral {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_alias_malformed)]
pub struct DocAliasMalformed {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_keyword_empty_mod)]
pub struct DocKeywordEmptyMod {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_keyword_not_mod)]
pub struct DocKeywordNotMod {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_keyword_invalid_ident)]
pub struct DocKeywordInvalidIdent {
#[primary_span]
pub span: Span,
pub doc_keyword: Symbol,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_tuple_variadic_not_first)]
pub struct DocTupleVariadicNotFirst {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_keyword_only_impl)]
pub struct DocKeywordOnlyImpl {
#[primary_span]
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_inline_conflict)]
#[help]
pub struct DocKeywordConflict {
#[primary_span]
pub spans: MultiSpan,
}
#[derive(LintDiagnostic)]
#[lint(passes::doc_inline_only_use)]
#[note]
pub struct DocInlineOnlyUse {
#[label]
pub attr_span: Span,
#[label(passes::not_a_use_item_label)]
pub item_span: Option<Span>,
}
#[derive(SessionDiagnostic)]
#[error(passes::doc_attr_not_crate_level)]
pub struct DocAttrNotCrateLevel<'a> {
#[primary_span]
pub span: Span,
pub attr_name: &'a str,
}
#[derive(LintDiagnostic)]
#[lint(passes::doc_test_unknown)]
pub struct DocTestUnknown {
pub path: String,
}
#[derive(LintDiagnostic)]
#[lint(passes::doc_test_takes_list)]
pub struct DocTestTakesList;
#[derive(LintDiagnostic)]
#[lint(passes::doc_primitive)]
pub struct DocPrimitive;
#[derive(LintDiagnostic)]
#[lint(passes::doc_test_unknown_any)]
pub struct DocTestUnknownAny {
pub path: String,
}
#[derive(LintDiagnostic)]
#[lint(passes::doc_test_unknown_spotlight)]
#[note]
#[note(passes::no_op_note)]
pub struct DocTestUnknownSpotlight {
pub path: String,
#[suggestion_short(applicability = "machine-applicable", code = "notable_trait")]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[lint(passes::doc_test_unknown_include)]
pub struct DocTestUnknownInclude {
pub path: String,
pub value: String,
pub inner: &'static str,
#[suggestion(code = "#{inner}[doc = include_str!(\"{value}\")]")]
pub sugg: (Span, Applicability),
}
#[derive(LintDiagnostic)]
#[lint(passes::doc_invalid)]
pub struct DocInvalid;
#[derive(SessionDiagnostic)]
#[error(passes::pass_by_value)]
pub struct PassByValue {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::allow_incoherent_impl)]
pub struct AllowIncoherentImpl {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}
#[derive(SessionDiagnostic)]
#[error(passes::has_incoherent_inherent_impl)]
pub struct HasIncoherentInherentImpl {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[lint(passes::must_use_async)]
pub struct MustUseAsync {
#[label]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[lint(passes::must_use_no_effect)]
pub struct MustUseNoEffect {
pub article: &'static str,
pub target: rustc_hir::Target,
}
#[derive(SessionDiagnostic)]
#[error(passes::must_not_suspend)]
pub struct MustNotSuspend {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[lint(passes::cold)]
#[warn_]
pub struct Cold {
#[label]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[lint(passes::link)]
#[warn_]
pub struct Link {
#[label]
pub span: Option<Span>,
}

View file

@ -7,8 +7,8 @@
#![allow(rustc::potential_query_instability)] #![allow(rustc::potential_query_instability)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(iter_intersperse)] #![feature(iter_intersperse)]
#![feature(let_else)]
#![feature(let_chains)] #![feature(let_chains)]
#![feature(let_else)]
#![feature(map_try_insert)] #![feature(map_try_insert)]
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(try_blocks)] #![feature(try_blocks)]
@ -27,6 +27,7 @@ pub mod dead;
mod debugger_visualizer; mod debugger_visualizer;
mod diagnostic_items; mod diagnostic_items;
pub mod entry; pub mod entry;
mod errors;
pub mod hir_id_validator; pub mod hir_id_validator;
pub mod hir_stats; pub mod hir_stats;
mod lang_items; mod lang_items;

View file

@ -12,7 +12,7 @@ LL | #![deny(warnings)]
= note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
help: to apply to the crate, use an inner attribute help: to apply to the crate, use an inner attribute
| |
LL | #![doc(test(no_crate_inject))] LL | #![doc(test(no_crate_inject))]
@ -29,7 +29,7 @@ LL | pub fn foo() {}
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
error: this attribute can only be applied at the crate level error: this attribute can only be applied at the crate level
--> $DIR/invalid-doc-attr.rs:15:12 --> $DIR/invalid-doc-attr.rs:15:12
@ -39,7 +39,7 @@ LL | #![doc(test(no_crate_inject))]
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
error: conflicting doc inlining attributes error: conflicting doc inlining attributes
--> $DIR/invalid-doc-attr.rs:28:7 --> $DIR/invalid-doc-attr.rs:28:7
@ -59,7 +59,7 @@ LL | #[doc(test(no_crate_inject))]
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
error: this attribute can only be applied to a `use` item error: this attribute can only be applied to a `use` item
--> $DIR/invalid-doc-attr.rs:22:11 --> $DIR/invalid-doc-attr.rs:22:11
@ -72,7 +72,7 @@ LL | pub fn baz() {}
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -12,7 +12,7 @@ LL | #![deny(warnings)]
= note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
help: to apply to the crate, use an inner attribute help: to apply to the crate, use an inner attribute
| |
LL | #![doc(test(no_crate_inject))] LL | #![doc(test(no_crate_inject))]
@ -29,7 +29,7 @@ LL | pub fn foo() {}
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
error: this attribute can only be applied at the crate level error: this attribute can only be applied at the crate level
--> $DIR/invalid-doc-attr.rs:15:12 --> $DIR/invalid-doc-attr.rs:15:12
@ -39,7 +39,7 @@ LL | #![doc(test(no_crate_inject))]
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
error: conflicting doc inlining attributes error: conflicting doc inlining attributes
--> $DIR/invalid-doc-attr.rs:28:7 --> $DIR/invalid-doc-attr.rs:28:7
@ -59,7 +59,7 @@ LL | #[doc(test(no_crate_inject))]
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
error: this attribute can only be applied to a `use` item error: this attribute can only be applied to a `use` item
--> $DIR/invalid-doc-attr.rs:22:11 --> $DIR/invalid-doc-attr.rs:22:11
@ -72,7 +72,7 @@ LL | pub fn baz() {}
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -7,14 +7,14 @@ LL | #[inline]
LL | const FOO: u8 = 0; LL | const FOO: u8 = 0;
| ------------------ not a function or closure | ------------------ not a function or closure
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/multiple-invalid.rs:6:1 --> $DIR/multiple-invalid.rs:6:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | const FOO: u8 = 0; LL | const FOO: u8 = 0;
| ------------------ not a function | ------------------ not a function definition
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -259,7 +259,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation
LL | #[no_std] LL | #[no_std]
| ^^^^^^^^^ | ^^^^^^^^^
warning: attribute should be applied to a function warning: attribute should be applied to a function definition
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:453:1 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:453:1
| |
LL | #[cold] LL | #[cold]
@ -272,7 +272,7 @@ LL | | mod inner { #![cold] }
... | ... |
LL | | LL | |
LL | | } LL | | }
| |_- not a function | |_- not a function definition
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
@ -399,7 +399,7 @@ warning: `#[proc_macro_derive]` only has an effect on functions
LL | #![proc_macro_derive()] LL | #![proc_macro_derive()]
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
warning: attribute should be applied to a function warning: attribute should be applied to a function definition
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
| |
LL | #![cold] LL | #![cold]
@ -743,35 +743,35 @@ warning: crate-level attribute should be an inner attribute: add an exclamation
LL | #[no_std] impl S { } LL | #[no_std] impl S { }
| ^^^^^^^^^ | ^^^^^^^^^
warning: attribute should be applied to a function warning: attribute should be applied to a function definition
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:459:17 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:459:17
| |
LL | mod inner { #![cold] } LL | mod inner { #![cold] }
| ------------^^^^^^^^-- not a function | ------------^^^^^^^^-- not a function definition
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: attribute should be applied to a function warning: attribute should be applied to a function definition
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5
| |
LL | #[cold] struct S; LL | #[cold] struct S;
| ^^^^^^^ --------- not a function | ^^^^^^^ --------- not a function definition
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: attribute should be applied to a function warning: attribute should be applied to a function definition
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5
| |
LL | #[cold] type T = S; LL | #[cold] type T = S;
| ^^^^^^^ ----------- not a function | ^^^^^^^ ----------- not a function definition
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: attribute should be applied to a function warning: attribute should be applied to a function definition
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:5 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:5
| |
LL | #[cold] impl S { } LL | #[cold] impl S { }
| ^^^^^^^ ---------- not a function | ^^^^^^^ ---------- not a function definition
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!

View file

@ -22,7 +22,7 @@ LL | #![deny(future_incompatible)]
= note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(future_incompatible)]` = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(future_incompatible)]`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
error: aborting due to previous error; 1 warning emitted error: aborting due to previous error; 1 warning emitted

View file

@ -1,11 +1,11 @@
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/issue-54044.rs:3:1 --> $DIR/issue-54044.rs:3:1
| |
LL | #[cold] LL | #[cold]
| ^^^^^^^ | ^^^^^^^
... ...
LL | struct Foo; LL | struct Foo;
| ----------- not a function | ----------- not a function definition
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/issue-54044.rs:1:9 --> $DIR/issue-54044.rs:1:9
@ -14,14 +14,14 @@ LL | #![deny(unused_attributes)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/issue-54044.rs:9:5 --> $DIR/issue-54044.rs:9:5
| |
LL | #[cold] LL | #[cold]
| ^^^^^^^ | ^^^^^^^
... ...
LL | 5; LL | 5;
| - not a function | - not a function definition
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!

View file

@ -4,11 +4,11 @@ error[E0518]: attribute should be applied to function or closure
LL | pub struct Foo<#[inline] const N: usize>; LL | pub struct Foo<#[inline] const N: usize>;
| ^^^^^^^^^ -------------- not a function or closure | ^^^^^^^^^ -------------- not a function or closure
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/issue-78957.rs:7:16 --> $DIR/issue-78957.rs:7:16
| |
LL | pub struct Bar<#[cold] const N: usize>; LL | pub struct Bar<#[cold] const N: usize>;
| ^^^^^^^ -------------- not a function | ^^^^^^^ -------------- not a function definition
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/issue-78957.rs:1:9 --> $DIR/issue-78957.rs:1:9
@ -29,11 +29,11 @@ error[E0518]: attribute should be applied to function or closure
LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>);
| ^^^^^^^^^ -- not a function or closure | ^^^^^^^^^ -- not a function or closure
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/issue-78957.rs:15:17 --> $DIR/issue-78957.rs:15:17
| |
LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>);
| ^^^^^^^ -- not a function | ^^^^^^^ -- not a function definition
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
@ -49,11 +49,11 @@ error[E0518]: attribute should be applied to function or closure
LL | pub struct Foo3<#[inline] T>(PhantomData<T>); LL | pub struct Foo3<#[inline] T>(PhantomData<T>);
| ^^^^^^^^^ - not a function or closure | ^^^^^^^^^ - not a function or closure
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/issue-78957.rs:23:17 --> $DIR/issue-78957.rs:23:17
| |
LL | pub struct Bar3<#[cold] T>(PhantomData<T>); LL | pub struct Bar3<#[cold] T>(PhantomData<T>);
| ^^^^^^^ - not a function | ^^^^^^^ - not a function definition
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!

View file

@ -1,11 +1,11 @@
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/issue-68060.rs:4:13 --> $DIR/issue-68060.rs:4:13
| |
LL | #[target_feature(enable = "")] LL | #[target_feature(enable = "")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
... ...
LL | |_| (), LL | |_| (),
| ------ not a function | ------ not a function definition
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,23 +1,23 @@
#![feature(marker_trait_attr)] #![feature(marker_trait_attr)]
#[marker] //~ ERROR attribute can only be applied to a trait #[marker] //~ ERROR attribute should be applied to a trait
struct Struct {} struct Struct {}
#[marker] //~ ERROR attribute can only be applied to a trait #[marker] //~ ERROR attribute should be applied to a trait
impl Struct {} impl Struct {}
#[marker] //~ ERROR attribute can only be applied to a trait #[marker] //~ ERROR attribute should be applied to a trait
union Union { union Union {
x: i32, x: i32,
} }
#[marker] //~ ERROR attribute can only be applied to a trait #[marker] //~ ERROR attribute should be applied to a trait
const CONST: usize = 10; const CONST: usize = 10;
#[marker] //~ ERROR attribute can only be applied to a trait #[marker] //~ ERROR attribute should be applied to a trait
fn function() {} fn function() {}
#[marker] //~ ERROR attribute can only be applied to a trait #[marker] //~ ERROR attribute should be applied to a trait
type Type = (); type Type = ();
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
error: attribute can only be applied to a trait error: attribute should be applied to a trait
--> $DIR/marker-attribute-on-non-trait.rs:3:1 --> $DIR/marker-attribute-on-non-trait.rs:3:1
| |
LL | #[marker] LL | #[marker]
@ -6,7 +6,7 @@ LL | #[marker]
LL | struct Struct {} LL | struct Struct {}
| ---------------- not a trait | ---------------- not a trait
error: attribute can only be applied to a trait error: attribute should be applied to a trait
--> $DIR/marker-attribute-on-non-trait.rs:6:1 --> $DIR/marker-attribute-on-non-trait.rs:6:1
| |
LL | #[marker] LL | #[marker]
@ -14,7 +14,7 @@ LL | #[marker]
LL | impl Struct {} LL | impl Struct {}
| -------------- not a trait | -------------- not a trait
error: attribute can only be applied to a trait error: attribute should be applied to a trait
--> $DIR/marker-attribute-on-non-trait.rs:9:1 --> $DIR/marker-attribute-on-non-trait.rs:9:1
| |
LL | #[marker] LL | #[marker]
@ -24,7 +24,7 @@ LL | | x: i32,
LL | | } LL | | }
| |_- not a trait | |_- not a trait
error: attribute can only be applied to a trait error: attribute should be applied to a trait
--> $DIR/marker-attribute-on-non-trait.rs:14:1 --> $DIR/marker-attribute-on-non-trait.rs:14:1
| |
LL | #[marker] LL | #[marker]
@ -32,7 +32,7 @@ LL | #[marker]
LL | const CONST: usize = 10; LL | const CONST: usize = 10;
| ------------------------ not a trait | ------------------------ not a trait
error: attribute can only be applied to a trait error: attribute should be applied to a trait
--> $DIR/marker-attribute-on-non-trait.rs:17:1 --> $DIR/marker-attribute-on-non-trait.rs:17:1
| |
LL | #[marker] LL | #[marker]
@ -40,7 +40,7 @@ LL | #[marker]
LL | fn function() {} LL | fn function() {}
| ---------------- not a trait | ---------------- not a trait
error: attribute can only be applied to a trait error: attribute should be applied to a trait
--> $DIR/marker-attribute-on-non-trait.rs:20:1 --> $DIR/marker-attribute-on-non-trait.rs:20:1
| |
LL | #[marker] LL | #[marker]

View file

@ -3,11 +3,11 @@
struct Foo; struct Foo;
#[non_exhaustive] #[non_exhaustive]
//~^ ERROR attribute can only be applied to a struct or enum [E0701] //~^ ERROR attribute should be applied to a struct or enum [E0701]
trait Bar { } trait Bar { }
#[non_exhaustive] #[non_exhaustive]
//~^ ERROR attribute can only be applied to a struct or enum [E0701] //~^ ERROR attribute should be applied to a struct or enum [E0701]
union Baz { union Baz {
f1: u16, f1: u16,
f2: u16 f2: u16

View file

@ -4,7 +4,7 @@ error: malformed `non_exhaustive` attribute input
LL | #[non_exhaustive(anything)] LL | #[non_exhaustive(anything)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]`
error[E0701]: attribute can only be applied to a struct or enum error[E0701]: attribute should be applied to a struct or enum
--> $DIR/invalid-attribute.rs:5:1 --> $DIR/invalid-attribute.rs:5:1
| |
LL | #[non_exhaustive] LL | #[non_exhaustive]
@ -13,7 +13,7 @@ LL |
LL | trait Bar { } LL | trait Bar { }
| ------------- not a struct or enum | ------------- not a struct or enum
error[E0701]: attribute can only be applied to a struct or enum error[E0701]: attribute should be applied to a struct or enum
--> $DIR/invalid-attribute.rs:9:1 --> $DIR/invalid-attribute.rs:9:1
| |
LL | #[non_exhaustive] LL | #[non_exhaustive]

View file

@ -1,5 +1,5 @@
#[track_caller] #[track_caller]
struct S; struct S;
//~^^ ERROR attribute should be applied to function //~^^ ERROR attribute should be applied to a function definition
fn main() {} fn main() {}

View file

@ -1,10 +1,10 @@
error[E0739]: attribute should be applied to function error[E0739]: attribute should be applied to a function definition
--> $DIR/only-for-fns.rs:1:1 --> $DIR/only-for-fns.rs:1:1
| |
LL | #[track_caller] LL | #[track_caller]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
LL | struct S; LL | struct S;
| --------- not a function | --------- not a function definition
error: aborting due to previous error error: aborting due to previous error

View file

@ -15,6 +15,6 @@ fn foo() {}
// Regression test for the ICE described in #83512. // Regression test for the ICE described in #83512.
trait Foo { trait Foo {
#[doc(keyword = "match")] #[doc(keyword = "match")]
//~^ ERROR: `#[doc(keyword = "...")]` can only be used on modules //~^ ERROR: `#[doc(keyword = "...")]` should be used on modules
fn quux() {} fn quux() {}
} }

View file

@ -1,16 +1,16 @@
error: `#[doc(keyword = "...")]` can only be used on empty modules error: `#[doc(keyword = "...")]` should be used on empty modules
--> $DIR/doc_keyword.rs:6:7 --> $DIR/doc_keyword.rs:6:7
| |
LL | #[doc(keyword = "hell")] LL | #[doc(keyword = "hell")]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: `#[doc(keyword = "...")]` can only be used on modules error: `#[doc(keyword = "...")]` should be used on modules
--> $DIR/doc_keyword.rs:11:7 --> $DIR/doc_keyword.rs:11:7
| |
LL | #[doc(keyword = "hall")] LL | #[doc(keyword = "hall")]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: `#[doc(keyword = "...")]` can only be used on modules error: `#[doc(keyword = "...")]` should be used on modules
--> $DIR/doc_keyword.rs:17:11 --> $DIR/doc_keyword.rs:17:11
| |
LL | #[doc(keyword = "match")] LL | #[doc(keyword = "match")]

View file

@ -34,43 +34,43 @@ LL | fn bar() {}
= note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information = note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable = help: add `#![feature(target_feature_11)]` to the crate attributes to enable
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:34:1 --> $DIR/invalid-attribute.rs:34:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | mod another {} LL | mod another {}
| -------------- not a function | -------------- not a function definition
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:39:1 --> $DIR/invalid-attribute.rs:39:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | const FOO: usize = 7; LL | const FOO: usize = 7;
| --------------------- not a function | --------------------- not a function definition
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:44:1 --> $DIR/invalid-attribute.rs:44:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | struct Foo; LL | struct Foo;
| ----------- not a function | ----------- not a function definition
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:49:1 --> $DIR/invalid-attribute.rs:49:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | enum Bar {} LL | enum Bar {}
| ----------- not a function | ----------- not a function definition
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:54:1 --> $DIR/invalid-attribute.rs:54:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
@ -81,16 +81,16 @@ LL | |
LL | | f1: u16, LL | | f1: u16,
LL | | f2: u16, LL | | f2: u16,
LL | | } LL | | }
| |_- not a function | |_- not a function definition
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:62:1 --> $DIR/invalid-attribute.rs:62:1
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | trait Baz {} LL | trait Baz {}
| ------------ not a function | ------------ not a function definition
error: cannot use `#[inline(always)]` with `#[target_feature]` error: cannot use `#[inline(always)]` with `#[target_feature]`
--> $DIR/invalid-attribute.rs:67:1 --> $DIR/invalid-attribute.rs:67:1
@ -98,7 +98,7 @@ error: cannot use `#[inline(always)]` with `#[target_feature]`
LL | #[inline(always)] LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:85:5 --> $DIR/invalid-attribute.rs:85:5
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
@ -108,16 +108,16 @@ LL | / unsafe {
LL | | foo(); LL | | foo();
LL | | bar(); LL | | bar();
LL | | } LL | | }
| |_____- not a function | |_____- not a function definition
error: attribute should be applied to a function error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:93:5 --> $DIR/invalid-attribute.rs:93:5
| |
LL | #[target_feature(enable = "sse2")] LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | || {}; LL | || {};
| ----- not a function | ----- not a function definition
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
--> $DIR/invalid-attribute.rs:77:5 --> $DIR/invalid-attribute.rs:77:5

View file

@ -36,11 +36,11 @@ trait Tr5 {
} }
#[rustc_must_implement_one_of(abc, xyz)] #[rustc_must_implement_one_of(abc, xyz)]
//~^ attribute can only be applied to a trait //~^ attribute should be applied to a trait
fn function() {} fn function() {}
#[rustc_must_implement_one_of(abc, xyz)] #[rustc_must_implement_one_of(abc, xyz)]
//~^ attribute can only be applied to a trait //~^ attribute should be applied to a trait
struct Struct {} struct Struct {}
fn main() {} fn main() {}

View file

@ -4,7 +4,7 @@ error: malformed `rustc_must_implement_one_of` attribute input
LL | #[rustc_must_implement_one_of] LL | #[rustc_must_implement_one_of]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]`
error: attribute can only be applied to a trait error: attribute should be applied to a trait
--> $DIR/rustc_must_implement_one_of_misuse.rs:38:1 --> $DIR/rustc_must_implement_one_of_misuse.rs:38:1
| |
LL | #[rustc_must_implement_one_of(abc, xyz)] LL | #[rustc_must_implement_one_of(abc, xyz)]
@ -13,7 +13,7 @@ LL |
LL | fn function() {} LL | fn function() {}
| ---------------- not a trait | ---------------- not a trait
error: attribute can only be applied to a trait error: attribute should be applied to a trait
--> $DIR/rustc_must_implement_one_of_misuse.rs:42:1 --> $DIR/rustc_must_implement_one_of_misuse.rs:42:1
| |
LL | #[rustc_must_implement_one_of(abc, xyz)] LL | #[rustc_must_implement_one_of(abc, xyz)]