diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index 78701b336822..b3f4d6f6cb46 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -577,9 +577,8 @@ impl PostExpansionEarlyAttributes { } impl EarlyLintPass for PostExpansionEarlyAttributes { - fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) { + fn check_crate(&mut self, cx: &EarlyContext<'_>, _krate: &ast::Crate) { blanket_clippy_restriction_lints::check_command_line(cx); - duplicated_attributes::check(cx, &krate.attrs); } fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) { @@ -639,8 +638,15 @@ impl EarlyLintPass for PostExpansionEarlyAttributes { } mixed_attributes_style::check(cx, item.span, &item.attrs); - duplicated_attributes::check(cx, &item.attrs); } - extract_msrv_attr!(); + fn check_attributes(&mut self, cx: &EarlyContext<'_>, attrs: &[Attribute]) { + self.msrv.check_attributes(attrs); + duplicated_attributes::check(cx, attrs); + msrvs::check_attrs(cx.sess(), attrs); + } + + fn check_attributes_post(&mut self, _cx: &EarlyContext<'_>, attrs: &[Attribute]) { + self.msrv.check_attributes_post(attrs); + } } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 93bb20aac309..746b1b4f24f1 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -134,12 +134,12 @@ macro_rules! extract_msrv_attr { () => { fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); - self.msrv.check_attributes(sess, attrs); + self.msrv.check_attributes(attrs); } fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); - self.msrv.check_attributes_post(sess, attrs); + self.msrv.check_attributes_post(attrs); } }; } diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index d9b34ebfe21e..adcecb1244af 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -140,7 +140,7 @@ impl Msrv { fn for_attrs(self, tcx: TyCtxt<'_>, node: HirId) -> Option { once(node) .chain(tcx.hir_parent_id_iter(node)) - .find_map(|id| parse_attrs(tcx.sess, tcx.hir_attrs(id))) + .find_map(|id| parse_attrs(tcx.hir_attrs(id))) .or(self.0) } @@ -199,24 +199,34 @@ impl MsrvStack { self.current().is_none_or(|msrv| msrv >= required) } - pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) { - if let Some(version) = parse_attrs(sess, attrs) { + pub fn check_attributes(&mut self, attrs: &[Attribute]) { + if let Some(version) = parse_attrs(attrs) { SEEN_MSRV_ATTR.store(true, Ordering::Relaxed); self.stack.push(version); } } - pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) { - if parse_attrs(sess, attrs).is_some() { + pub fn check_attributes_post(&mut self, attrs: &[Attribute]) { + if parse_attrs(attrs).is_some() { self.stack.pop(); } } } -fn parse_attrs(sess: &Session, attrs: &[impl AttributeExt]) -> Option { +fn parse_attrs(attrs: &[impl AttributeExt]) -> Option { + let msrv_attr = attrs.iter().find(|attr| attr.path_matches(&[sym::clippy, sym::msrv]))?; + + let msrv = msrv_attr.value_str()?; + + parse_version(msrv) +} + +pub fn check_attrs(sess: &Session, attrs: &[impl AttributeExt]) { let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym::msrv])); - let msrv_attr = msrv_attrs.next()?; + let Some(msrv_attr) = msrv_attrs.next() else { + return; + }; if let Some(duplicate) = msrv_attrs.next_back() { sess.dcx() @@ -227,14 +237,11 @@ fn parse_attrs(sess: &Session, attrs: &[impl AttributeExt]) -> Option tests/ui/min_rust_version_invalid_attr.rs:4:1 + --> tests/ui/min_rust_version_invalid_attr.rs:2:1 | LL | #![clippy::msrv = "invalid.version"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `invalid.version` is not a valid Rust version - --> tests/ui/min_rust_version_invalid_attr.rs:9:1 + --> tests/ui/min_rust_version_invalid_attr.rs:7:1 | LL | #[clippy::msrv = "invalid.version"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `clippy::msrv` is defined multiple times - --> tests/ui/min_rust_version_invalid_attr.rs:16:5 + --> tests/ui/min_rust_version_invalid_attr.rs:14:5 | LL | #![clippy::msrv = "1.10.1"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first definition found here - --> tests/ui/min_rust_version_invalid_attr.rs:14:5 + --> tests/ui/min_rust_version_invalid_attr.rs:12:5 | LL | #![clippy::msrv = "1.40"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `clippy::msrv` is defined multiple times - --> tests/ui/min_rust_version_invalid_attr.rs:21:9 + --> tests/ui/min_rust_version_invalid_attr.rs:19:9 | LL | #![clippy::msrv = "1.0.0"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first definition found here - --> tests/ui/min_rust_version_invalid_attr.rs:20:9 + --> tests/ui/min_rust_version_invalid_attr.rs:18:9 | LL | #![clippy::msrv = "1.0"] | ^^^^^^^^^^^^^^^^^^^^^^^^