From 0de8f46f52039310adad8552422d4df4d98157a5 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Thu, 4 Jul 2024 19:00:17 -0400 Subject: [PATCH] Refactor `absolute_paths`: * Check the path length first * Use `is_from_proc_macro` * Use symbols instead of strings when checking crate names --- clippy_lints/src/absolute_paths.rs | 94 ++++----- clippy_utils/src/check_proc_macro.rs | 12 +- .../absolute_paths.allow_crates.stderr | 45 +++-- .../absolute_paths.allow_long.stderr | 14 ++ .../absolute_paths.default.stderr | 80 ++++++++ .../absolute_paths.disallow_crates.stderr | 71 ------- .../absolute_paths.no_short.stderr | 98 ++++++++++ .../ui-toml/absolute_paths/absolute_paths.rs | 178 ++++++++++-------- .../absolute_paths_2015.default.stderr | 14 ++ .../absolute_paths/absolute_paths_2015.rs | 16 ++ .../absolute_paths/allow_crates/clippy.toml | 3 +- .../absolute_paths/allow_long/clippy.toml | 1 + .../absolute_paths/auxiliary/helper.rs | 11 -- .../absolute_paths/default/clippy.toml | 0 .../disallow_crates/clippy.toml | 1 - .../absolute_paths/no_short/clippy.toml | 1 + 16 files changed, 414 insertions(+), 225 deletions(-) create mode 100644 tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr create mode 100644 tests/ui-toml/absolute_paths/absolute_paths.default.stderr delete mode 100644 tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr create mode 100644 tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr create mode 100644 tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr create mode 100644 tests/ui-toml/absolute_paths/absolute_paths_2015.rs create mode 100644 tests/ui-toml/absolute_paths/allow_long/clippy.toml delete mode 100644 tests/ui-toml/absolute_paths/auxiliary/helper.rs create mode 100644 tests/ui-toml/absolute_paths/default/clippy.toml delete mode 100644 tests/ui-toml/absolute_paths/disallow_crates/clippy.toml create mode 100644 tests/ui-toml/absolute_paths/no_short/clippy.toml diff --git a/clippy_lints/src/absolute_paths.rs b/clippy_lints/src/absolute_paths.rs index c0a9d888e0b0..b18386c87eaf 100644 --- a/clippy_lints/src/absolute_paths.rs +++ b/clippy_lints/src/absolute_paths.rs @@ -1,6 +1,6 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint; -use clippy_utils::source::snippet_opt; +use clippy_utils::is_from_proc_macro; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; @@ -8,6 +8,7 @@ use rustc_hir::{HirId, ItemKind, Node, Path}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::symbol::kw; +use rustc_span::Symbol; declare_clippy_lint! { /// ### What it does @@ -24,6 +25,13 @@ declare_clippy_lint! { /// Note: One exception to this is code from macro expansion - this does not lint such cases, as /// using absolute paths is the proper way of referencing items in one. /// + /// ### Known issues + /// + /// There are currently a few cases which are not caught by this lint: + /// * Macro calls. e.g. `path::to::macro!()` + /// * Derive macros. e.g. `#[derive(path::to::macro)]` + /// * Attribute macros. e.g. `#[path::to::macro]` + /// /// ### Example /// ```no_run /// let x = std::f64::consts::PI; @@ -48,63 +56,65 @@ impl_lint_pass!(AbsolutePaths => [ABSOLUTE_PATHS]); pub struct AbsolutePaths { pub absolute_paths_max_segments: u64, - pub absolute_paths_allowed_crates: &'static FxHashSet, + pub absolute_paths_allowed_crates: FxHashSet, } impl AbsolutePaths { pub fn new(conf: &'static Conf) -> Self { Self { absolute_paths_max_segments: conf.absolute_paths_max_segments, - absolute_paths_allowed_crates: &conf.absolute_paths_allowed_crates, + absolute_paths_allowed_crates: conf.absolute_paths_allowed_crates + .iter() + .map(|x| Symbol::intern(x)) + .collect(), } } } -impl LateLintPass<'_> for AbsolutePaths { +impl<'tcx> LateLintPass<'tcx> for AbsolutePaths { // We should only lint `QPath::Resolved`s, but since `Path` is only used in `Resolved` and `UsePath` // we don't need to use a visitor or anything as we can just check if the `Node` for `hir_id` isn't // a `Use` - #[expect(clippy::cast_possible_truncation)] - fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) { - let Self { - absolute_paths_max_segments, - absolute_paths_allowed_crates, - } = self; - - if !path.span.from_expansion() - && let node = cx.tcx.hir_node(hir_id) - && !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(_, _))) - && let [first, rest @ ..] = path.segments - // Handle `::std` - && let (segment, len) = if first.ident.name == kw::PathRoot { - // Indexing is fine as `PathRoot` must be followed by another segment. `len() - 1` - // is fine here for the same reason - (&rest[0], path.segments.len() - 1) - } else { - (first, path.segments.len()) - } - && len > *absolute_paths_max_segments as usize - && let Some(segment_snippet) = snippet_opt(cx, segment.ident.span) - && segment_snippet == segment.ident.as_str() - { - let is_abs_external = - matches!(segment.res, Res::Def(DefKind::Mod, DefId { index, .. }) if index == CRATE_DEF_INDEX); - let is_abs_crate = segment.ident.name == kw::Crate; - - if is_abs_external && absolute_paths_allowed_crates.contains(segment.ident.name.as_str()) - || is_abs_crate && absolute_paths_allowed_crates.contains("crate") + fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, hir_id: HirId) { + let segments = match path.segments { + [] | [_] => return, + // Don't count enum variants and trait items as part of the length. + [rest @ .., _] + if let [.., s] = rest + && matches!(s.res, Res::Def(DefKind::Enum | DefKind::Trait | DefKind::TraitAlias, _)) => + { + rest + }, + path => path, + }; + if let [s1, s2, ..] = segments + && let has_root = s1.ident.name == kw::PathRoot + && let first = if has_root { s2 } else { s1 } + && let len = segments.len() - usize::from(has_root) + && len as u64 > self.absolute_paths_max_segments + && let crate_name = if let Res::Def(DefKind::Mod, DefId { index, .. }) = first.res + && index == CRATE_DEF_INDEX { + // `other_crate::foo` or `::other_crate::foo` + first.ident.name + } else if first.ident.name == kw::Crate || has_root { + // `::foo` or `crate::foo` + kw::Crate + } else { return; } - - if is_abs_external || is_abs_crate { - span_lint( - cx, - ABSOLUTE_PATHS, - path.span, - "consider bringing this path into scope with the `use` keyword", - ); - } + && !path.span.from_expansion() + && let node = cx.tcx.hir_node(hir_id) + && !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(..))) + && !self.absolute_paths_allowed_crates.contains(&crate_name) + && !is_from_proc_macro(cx, path) + { + span_lint( + cx, + ABSOLUTE_PATHS, + path.span, + "consider bringing this path into scope with the `use` keyword", + ); } } } diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 7f2234b310b4..2bd6837d973b 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -123,16 +123,14 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) { fn path_search_pat(path: &Path<'_>) -> (Pat, Pat) { let (head, tail) = match path.segments { - [head, .., tail] => (head, tail), - [p] => (p, p), [] => return (Pat::Str(""), Pat::Str("")), + [p] => (Pat::Sym(p.ident.name), p), + // QPath::Resolved can have a path that looks like `::baz` where + // the path (`Bar::baz`) has it's span covering the whole QPath. + [.., tail] => (Pat::Str(""), tail), }; ( - if head.ident.name == kw::PathRoot { - Pat::Str("::") - } else { - Pat::Sym(head.ident.name) - }, + head, if tail.args.is_some() { Pat::Str(">") } else { diff --git a/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr b/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr index 1cc1034cd89b..d24b0cd61629 100644 --- a/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr +++ b/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr @@ -1,29 +1,44 @@ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:5 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13 | -LL | std::f32::MAX; - | ^^^^^^^^^^^^^ +LL | let _ = std::path::is_separator(' '); + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::absolute-paths` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]` +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13 + | +LL | let _ = ::std::path::MAIN_SEPARATOR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13 + | +LL | let _ = std::collections::hash_map::HashMap::::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:41:5 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31 | -LL | core::f32::MAX; - | ^^^^^^^^^^^^^^ +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:42:5 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13 | -LL | ::core::f32::MAX; - | ^^^^^^^^^^^^^^^^ +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:58:5 + --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13 | -LL | ::std::f32::MAX; - | ^^^^^^^^^^^^^^^ +LL | let _ = std::option::Option::None::; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors diff --git a/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr b/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr new file mode 100644 index 000000000000..0cc6566af3a9 --- /dev/null +++ b/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr @@ -0,0 +1,14 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13 + | +LL | let _ = std::collections::hash_map::HashMap::::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/absolute_paths/absolute_paths.default.stderr b/tests/ui-toml/absolute_paths/absolute_paths.default.stderr new file mode 100644 index 000000000000..53aa9030e0dd --- /dev/null +++ b/tests/ui-toml/absolute_paths/absolute_paths.default.stderr @@ -0,0 +1,80 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13 + | +LL | let _ = std::path::is_separator(' '); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13 + | +LL | let _ = ::std::path::MAIN_SEPARATOR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13 + | +LL | let _ = std::collections::hash_map::HashMap::::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31 + | +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13 + | +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13 + | +LL | let _ = ::core::clone::Clone::clone(&0i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13 + | +LL | let _ = ::clone(&0i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13 + | +LL | let _ = std::option::Option::None::; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17 + | +LL | impl core::fmt::Display for X + | ^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18 + | +LL | where T: core::clone::Clone + | ^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32 + | +LL | impl core::fmt::Display for X + | ^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5 + | +LL | crate::m1::S + | ^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + diff --git a/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr b/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr deleted file mode 100644 index f342ebf6632e..000000000000 --- a/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr +++ /dev/null @@ -1,71 +0,0 @@ -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:5 - | -LL | std::f32::MAX; - | ^^^^^^^^^^^^^ - | - = note: `-D clippy::absolute-paths` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]` - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:41:5 - | -LL | core::f32::MAX; - | ^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:42:5 - | -LL | ::core::f32::MAX; - | ^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:5 - | -LL | crate::a::b::c::C; - | ^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:44:5 - | -LL | crate::a::b::c::d::e::f::F; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:45:5 - | -LL | crate::a::A; - | ^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:46:5 - | -LL | crate::a::b::B; - | ^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:47:5 - | -LL | crate::a::b::c::C::ZERO; - | ^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:48:5 - | -LL | helper::b::c::d::e::f(); - | ^^^^^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:49:5 - | -LL | ::helper::b::c::d::e::f(); - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: consider bringing this path into scope with the `use` keyword - --> tests/ui-toml/absolute_paths/absolute_paths.rs:58:5 - | -LL | ::std::f32::MAX; - | ^^^^^^^^^^^^^^^ - -error: aborting due to 11 previous errors - diff --git a/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr b/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr new file mode 100644 index 000000000000..70d71f6c4ea1 --- /dev/null +++ b/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr @@ -0,0 +1,98 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13 + | +LL | let _ = std::path::is_separator(' '); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13 + | +LL | let _ = ::std::path::MAIN_SEPARATOR; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13 + | +LL | let _ = std::collections::hash_map::HashMap::::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31 + | +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13 + | +LL | let _: &std::path::Path = std::path::Path::new(""); + | ^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13 + | +LL | let _ = ::core::clone::Clone::clone(&0i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13 + | +LL | let _ = ::clone(&0i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13 + | +LL | let _ = std::option::Option::None::; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17 + | +LL | impl core::fmt::Display for X + | ^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18 + | +LL | where T: core::clone::Clone + | ^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32 + | +LL | impl core::fmt::Display for X + | ^^^^^^^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:14 + | +LL | pub const _: crate::S = { + | ^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:114:9 + | +LL | let crate::S = m1::S; + | ^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5 + | +LL | crate::m1::S + | ^^^^^^^^^^^^ + +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths.rs:122:14 + | +LL | let _ = ::clone(&m1::S); + | ^^^^^^^^ + +error: aborting due to 15 previous errors + diff --git a/tests/ui-toml/absolute_paths/absolute_paths.rs b/tests/ui-toml/absolute_paths/absolute_paths.rs index a828701bcee9..c024f2f513ce 100644 --- a/tests/ui-toml/absolute_paths/absolute_paths.rs +++ b/tests/ui-toml/absolute_paths/absolute_paths.rs @@ -1,97 +1,123 @@ //@aux-build:../../ui/auxiliary/proc_macros.rs -//@aux-build:helper.rs -//@revisions: allow_crates disallow_crates +//@revisions: default allow_crates allow_long no_short +//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default //@[allow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates -//@[disallow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/disallow_crates -#![allow(clippy::no_effect, clippy::legacy_numeric_constants, unused)] -#![warn(clippy::absolute_paths)] -#![feature(decl_macro)] +//@[allow_long] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_long +//@[no_short] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/no_short +#![deny(clippy::absolute_paths)] -extern crate helper; -#[macro_use] extern crate proc_macros; +use proc_macros::{external, inline_macros, with_span}; -pub mod a { - pub mod b { - pub mod c { - pub struct C; +#[inline_macros] +fn main() { + let _ = std::path::is_separator(' '); + //~[default]^ absolute_paths + //~[allow_crates]| absolute_paths + //~[no_short]| absolute_paths - impl C { - pub const ZERO: u32 = 0; - } + // Make sure this is treated as having three path segments, not four. + let _ = ::std::path::MAIN_SEPARATOR; + //~[default]^ absolute_paths + //~[allow_crates]| absolute_paths + //~[no_short]| absolute_paths - pub mod d { - pub mod e { - pub mod f { - pub struct F; - } - } - } - } + let _ = std::collections::hash_map::HashMap::::new(); //~ absolute_paths - pub struct B; - } + // Note `std::path::Path::new` is treated as having three parts + let _: &std::path::Path = std::path::Path::new(""); + //~[default]^ absolute_paths + //~[default]| absolute_paths + //~[allow_crates]| absolute_paths + //~[allow_crates]| absolute_paths + //~[no_short]| absolute_paths + //~[no_short]| absolute_paths - pub struct A; -} + // Treated as having three parts. + let _ = ::core::clone::Clone::clone(&0i32); + //~[default]^ absolute_paths + //~[no_short]| absolute_paths + let _ = ::clone(&0i32); + //~[default]^ absolute_paths + //~[no_short]| absolute_paths + let _ = std::option::Option::None::; + //~[default]^ absolute_paths + //~[allow_crates]| absolute_paths + //~[no_short]| absolute_paths -fn main() { - f32::max(1.0, 2.0); - std::f32::MAX; - core::f32::MAX; - ::core::f32::MAX; - crate::a::b::c::C; - crate::a::b::c::d::e::f::F; - crate::a::A; - crate::a::b::B; - crate::a::b::c::C::ZERO; - helper::b::c::d::e::f(); - ::helper::b::c::d::e::f(); - fn b() -> a::b::B { - todo!() + { + // FIXME: macro calls should be checked. + let x = 1i32; + let _ = core::ptr::addr_of!(x); } - std::println!("a"); - let x = 1; - std::ptr::addr_of!(x); - // Test we handle max segments with `PathRoot` properly; this has 4 segments but we should say it - // has 3 - ::std::f32::MAX; - // Do not lint due to the above - ::helper::a(); - // Do not lint - helper::a(); - use crate::a::b::c::C; - use a::b; - use std::f32::MAX; - a::b::c::d::e::f::F; - b::c::C; - fn a() -> a::A { - todo!() - } - use a::b::c; - fn c() -> c::C { - todo!() + { + // FIXME: derive macro paths should be checked. + #[derive(core::clone::Clone)] + struct S; } - fn d() -> Result<(), ()> { - todo!() + + { + use core::fmt; + use core::marker::PhantomData; + + struct X(PhantomData); + impl core::fmt::Display for X + //~[default]^ absolute_paths + //~[default]| absolute_paths + //~[no_short]| absolute_paths + //~[no_short]| absolute_paths + where T: core::clone::Clone + //~[no_short]^ absolute_paths + //~[default]| absolute_paths + { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } + } } - external! { - crate::a::b::c::C::ZERO; + + { + mod m1 { + pub(crate) mod m2 { + pub(crate) const FOO: i32 = 0; + } + } + let _ = m1::m2::FOO; } - // For some reason, `path.span.from_expansion()` takes care of this for us + with_span! { span - crate::a::b::c::C::ZERO; + let _ = std::path::is_separator(' '); } - macro_rules! local_crate { - () => { - crate::a::b::c::C::ZERO; - }; + + external! { + let _ = std::path::is_separator(' '); } - macro local_crate_2_0() { - crate::a::b::c::C::ZERO; + + inline! { + let _ = std::path::is_separator(' '); } - local_crate!(); - local_crate_2_0!(); +} + +pub use core::cmp::Ordering; +pub use std::fs::File; + +#[derive(Clone)] +pub struct S; +mod m1 { + pub use crate::S; +} + +//~[no_short]v absolute_paths +pub const _: crate::S = { + let crate::S = m1::S; //~[no_short] absolute_paths + + crate::m1::S + //~[default]^ absolute_paths + //~[no_short]| absolute_paths +}; + +pub fn f() { + let _ = ::clone(&m1::S); //~[no_short] absolute_paths } diff --git a/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr b/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr new file mode 100644 index 000000000000..6fc495f01808 --- /dev/null +++ b/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr @@ -0,0 +1,14 @@ +error: consider bringing this path into scope with the `use` keyword + --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:15:13 + | +LL | let _ = ::m1::m2::X; + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:6:9 + | +LL | #![deny(clippy::absolute_paths)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui-toml/absolute_paths/absolute_paths_2015.rs b/tests/ui-toml/absolute_paths/absolute_paths_2015.rs new file mode 100644 index 000000000000..033c47809191 --- /dev/null +++ b/tests/ui-toml/absolute_paths/absolute_paths_2015.rs @@ -0,0 +1,16 @@ +//@revisions: default allow_crates +//@[default]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default +//@[allow_crates]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates +//@edition:2015 + +#![deny(clippy::absolute_paths)] + +mod m1 { + pub mod m2 { + pub struct X; + } +} + +fn main() { + let _ = ::m1::m2::X; //~[default] absolute_paths +} diff --git a/tests/ui-toml/absolute_paths/allow_crates/clippy.toml b/tests/ui-toml/absolute_paths/allow_crates/clippy.toml index 59a621e9d1db..9da49abcd31f 100644 --- a/tests/ui-toml/absolute_paths/allow_crates/clippy.toml +++ b/tests/ui-toml/absolute_paths/allow_crates/clippy.toml @@ -1,2 +1 @@ -absolute-paths-max-segments = 2 -absolute-paths-allowed-crates = ["crate", "helper"] +absolute-paths-allowed-crates = ["core", "crate"] diff --git a/tests/ui-toml/absolute_paths/allow_long/clippy.toml b/tests/ui-toml/absolute_paths/allow_long/clippy.toml new file mode 100644 index 000000000000..5992fd1ed821 --- /dev/null +++ b/tests/ui-toml/absolute_paths/allow_long/clippy.toml @@ -0,0 +1 @@ +absolute-paths-max-segments = 3 diff --git a/tests/ui-toml/absolute_paths/auxiliary/helper.rs b/tests/ui-toml/absolute_paths/auxiliary/helper.rs deleted file mode 100644 index 8e2678f5fe69..000000000000 --- a/tests/ui-toml/absolute_paths/auxiliary/helper.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub fn a() {} - -pub mod b { - pub mod c { - pub mod d { - pub mod e { - pub fn f() {} - } - } - } -} diff --git a/tests/ui-toml/absolute_paths/default/clippy.toml b/tests/ui-toml/absolute_paths/default/clippy.toml new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml b/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml deleted file mode 100644 index d44d648c6411..000000000000 --- a/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml +++ /dev/null @@ -1 +0,0 @@ -absolute-paths-max-segments = 2 diff --git a/tests/ui-toml/absolute_paths/no_short/clippy.toml b/tests/ui-toml/absolute_paths/no_short/clippy.toml new file mode 100644 index 000000000000..357524420c5a --- /dev/null +++ b/tests/ui-toml/absolute_paths/no_short/clippy.toml @@ -0,0 +1 @@ +absolute-paths-max-segments = 0