Rollup merge of #151152 - nik-contrib:helper_attr_builtin, r=chenyukang
Add FCW for derive helper attributes that will conflict with built-in attributes
Adds a future-compatibility-warning deny-by-default lint that helps catch invalid derive helper attribute names early.
This issues the lint, saying that `ignore` helper will clash with the built-in `ignore` attribute.
```rust
#![crate_type = "proc-macro"]
#![deny(ambiguous_derive_helpers)]
use proc_macro::TokenStream;
#[proc_macro_derive(Trait, attributes(ignore))]
pub fn example(input: TokenStream) -> TokenStream {
TokenStream::new()
}
```
If you actually tried to use that `ignore` helper attribute, you won't be able to due to the ambiguity:
```rust
#[derive(Trait)]
struct Foo {
#[ignore]
field: (),
}
```
Produces:
```
error[E0659]: `ignore` is ambiguous
--> src/lib.rs:5:7
|
5 | #[ignore]
| ^^^^^^ ambiguous name
|
= note: ambiguous because of a name conflict with a builtin attribute
= note: `ignore` could refer to a built-in attribute
note: `ignore` could also refer to the derive helper attribute defined here
--> src/lib.rs:3:10
|
3 | #[derive(Trait)]
| ^^^^^
```
This commit is contained in:
commit
2dba56033e
7 changed files with 120 additions and 0 deletions
|
|
@ -1,3 +1,6 @@
|
|||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_session::lint::builtin::AMBIGUOUS_DERIVE_HELPERS;
|
||||
|
||||
use super::prelude::*;
|
||||
|
||||
const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets =
|
||||
|
|
@ -126,6 +129,13 @@ fn parse_derive_like<S: Stage>(
|
|||
cx.expected_identifier(ident.span);
|
||||
return None;
|
||||
}
|
||||
if rustc_feature::is_builtin_attr_name(ident.name) {
|
||||
cx.emit_lint(
|
||||
AMBIGUOUS_DERIVE_HELPERS,
|
||||
AttributeLintKind::AmbiguousDeriveHelpers,
|
||||
ident.span,
|
||||
);
|
||||
}
|
||||
attributes.push(ident.name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -383,6 +383,10 @@ pub fn decorate_attribute_lint(
|
|||
lints::DocAutoCfgExpectsHideOrShow.decorate_lint(diag)
|
||||
}
|
||||
|
||||
&AttributeLintKind::AmbiguousDeriveHelpers => {
|
||||
lints::AmbiguousDeriveHelpers.decorate_lint(diag)
|
||||
}
|
||||
|
||||
&AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name } => {
|
||||
lints::DocAutoCfgHideShowUnexpectedItem { attr_name }.decorate_lint(diag)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3752,6 +3752,10 @@ pub(crate) struct DocAliasDuplicated {
|
|||
#[diag("only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]`")]
|
||||
pub(crate) struct DocAutoCfgExpectsHideOrShow;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag("there exists a built-in attribute with the same name")]
|
||||
pub(crate) struct AmbiguousDeriveHelpers;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag("`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items")]
|
||||
pub(crate) struct DocAutoCfgHideShowUnexpectedItem {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ declare_lint_pass! {
|
|||
AARCH64_SOFTFLOAT_NEON,
|
||||
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||
AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||
AMBIGUOUS_DERIVE_HELPERS,
|
||||
AMBIGUOUS_GLOB_IMPORTED_TRAITS,
|
||||
AMBIGUOUS_GLOB_IMPORTS,
|
||||
AMBIGUOUS_GLOB_REEXPORTS,
|
||||
|
|
@ -4267,6 +4268,75 @@ declare_lint! {
|
|||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `ambiguous_derive_helpers` lint detects cases where a derive macro's helper attribute
|
||||
/// is the same name as that of a built-in attribute.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,ignore (proc-macro)
|
||||
/// #![crate_type = "proc-macro"]
|
||||
/// #![deny(ambiguous_derive_helpers)]
|
||||
///
|
||||
/// use proc_macro::TokenStream;
|
||||
///
|
||||
/// #[proc_macro_derive(Trait, attributes(ignore))]
|
||||
/// pub fn example(input: TokenStream) -> TokenStream {
|
||||
/// TokenStream::new()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Produces:
|
||||
///
|
||||
/// ```text
|
||||
/// warning: there exists a built-in attribute with the same name
|
||||
/// --> file.rs:5:39
|
||||
/// |
|
||||
/// 5 | #[proc_macro_derive(Trait, attributes(ignore))]
|
||||
/// | ^^^^^^
|
||||
/// |
|
||||
/// = 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 #151152 <https://github.com/rust-lang/rust/issues/151152>
|
||||
/// = note: `#[deny(ambiguous_derive_helpers)]` (part of `#[deny(future_incompatible)]`) on by default
|
||||
/// ```
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// Attempting to use this helper attribute will throw an error:
|
||||
///
|
||||
/// ```rust,ignore (needs-dependency)
|
||||
/// #[derive(Trait)]
|
||||
/// struct Example {
|
||||
/// #[ignore]
|
||||
/// fields: ()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Produces:
|
||||
///
|
||||
/// ```text
|
||||
/// error[E0659]: `ignore` is ambiguous
|
||||
/// --> src/lib.rs:5:7
|
||||
/// |
|
||||
/// 5 | #[ignore]
|
||||
/// | ^^^^^^ ambiguous name
|
||||
/// |
|
||||
/// = note: ambiguous because of a name conflict with a builtin attribute
|
||||
/// = note: `ignore` could refer to a built-in attribute
|
||||
/// note: `ignore` could also refer to the derive helper attribute defined here
|
||||
/// --> src/lib.rs:3:10
|
||||
/// |
|
||||
/// 3 | #[derive(Trait)]
|
||||
/// | ^^^^^
|
||||
/// ```
|
||||
pub AMBIGUOUS_DERIVE_HELPERS,
|
||||
Warn,
|
||||
"detects derive helper attributes that are ambiguous with built-in attributes",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reason: fcw!(FutureReleaseError #151276),
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `private_interfaces` lint detects types in a primary interface of an item,
|
||||
/// that are more private than the item itself. Primary interface of an item is all
|
||||
|
|
|
|||
|
|
@ -800,6 +800,7 @@ pub enum AttributeLintKind {
|
|||
attr_name: Symbol,
|
||||
},
|
||||
DocInvalid,
|
||||
AmbiguousDeriveHelpers,
|
||||
DocUnknownInclude {
|
||||
span: Span,
|
||||
inner: &'static str,
|
||||
|
|
|
|||
15
tests/ui/attributes/ambiguous_derive_helpers.rs
Normal file
15
tests/ui/attributes/ambiguous_derive_helpers.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
//@ force-host
|
||||
//@ no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![deny(ambiguous_derive_helpers)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_derive(Trait, attributes(ignore))] //~ ERROR there exists a built-in attribute with the same name
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
pub fn deriving(input: TokenStream) -> TokenStream {
|
||||
TokenStream::new()
|
||||
}
|
||||
16
tests/ui/attributes/ambiguous_derive_helpers.stderr
Normal file
16
tests/ui/attributes/ambiguous_derive_helpers.stderr
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
error: there exists a built-in attribute with the same name
|
||||
--> $DIR/ambiguous_derive_helpers.rs:11:39
|
||||
|
|
||||
LL | #[proc_macro_derive(Trait, attributes(ignore))]
|
||||
| ^^^^^^
|
||||
|
|
||||
= 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 #151276 <https://github.com/rust-lang/rust/issues/151276>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/ambiguous_derive_helpers.rs:5:9
|
||||
|
|
||||
LL | #![deny(ambiguous_derive_helpers)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue