From 65a26692fd361b794f528ead645d880527ce3de0 Mon Sep 17 00:00:00 2001 From: "Samuel E. Moelius III" Date: Wed, 23 Mar 2022 21:08:52 -0400 Subject: [PATCH 1/8] Add `crate_in_macro_def` lint --- CHANGELOG.md | 1 + clippy_lints/src/crate_in_macro_def.rs | 100 +++++++++++++++++++ clippy_lints/src/lib.register_all.rs | 1 + clippy_lints/src/lib.register_correctness.rs | 1 + clippy_lints/src/lib.register_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/utils/conf.rs | 2 +- tests/ui/crate_in_macro_def.fixed | 29 ++++++ tests/ui/crate_in_macro_def.rs | 29 ++++++ tests/ui/crate_in_macro_def.stderr | 14 +++ tests/ui/crate_in_macro_def_allow.rs | 19 ++++ tests/ui/crate_in_macro_def_allow.stderr | 0 12 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 clippy_lints/src/crate_in_macro_def.rs create mode 100644 tests/ui/crate_in_macro_def.fixed create mode 100644 tests/ui/crate_in_macro_def.rs create mode 100644 tests/ui/crate_in_macro_def.stderr create mode 100644 tests/ui/crate_in_macro_def_allow.rs create mode 100644 tests/ui/crate_in_macro_def_allow.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index dc83de665548..9cede8065ec7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3097,6 +3097,7 @@ Released 2018-09-13 [`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain [`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_to_empty [`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator +[`crate_in_macro_def`]: https://rust-lang.github.io/rust-clippy/master/index.html#crate_in_macro_def [`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir [`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute [`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs new file mode 100644 index 000000000000..9ac6d6d520cc --- /dev/null +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -0,0 +1,100 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use rustc_ast::ast::MacroDef; +use rustc_ast::node_id::NodeId; +use rustc_ast::token::{Token, TokenKind}; +use rustc_ast::tokenstream::{TokenStream, TokenTree}; +use rustc_errors::Applicability; +use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::Span; + +declare_clippy_lint! { + /// ### What it does + /// Checks for use of `crate` as opposed to `$crate` in a macro definition. + /// + /// ### Why is this bad? + /// `crate` refers to macro call's crate, whereas `$crate` refers to the macro + /// definition's crate. Rarely is the former intended. See: + /// https://doc.rust-lang.org/reference/macros-by-example.html#hygiene + /// + /// ### Example + /// ```rust + /// macro_rules! print_message { + /// () => { + /// println!("{}", crate::MESSAGE); + /// }; + /// } + /// pub const MESSAGE: &str = "Hello!"; + /// ``` + /// Use instead: + /// ```rust + /// macro_rules! print_message { + /// () => { + /// println!("{}", $crate::MESSAGE); + /// }; + /// } + /// pub const MESSAGE: &str = "Hello!"; + /// ``` + #[clippy::version = "1.61.0"] + pub CRATE_IN_MACRO_DEF, + correctness, + "using `crate` in a macro definition" +} +declare_lint_pass!(CrateInMacroDef => [CRATE_IN_MACRO_DEF]); + +impl EarlyLintPass for CrateInMacroDef { + fn check_mac_def(&mut self, cx: &EarlyContext<'_>, macro_def: &MacroDef, _: NodeId) { + let tts = macro_def.body.inner_tokens(); + if let Some(span) = contains_unhygienic_crate_reference(&tts) { + span_lint_and_sugg( + cx, + CRATE_IN_MACRO_DEF, + span, + "reference to the macro call's crate, which is rarely intended", + "if reference to the macro definition's crate is intended, use", + String::from("$crate"), + Applicability::MachineApplicable, + ); + } + } +} + +fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option { + let mut prev_is_dollar = false; + let mut cursor = tts.trees(); + while let Some(curr) = cursor.next() { + if_chain! { + if !prev_is_dollar; + if let Some(span) = is_crate_keyword(&curr); + if let Some(next) = cursor.look_ahead(0); + if is_token(next, &TokenKind::ModSep); + then { + return Some(span); + } + } + if let TokenTree::Delimited(_, _, tts) = &curr { + let span = contains_unhygienic_crate_reference(tts); + if span.is_some() { + return span; + } + } + prev_is_dollar = is_token(&curr, &TokenKind::Dollar); + } + None +} + +fn is_crate_keyword(tt: &TokenTree) -> Option { + if_chain! { + if let TokenTree::Token(Token { kind: TokenKind::Ident(symbol, _), span }) = tt; + if symbol.as_str() == "crate"; + then { Some(*span) } else { None } + } +} + +fn is_token(tt: &TokenTree, kind: &TokenKind) -> bool { + if let TokenTree::Token(Token { kind: other, .. }) = tt { + kind == other + } else { + false + } +} diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs index 132a46626762..1fb3ca1fd9b2 100644 --- a/clippy_lints/src/lib.register_all.rs +++ b/clippy_lints/src/lib.register_all.rs @@ -37,6 +37,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![ LintId::of(comparison_chain::COMPARISON_CHAIN), LintId::of(copies::IFS_SAME_COND), LintId::of(copies::IF_SAME_THEN_ELSE), + LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF), LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT), LintId::of(dereference::NEEDLESS_BORROW), LintId::of(derivable_impls::DERIVABLE_IMPLS), diff --git a/clippy_lints/src/lib.register_correctness.rs b/clippy_lints/src/lib.register_correctness.rs index df63f84463db..d5cade8fe998 100644 --- a/clippy_lints/src/lib.register_correctness.rs +++ b/clippy_lints/src/lib.register_correctness.rs @@ -16,6 +16,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES), LintId::of(copies::IFS_SAME_COND), LintId::of(copies::IF_SAME_THEN_ELSE), + LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF), LintId::of(derive::DERIVE_HASH_XOR_EQ), LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD), LintId::of(drop_forget_ref::DROP_COPY), diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs index 65ad64f19018..984939a74b8d 100644 --- a/clippy_lints/src/lib.register_lints.rs +++ b/clippy_lints/src/lib.register_lints.rs @@ -97,6 +97,7 @@ store.register_lints(&[ copies::IF_SAME_THEN_ELSE, copies::SAME_FUNCTIONS_IN_IF_CONDITION, copy_iterator::COPY_ITERATOR, + crate_in_macro_def::CRATE_IN_MACRO_DEF, create_dir::CREATE_DIR, dbg_macro::DBG_MACRO, default::DEFAULT_TRAIT_ACCESS, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index f2a079991444..c8b57956b1b6 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -190,6 +190,7 @@ mod collapsible_match; mod comparison_chain; mod copies; mod copy_iterator; +mod crate_in_macro_def; mod create_dir; mod dbg_macro; mod default; @@ -867,6 +868,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: ignore_publish: cargo_ignore_publish, }) }); + store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 680b2eb1da72..b1e474f80561 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -123,7 +123,7 @@ macro_rules! define_Conf { #[cfg(feature = "internal")] pub mod metadata { - use crate::utils::internal_lints::metadata_collector::ClippyConfiguration; + use $crate::utils::internal_lints::metadata_collector::ClippyConfiguration; macro_rules! wrap_option { () => (None); diff --git a/tests/ui/crate_in_macro_def.fixed b/tests/ui/crate_in_macro_def.fixed new file mode 100644 index 000000000000..77b43f432601 --- /dev/null +++ b/tests/ui/crate_in_macro_def.fixed @@ -0,0 +1,29 @@ +// run-rustfix +#![warn(clippy::crate_in_macro_def)] + +#[macro_use] +mod hygienic { + macro_rules! print_message_hygienic { + () => { + println!("{}", $crate::hygienic::MESSAGE); + }; + } + + pub const MESSAGE: &str = "Hello!"; +} + +#[macro_use] +mod unhygienic { + macro_rules! print_message_unhygienic { + () => { + println!("{}", $crate::unhygienic::MESSAGE); + }; + } + + pub const MESSAGE: &str = "Hello!"; +} + +fn main() { + print_message_hygienic!(); + print_message_unhygienic!(); +} diff --git a/tests/ui/crate_in_macro_def.rs b/tests/ui/crate_in_macro_def.rs new file mode 100644 index 000000000000..d72d4c4009c3 --- /dev/null +++ b/tests/ui/crate_in_macro_def.rs @@ -0,0 +1,29 @@ +// run-rustfix +#![warn(clippy::crate_in_macro_def)] + +#[macro_use] +mod hygienic { + macro_rules! print_message_hygienic { + () => { + println!("{}", $crate::hygienic::MESSAGE); + }; + } + + pub const MESSAGE: &str = "Hello!"; +} + +#[macro_use] +mod unhygienic { + macro_rules! print_message_unhygienic { + () => { + println!("{}", crate::unhygienic::MESSAGE); + }; + } + + pub const MESSAGE: &str = "Hello!"; +} + +fn main() { + print_message_hygienic!(); + print_message_unhygienic!(); +} diff --git a/tests/ui/crate_in_macro_def.stderr b/tests/ui/crate_in_macro_def.stderr new file mode 100644 index 000000000000..3f5e4870ad1c --- /dev/null +++ b/tests/ui/crate_in_macro_def.stderr @@ -0,0 +1,14 @@ +error: reference to the macro call's crate, which is rarely intended + --> $DIR/crate_in_macro_def.rs:19:28 + | +LL | println!("{}", crate::unhygienic::MESSAGE); + | ^^^^^ + | + = note: `-D clippy::crate-in-macro-def` implied by `-D warnings` +help: if reference to the macro definition's crate is intended, use + | +LL | println!("{}", $crate::unhygienic::MESSAGE); + | ~~~~~~ + +error: aborting due to previous error + diff --git a/tests/ui/crate_in_macro_def_allow.rs b/tests/ui/crate_in_macro_def_allow.rs new file mode 100644 index 000000000000..d6b30fd96152 --- /dev/null +++ b/tests/ui/crate_in_macro_def_allow.rs @@ -0,0 +1,19 @@ +#![warn(clippy::crate_in_macro_def)] + +#[macro_use] +mod intentional { + // For cases where use of `crate` is intentional, applying `allow` to the macro definition + // should suppress the lint. + #[allow(clippy::crate_in_macro_def)] + macro_rules! print_message { + () => { + println!("{}", crate::CALLER_PROVIDED_MESSAGE); + }; + } +} + +fn main() { + print_message!(); +} + +pub const CALLER_PROVIDED_MESSAGE: &str = "Hello!"; diff --git a/tests/ui/crate_in_macro_def_allow.stderr b/tests/ui/crate_in_macro_def_allow.stderr new file mode 100644 index 000000000000..e69de29bb2d1 From 86872059ed143e93f04130578d8b2d1561d5f3a7 Mon Sep 17 00:00:00 2001 From: Samuel Moelius <35515885+smoelius@users.noreply.github.com> Date: Thu, 24 Mar 2022 08:57:08 -0400 Subject: [PATCH 2/8] Typo --- clippy_lints/src/crate_in_macro_def.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs index 9ac6d6d520cc..de9c7ee5f204 100644 --- a/clippy_lints/src/crate_in_macro_def.rs +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -13,7 +13,7 @@ declare_clippy_lint! { /// Checks for use of `crate` as opposed to `$crate` in a macro definition. /// /// ### Why is this bad? - /// `crate` refers to macro call's crate, whereas `$crate` refers to the macro + /// `crate` refers to the macro call's crate, whereas `$crate` refers to the macro /// definition's crate. Rarely is the former intended. See: /// https://doc.rust-lang.org/reference/macros-by-example.html#hygiene /// From cb307bbfcd123d3bae8f210f2b51eebe68525c27 Mon Sep 17 00:00:00 2001 From: "Samuel E. Moelius III" Date: Mon, 28 Mar 2022 04:32:31 -0400 Subject: [PATCH 3/8] Address review comments --- clippy_lints/src/crate_in_macro_def.rs | 60 +++++++++++++++++------- clippy_lints/src/utils/conf.rs | 2 +- tests/ui/crate_in_macro_def.fixed | 31 +++++++++++- tests/ui/crate_in_macro_def.rs | 31 +++++++++++- tests/ui/crate_in_macro_def_allow.rs | 19 -------- tests/ui/crate_in_macro_def_allow.stderr | 0 6 files changed, 102 insertions(+), 41 deletions(-) delete mode 100644 tests/ui/crate_in_macro_def_allow.rs delete mode 100644 tests/ui/crate_in_macro_def_allow.stderr diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs index de9c7ee5f204..21c65f9d6f04 100644 --- a/clippy_lints/src/crate_in_macro_def.rs +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -1,24 +1,24 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use rustc_ast::ast::MacroDef; -use rustc_ast::node_id::NodeId; +use rustc_ast::ast::{AttrKind, Attribute, Item, ItemKind}; use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::Span; +use rustc_span::{symbol::sym, Span}; declare_clippy_lint! { /// ### What it does /// Checks for use of `crate` as opposed to `$crate` in a macro definition. /// /// ### Why is this bad? - /// `crate` refers to the macro call's crate, whereas `$crate` refers to the macro - /// definition's crate. Rarely is the former intended. See: + /// `crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's + /// crate. Rarely is the former intended. See: /// https://doc.rust-lang.org/reference/macros-by-example.html#hygiene /// /// ### Example /// ```rust + /// #[macro_export] /// macro_rules! print_message { /// () => { /// println!("{}", crate::MESSAGE); @@ -28,6 +28,7 @@ declare_clippy_lint! { /// ``` /// Use instead: /// ```rust + /// #[macro_export] /// macro_rules! print_message { /// () => { /// println!("{}", $crate::MESSAGE); @@ -35,6 +36,13 @@ declare_clippy_lint! { /// } /// pub const MESSAGE: &str = "Hello!"; /// ``` + /// + /// Note that if the use of `crate` is intentional, an `allow` attribute can be applied to the + /// macro definition, e.g.: + /// ```rust,ignore + /// #[allow(clippy::crate_in_macro_def)] + /// macro_rules! ok { ... crate::foo ... } + /// ``` #[clippy::version = "1.61.0"] pub CRATE_IN_MACRO_DEF, correctness, @@ -43,18 +51,36 @@ declare_clippy_lint! { declare_lint_pass!(CrateInMacroDef => [CRATE_IN_MACRO_DEF]); impl EarlyLintPass for CrateInMacroDef { - fn check_mac_def(&mut self, cx: &EarlyContext<'_>, macro_def: &MacroDef, _: NodeId) { - let tts = macro_def.body.inner_tokens(); - if let Some(span) = contains_unhygienic_crate_reference(&tts) { - span_lint_and_sugg( - cx, - CRATE_IN_MACRO_DEF, - span, - "reference to the macro call's crate, which is rarely intended", - "if reference to the macro definition's crate is intended, use", - String::from("$crate"), - Applicability::MachineApplicable, - ); + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + if_chain! { + if item.attrs.iter().any(is_macro_export); + if let ItemKind::MacroDef(macro_def) = &item.kind; + let tts = macro_def.body.inner_tokens(); + if let Some(span) = contains_unhygienic_crate_reference(&tts); + then { + span_lint_and_sugg( + cx, + CRATE_IN_MACRO_DEF, + span, + "reference to the macro call's crate, which is rarely intended", + "if reference to the macro definition's crate is intended, use", + String::from("$crate"), + Applicability::MachineApplicable, + ); + } + } + } +} + +fn is_macro_export(attr: &Attribute) -> bool { + if_chain! { + if let AttrKind::Normal(attr_item, _) = &attr.kind; + if let [segment] = attr_item.path.segments.as_slice(); + if segment.ident.name == sym::macro_export; + then { + true + } else { + false } } } diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index b1e474f80561..680b2eb1da72 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -123,7 +123,7 @@ macro_rules! define_Conf { #[cfg(feature = "internal")] pub mod metadata { - use $crate::utils::internal_lints::metadata_collector::ClippyConfiguration; + use crate::utils::internal_lints::metadata_collector::ClippyConfiguration; macro_rules! wrap_option { () => (None); diff --git a/tests/ui/crate_in_macro_def.fixed b/tests/ui/crate_in_macro_def.fixed index 77b43f432601..9fc594be311e 100644 --- a/tests/ui/crate_in_macro_def.fixed +++ b/tests/ui/crate_in_macro_def.fixed @@ -1,8 +1,8 @@ // run-rustfix #![warn(clippy::crate_in_macro_def)] -#[macro_use] mod hygienic { + #[macro_export] macro_rules! print_message_hygienic { () => { println!("{}", $crate::hygienic::MESSAGE); @@ -12,8 +12,8 @@ mod hygienic { pub const MESSAGE: &str = "Hello!"; } -#[macro_use] mod unhygienic { + #[macro_export] macro_rules! print_message_unhygienic { () => { println!("{}", $crate::unhygienic::MESSAGE); @@ -23,7 +23,34 @@ mod unhygienic { pub const MESSAGE: &str = "Hello!"; } +mod unhygienic_intentionally { + // For cases where the use of `crate` is intentional, applying `allow` to the macro definition + // should suppress the lint. + #[allow(clippy::crate_in_macro_def)] + #[macro_export] + macro_rules! print_message_unhygienic_intentionally { + () => { + println!("{}", crate::CALLER_PROVIDED_MESSAGE); + }; + } +} + +#[macro_use] +mod not_exported { + macro_rules! print_message_not_exported { + () => { + println!("{}", crate::not_exported::MESSAGE); + }; + } + + pub const MESSAGE: &str = "Hello!"; +} + fn main() { print_message_hygienic!(); print_message_unhygienic!(); + print_message_unhygienic_intentionally!(); + print_message_not_exported!(); } + +pub const CALLER_PROVIDED_MESSAGE: &str = "Hello!"; diff --git a/tests/ui/crate_in_macro_def.rs b/tests/ui/crate_in_macro_def.rs index d72d4c4009c3..ac456108e4ab 100644 --- a/tests/ui/crate_in_macro_def.rs +++ b/tests/ui/crate_in_macro_def.rs @@ -1,8 +1,8 @@ // run-rustfix #![warn(clippy::crate_in_macro_def)] -#[macro_use] mod hygienic { + #[macro_export] macro_rules! print_message_hygienic { () => { println!("{}", $crate::hygienic::MESSAGE); @@ -12,8 +12,8 @@ mod hygienic { pub const MESSAGE: &str = "Hello!"; } -#[macro_use] mod unhygienic { + #[macro_export] macro_rules! print_message_unhygienic { () => { println!("{}", crate::unhygienic::MESSAGE); @@ -23,7 +23,34 @@ mod unhygienic { pub const MESSAGE: &str = "Hello!"; } +mod unhygienic_intentionally { + // For cases where the use of `crate` is intentional, applying `allow` to the macro definition + // should suppress the lint. + #[allow(clippy::crate_in_macro_def)] + #[macro_export] + macro_rules! print_message_unhygienic_intentionally { + () => { + println!("{}", crate::CALLER_PROVIDED_MESSAGE); + }; + } +} + +#[macro_use] +mod not_exported { + macro_rules! print_message_not_exported { + () => { + println!("{}", crate::not_exported::MESSAGE); + }; + } + + pub const MESSAGE: &str = "Hello!"; +} + fn main() { print_message_hygienic!(); print_message_unhygienic!(); + print_message_unhygienic_intentionally!(); + print_message_not_exported!(); } + +pub const CALLER_PROVIDED_MESSAGE: &str = "Hello!"; diff --git a/tests/ui/crate_in_macro_def_allow.rs b/tests/ui/crate_in_macro_def_allow.rs deleted file mode 100644 index d6b30fd96152..000000000000 --- a/tests/ui/crate_in_macro_def_allow.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![warn(clippy::crate_in_macro_def)] - -#[macro_use] -mod intentional { - // For cases where use of `crate` is intentional, applying `allow` to the macro definition - // should suppress the lint. - #[allow(clippy::crate_in_macro_def)] - macro_rules! print_message { - () => { - println!("{}", crate::CALLER_PROVIDED_MESSAGE); - }; - } -} - -fn main() { - print_message!(); -} - -pub const CALLER_PROVIDED_MESSAGE: &str = "Hello!"; diff --git a/tests/ui/crate_in_macro_def_allow.stderr b/tests/ui/crate_in_macro_def_allow.stderr deleted file mode 100644 index e69de29bb2d1..000000000000 From 9b304533abac7479f168c0aaa1b6282194f4c128 Mon Sep 17 00:00:00 2001 From: Samuel Moelius <35515885+smoelius@users.noreply.github.com> Date: Wed, 30 Mar 2022 12:40:16 -0400 Subject: [PATCH 4/8] Update clippy_lints/src/crate_in_macro_def.rs Co-authored-by: llogiq --- clippy_lints/src/crate_in_macro_def.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs index 21c65f9d6f04..844887dcbe53 100644 --- a/clippy_lints/src/crate_in_macro_def.rs +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -62,7 +62,7 @@ impl EarlyLintPass for CrateInMacroDef { cx, CRATE_IN_MACRO_DEF, span, - "reference to the macro call's crate, which is rarely intended", + "`crate` references the macro call's crate", "if reference to the macro definition's crate is intended, use", String::from("$crate"), Applicability::MachineApplicable, From abc221e7f66b495d2ea86ccdb200ee9f29cecaab Mon Sep 17 00:00:00 2001 From: Samuel Moelius <35515885+smoelius@users.noreply.github.com> Date: Wed, 30 Mar 2022 12:40:25 -0400 Subject: [PATCH 5/8] Update clippy_lints/src/crate_in_macro_def.rs Co-authored-by: llogiq --- clippy_lints/src/crate_in_macro_def.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs index 844887dcbe53..ef2f3df105a7 100644 --- a/clippy_lints/src/crate_in_macro_def.rs +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -63,7 +63,7 @@ impl EarlyLintPass for CrateInMacroDef { CRATE_IN_MACRO_DEF, span, "`crate` references the macro call's crate", - "if reference to the macro definition's crate is intended, use", + "to reference the macro definition's crate, use", String::from("$crate"), Applicability::MachineApplicable, ); From 75dc406e84122363c94e1faaae37472d23d20c29 Mon Sep 17 00:00:00 2001 From: Samuel Moelius <35515885+smoelius@users.noreply.github.com> Date: Wed, 30 Mar 2022 12:40:44 -0400 Subject: [PATCH 6/8] Update clippy_lints/src/crate_in_macro_def.rs Co-authored-by: llogiq --- clippy_lints/src/crate_in_macro_def.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs index ef2f3df105a7..e64c7f127eb5 100644 --- a/clippy_lints/src/crate_in_macro_def.rs +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -76,9 +76,8 @@ fn is_macro_export(attr: &Attribute) -> bool { if_chain! { if let AttrKind::Normal(attr_item, _) = &attr.kind; if let [segment] = attr_item.path.segments.as_slice(); - if segment.ident.name == sym::macro_export; then { - true + segment.ident.name == sym::macro_export } else { false } From d6eb82c0a8d94d21fee110620ee4d0515ac198d3 Mon Sep 17 00:00:00 2001 From: "Samuel E. Moelius III" Date: Wed, 30 Mar 2022 12:32:07 -0400 Subject: [PATCH 7/8] Move `crate_in_macro_def` to suspicious --- clippy_lints/src/crate_in_macro_def.rs | 2 +- clippy_lints/src/lib.register_correctness.rs | 1 - clippy_lints/src/lib.register_suspicious.rs | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs index e64c7f127eb5..fc141b4a6e3a 100644 --- a/clippy_lints/src/crate_in_macro_def.rs +++ b/clippy_lints/src/crate_in_macro_def.rs @@ -45,7 +45,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.61.0"] pub CRATE_IN_MACRO_DEF, - correctness, + suspicious, "using `crate` in a macro definition" } declare_lint_pass!(CrateInMacroDef => [CRATE_IN_MACRO_DEF]); diff --git a/clippy_lints/src/lib.register_correctness.rs b/clippy_lints/src/lib.register_correctness.rs index d5cade8fe998..df63f84463db 100644 --- a/clippy_lints/src/lib.register_correctness.rs +++ b/clippy_lints/src/lib.register_correctness.rs @@ -16,7 +16,6 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES), LintId::of(copies::IFS_SAME_COND), LintId::of(copies::IF_SAME_THEN_ELSE), - LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF), LintId::of(derive::DERIVE_HASH_XOR_EQ), LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD), LintId::of(drop_forget_ref::DROP_COPY), diff --git a/clippy_lints/src/lib.register_suspicious.rs b/clippy_lints/src/lib.register_suspicious.rs index fa3a88e1368c..0707e4f8f3d1 100644 --- a/clippy_lints/src/lib.register_suspicious.rs +++ b/clippy_lints/src/lib.register_suspicious.rs @@ -9,6 +9,7 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec! LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF), LintId::of(casts::CAST_ENUM_CONSTRUCTOR), LintId::of(casts::CAST_ENUM_TRUNCATION), + LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF), LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE), LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS), LintId::of(format_impl::PRINT_IN_FORMAT_IMPL), From aaf04dc0431aaf4be9f3125dd9cfcb80f2ae7e25 Mon Sep 17 00:00:00 2001 From: "Samuel E. Moelius III" Date: Wed, 30 Mar 2022 12:52:31 -0400 Subject: [PATCH 8/8] Fix error message in crate_in_macro_def.stderr --- tests/ui/crate_in_macro_def.stderr | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/ui/crate_in_macro_def.stderr b/tests/ui/crate_in_macro_def.stderr index 3f5e4870ad1c..9ac5937dcc06 100644 --- a/tests/ui/crate_in_macro_def.stderr +++ b/tests/ui/crate_in_macro_def.stderr @@ -1,14 +1,10 @@ -error: reference to the macro call's crate, which is rarely intended +error: `crate` references the macro call's crate --> $DIR/crate_in_macro_def.rs:19:28 | LL | println!("{}", crate::unhygienic::MESSAGE); - | ^^^^^ + | ^^^^^ help: to reference the macro definition's crate, use: `$crate` | = note: `-D clippy::crate-in-macro-def` implied by `-D warnings` -help: if reference to the macro definition's crate is intended, use - | -LL | println!("{}", $crate::unhygienic::MESSAGE); - | ~~~~~~ error: aborting due to previous error