Refactor absolute_paths
:
* Check the path length first * Use `is_from_proc_macro` * Use symbols instead of strings when checking crate names
This commit is contained in:
parent
1c81105b43
commit
f9509d3574
@ -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_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 @@
|
||||
/// 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,66 @@
|
||||
|
||||
pub struct AbsolutePaths {
|
||||
pub absolute_paths_max_segments: u64,
|
||||
pub absolute_paths_allowed_crates: &'static FxHashSet<String>,
|
||||
pub absolute_paths_allowed_crates: FxHashSet<Symbol>,
|
||||
}
|
||||
|
||||
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",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 `<Foo as Bar>::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 {
|
||||
|
@ -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:41:5
|
||||
--> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13
|
||||
|
|
||||
LL | core::f32::MAX;
|
||||
| ^^^^^^^^^^^^^^
|
||||
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:42:5
|
||||
--> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
|
||||
|
|
||||
LL | ::core::f32::MAX;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
LL | let _ = std::collections::hash_map::HashMap::<i32, i32>::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:28:31
|
||||
|
|
||||
LL | ::std::f32::MAX;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
LL | let _: &std::path::Path = std::path::Path::new("");
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
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:43:13
|
||||
|
|
||||
LL | let _ = std::option::Option::None::<i32>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -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::<i32, i32>::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
|
||||
|
80
tests/ui-toml/absolute_paths/absolute_paths.default.stderr
Normal file
80
tests/ui-toml/absolute_paths/absolute_paths.default.stderr
Normal file
@ -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::<i32, i32>::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 _ = <i32 as core::clone::Clone>::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::<i32>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: consider bringing this path into scope with the `use` keyword
|
||||
--> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17
|
||||
|
|
||||
LL | impl<T: core::cmp::Eq> core::fmt::Display for X<T>
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
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<T: core::cmp::Eq> core::fmt::Display for X<T>
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
98
tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr
Normal file
98
tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr
Normal file
@ -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::<i32, i32>::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 _ = <i32 as core::clone::Clone>::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::<i32>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: consider bringing this path into scope with the `use` keyword
|
||||
--> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17
|
||||
|
|
||||
LL | impl<T: core::cmp::Eq> core::fmt::Display for X<T>
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
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<T: core::cmp::Eq> core::fmt::Display for X<T>
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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 _ = <crate::S as Clone>::clone(&m1::S);
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
|
@ -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::<i32, i32>::new(); //~ absolute_paths
|
||||
|
||||
// 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
|
||||
|
||||
// Treated as having three parts.
|
||||
let _ = ::core::clone::Clone::clone(&0i32);
|
||||
//~[default]^ absolute_paths
|
||||
//~[no_short]| absolute_paths
|
||||
let _ = <i32 as core::clone::Clone>::clone(&0i32);
|
||||
//~[default]^ absolute_paths
|
||||
//~[no_short]| absolute_paths
|
||||
let _ = std::option::Option::None::<i32>;
|
||||
//~[default]^ absolute_paths
|
||||
//~[allow_crates]| absolute_paths
|
||||
//~[no_short]| absolute_paths
|
||||
|
||||
{
|
||||
// FIXME: macro calls should be checked.
|
||||
let x = 1i32;
|
||||
let _ = core::ptr::addr_of!(x);
|
||||
}
|
||||
|
||||
{
|
||||
// FIXME: derive macro paths should be checked.
|
||||
#[derive(core::clone::Clone)]
|
||||
struct S;
|
||||
}
|
||||
|
||||
{
|
||||
use core::fmt;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
struct X<T>(PhantomData<T>);
|
||||
impl<T: core::cmp::Eq> core::fmt::Display for X<T>
|
||||
//~[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(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct B;
|
||||
}
|
||||
|
||||
pub struct A;
|
||||
}
|
||||
{
|
||||
mod m1 {
|
||||
pub(crate) mod m2 {
|
||||
pub(crate) const FOO: i32 = 0;
|
||||
}
|
||||
}
|
||||
let _ = m1::m2::FOO;
|
||||
}
|
||||
|
||||
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!()
|
||||
}
|
||||
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!()
|
||||
}
|
||||
fn d() -> Result<(), ()> {
|
||||
todo!()
|
||||
}
|
||||
external! {
|
||||
crate::a::b::c::C::ZERO;
|
||||
}
|
||||
// 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 _ = <crate::S as Clone>::clone(&m1::S); //~[no_short] absolute_paths
|
||||
}
|
||||
|
@ -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
|
||||
|
16
tests/ui-toml/absolute_paths/absolute_paths_2015.rs
Normal file
16
tests/ui-toml/absolute_paths/absolute_paths_2015.rs
Normal file
@ -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
|
||||
}
|
@ -1,2 +1 @@
|
||||
absolute-paths-max-segments = 2
|
||||
absolute-paths-allowed-crates = ["crate", "helper"]
|
||||
absolute-paths-allowed-crates = ["core", "crate"]
|
||||
|
1
tests/ui-toml/absolute_paths/allow_long/clippy.toml
Normal file
1
tests/ui-toml/absolute_paths/allow_long/clippy.toml
Normal file
@ -0,0 +1 @@
|
||||
absolute-paths-max-segments = 3
|
@ -1,11 +0,0 @@
|
||||
pub fn a() {}
|
||||
|
||||
pub mod b {
|
||||
pub mod c {
|
||||
pub mod d {
|
||||
pub mod e {
|
||||
pub fn f() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
0
tests/ui-toml/absolute_paths/default/clippy.toml
Normal file
0
tests/ui-toml/absolute_paths/default/clippy.toml
Normal file
@ -1 +0,0 @@
|
||||
absolute-paths-max-segments = 2
|
1
tests/ui-toml/absolute_paths/no_short/clippy.toml
Normal file
1
tests/ui-toml/absolute_paths/no_short/clippy.toml
Normal file
@ -0,0 +1 @@
|
||||
absolute-paths-max-segments = 0
|
Loading…
Reference in New Issue
Block a user