Skip to content

Commit c9b7a07

Browse files
committed
Early error when helper attribute name clashes with built-in
1 parent ed0006a commit c9b7a07

8 files changed

Lines changed: 115 additions & 0 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use rustc_hir::lints::AttributeLintKind;
2+
use rustc_session::lint::builtin::DERIVE_HELPER_CLASHES_WITH_BUILTIN_ATTR;
3+
14
use super::prelude::*;
25

36
const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets =
@@ -126,6 +129,13 @@ fn parse_derive_like<S: Stage>(
126129
cx.expected_identifier(ident.span);
127130
return None;
128131
}
132+
if rustc_feature::is_builtin_attr_name(ident.name) {
133+
cx.emit_lint(
134+
DERIVE_HELPER_CLASHES_WITH_BUILTIN_ATTR,
135+
AttributeLintKind::DeriveHelperClashesWithBuiltinAttr,
136+
ident.span,
137+
);
138+
}
129139
attributes.push(ident.name);
130140
}
131141
}

compiler/rustc_lint/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ lint_deprecated_where_clause_location = where clause not allowed here
232232
.suggestion_move_to_end = move it to the end of the type declaration
233233
.suggestion_remove_where = remove this `where`
234234
235+
lint_derive_helper_clashes_with_builtin_attr =
236+
there exists a built-in attribute with the same name
237+
235238
lint_diag_out_of_impl =
236239
diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls
237240

compiler/rustc_lint/src/early/diagnostics.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,10 @@ pub fn decorate_attribute_lint(
375375
lints::DocAutoCfgExpectsHideOrShow.decorate_lint(diag)
376376
}
377377

378+
&AttributeLintKind::DeriveHelperClashesWithBuiltinAttr => {
379+
lints::DeriveHelperClashesWithBuiltinAttr.decorate_lint(diag)
380+
}
381+
378382
&AttributeLintKind::DocAutoCfgHideShowUnexpectedItem { attr_name } => {
379383
lints::DocAutoCfgHideShowUnexpectedItem { attr_name }.decorate_lint(diag)
380384
}

compiler/rustc_lint/src/lints.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3223,6 +3223,10 @@ pub(crate) struct DocAliasDuplicated {
32233223
#[diag(lint_doc_auto_cfg_expects_hide_or_show)]
32243224
pub(crate) struct DocAutoCfgExpectsHideOrShow;
32253225

3226+
#[derive(LintDiagnostic)]
3227+
#[diag(lint_derive_helper_clashes_with_builtin_attr)]
3228+
pub(crate) struct DeriveHelperClashesWithBuiltinAttr;
3229+
32263230
#[derive(LintDiagnostic)]
32273231
#[diag(lint_doc_auto_cfg_hide_show_unexpected_item)]
32283232
pub(crate) struct DocAutoCfgHideShowUnexpectedItem {

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ declare_lint_pass! {
3535
DEPRECATED_IN_FUTURE,
3636
DEPRECATED_SAFE_2024,
3737
DEPRECATED_WHERE_CLAUSE_LOCATION,
38+
DERIVE_HELPER_CLASHES_WITH_BUILTIN_ATTR,
3839
DUPLICATE_MACRO_ATTRIBUTES,
3940
ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
4041
ELIDED_LIFETIMES_IN_PATHS,
@@ -4237,6 +4238,75 @@ declare_lint! {
42374238
};
42384239
}
42394240

4241+
declare_lint! {
4242+
/// The `derive_helper_clashes_with_builtin_attr` lint detects cases where a derive macro's helper attribute
4243+
/// is the same name as that of a built-in attribute.
4244+
///
4245+
/// ### Example
4246+
///
4247+
/// ```rust,ignore (proc-macro)
4248+
/// #![crate_type = "proc-macro"]
4249+
/// #![deny(derive_helper_clashes_with_builtin_attr)]
4250+
///
4251+
/// use proc_macro::TokenStream;
4252+
///
4253+
/// #[proc_macro_derive(Trait, attributes(ignore))]
4254+
/// pub fn example(input: TokenStream) -> TokenStream {
4255+
/// TokenStream::new()
4256+
/// }
4257+
/// ```
4258+
///
4259+
/// Produces:
4260+
///
4261+
/// ```text
4262+
/// error: there exists a built-in attribute with the same name
4263+
/// --> file.rs:5:39
4264+
/// |
4265+
/// 5 | #[proc_macro_derive(Trait, attributes(ignore))]
4266+
/// | ^^^^^^
4267+
/// |
4268+
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4269+
/// = note: for more information, see issue #0 <https://github.com/rust-lang/rust/issues/0>
4270+
/// = note: `#[deny(derive_helper_clashes_with_builtin_attr)]` (part of `#[deny(future_incompatible)]`) on by default
4271+
/// ```
4272+
///
4273+
/// ### Explanation
4274+
///
4275+
/// Attempting to use this helper attribute will throw an error:
4276+
///
4277+
/// ```rust,ignore (needs-dependency)
4278+
/// #[derive(Trait)]
4279+
/// struct Example {
4280+
/// #[ignore]
4281+
/// fields: ()
4282+
/// }
4283+
/// ```
4284+
///
4285+
/// Produces:
4286+
///
4287+
/// ```text
4288+
/// error[E0659]: `ignore` is ambiguous
4289+
/// --> src/lib.rs:5:7
4290+
/// |
4291+
/// 5 | #[ignore]
4292+
/// | ^^^^^^ ambiguous name
4293+
/// |
4294+
/// = note: ambiguous because of a name conflict with a builtin attribute
4295+
/// = note: `ignore` could refer to a built-in attribute
4296+
/// note: `ignore` could also refer to the derive helper attribute defined here
4297+
/// --> src/lib.rs:3:10
4298+
/// |
4299+
/// 3 | #[derive(Trait)]
4300+
/// | ^^^^^
4301+
/// ```
4302+
pub DERIVE_HELPER_CLASHES_WITH_BUILTIN_ATTR,
4303+
Deny,
4304+
"same as a built-in attribute",
4305+
@future_incompatible = FutureIncompatibleInfo {
4306+
reason: fcw!(FutureReleaseError #0),
4307+
};
4308+
}
4309+
42404310
declare_lint! {
42414311
/// The `private_interfaces` lint detects types in a primary interface of an item,
42424312
/// that are more private than the item itself. Primary interface of an item is all

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ pub enum AttributeLintKind {
796796
attr_name: Symbol,
797797
},
798798
DocInvalid,
799+
DeriveHelperClashesWithBuiltinAttr,
799800
DocUnknownInclude {
800801
span: Span,
801802
inner: &'static str,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![crate_type = "proc-macro"]
2+
3+
extern crate proc_macro;
4+
5+
use proc_macro::TokenStream;
6+
7+
#[proc_macro_derive(Trait, attributes(ignore))] //~ ERROR there exists a built-in attribute with the same name
8+
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9+
pub fn deriving(input: TokenStream) -> TokenStream {
10+
TokenStream::new()
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error: there exists a built-in attribute with the same name
2+
--> $DIR/derive_helper_clashes_with_builtin_attr.rs:7:39
3+
|
4+
LL | #[proc_macro_derive(Trait, attributes(ignore))]
5+
| ^^^^^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #0 <https://github.com/rust-lang/rust/issues/0>
9+
= note: `#[deny(derive_helper_clashes_with_builtin_attr)]` (part of `#[deny(future_incompatible)]`) on by default
10+
11+
error: aborting due to 1 previous error
12+

0 commit comments

Comments
 (0)