Consider middle segments of paths in unused_qualifications
This commit is contained in:
parent
b6a23b8537
commit
4ea9f72c72
@ -4150,34 +4150,36 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||||||
PathResult::Indeterminate => bug!("indeterminate path result in resolve_qpath"),
|
PathResult::Indeterminate => bug!("indeterminate path result in resolve_qpath"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if path.len() > 1
|
if path.iter().all(|seg| !seg.ident.span.from_expansion()) {
|
||||||
&& let Some(res) = result.full_res()
|
let end_pos =
|
||||||
&& let Some((&last_segment, prev_segs)) = path.split_last()
|
path.iter().position(|seg| seg.has_generic_args).map_or(path.len(), |pos| pos + 1);
|
||||||
&& prev_segs.iter().all(|seg| !seg.has_generic_args)
|
let unqualified =
|
||||||
&& res != Res::Err
|
path[..end_pos].iter().enumerate().skip(1).rev().find_map(|(i, seg)| {
|
||||||
&& path[0].ident.name != kw::PathRoot
|
// Preserve the current namespace for the final path segment, but use the type
|
||||||
&& path[0].ident.name != kw::DollarCrate
|
// namespace for all preceding segments
|
||||||
{
|
//
|
||||||
let unqualified_result = {
|
// e.g. for `std::env::args` check the `ValueNS` for `args` but the `TypeNS` for
|
||||||
match self.resolve_path(&[last_segment], Some(ns), None) {
|
// `std` and `env`
|
||||||
PathResult::NonModule(path_res) => path_res.expect_full_res(),
|
//
|
||||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
|
// If the final path segment is beyond `end_pos` all the segments to check will
|
||||||
module.res().unwrap()
|
// use the type namespace
|
||||||
}
|
let ns = if i + 1 == path.len() { ns } else { TypeNS };
|
||||||
_ => return Ok(Some(result)),
|
let res = self.r.partial_res_map.get(&seg.id?)?.full_res()?;
|
||||||
}
|
let binding = self.resolve_ident_in_lexical_scope(seg.ident, ns, None, None)?;
|
||||||
};
|
|
||||||
if res == unqualified_result {
|
(res == binding.res()).then_some(seg)
|
||||||
let lint = lint::builtin::UNUSED_QUALIFICATIONS;
|
});
|
||||||
|
|
||||||
|
if let Some(unqualified) = unqualified {
|
||||||
self.r.lint_buffer.buffer_lint_with_diagnostic(
|
self.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||||
lint,
|
lint::builtin::UNUSED_QUALIFICATIONS,
|
||||||
finalize.node_id,
|
finalize.node_id,
|
||||||
finalize.path_span,
|
finalize.path_span,
|
||||||
"unnecessary qualification",
|
"unnecessary qualification",
|
||||||
lint::BuiltinLintDiagnostics::UnusedQualifications {
|
lint::BuiltinLintDiagnostics::UnusedQualifications {
|
||||||
removal_span: finalize.path_span.until(last_segment.ident.span),
|
removal_span: finalize.path_span.until(unqualified.ident.span),
|
||||||
},
|
},
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//@ run-rustfix
|
//@ run-rustfix
|
||||||
#![deny(unused_qualifications)]
|
#![deny(unused_qualifications)]
|
||||||
#![allow(deprecated)]
|
#![allow(deprecated, dead_code)]
|
||||||
|
|
||||||
mod foo {
|
mod foo {
|
||||||
pub fn bar() {}
|
pub fn bar() {}
|
||||||
@ -9,13 +9,37 @@ mod foo {
|
|||||||
fn main() {
|
fn main() {
|
||||||
use foo::bar;
|
use foo::bar;
|
||||||
bar(); //~ ERROR: unnecessary qualification
|
bar(); //~ ERROR: unnecessary qualification
|
||||||
|
bar(); //~ ERROR: unnecessary qualification
|
||||||
bar();
|
bar();
|
||||||
|
|
||||||
let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
|
let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
|
||||||
|
|
||||||
macro_rules! m { () => {
|
let _ = String::new(); //~ ERROR: unnecessary qualification
|
||||||
|
let _ = std::env::current_dir(); //~ ERROR: unnecessary qualification
|
||||||
|
|
||||||
|
let _: Vec<String> = Vec::<String>::new();
|
||||||
|
//~^ ERROR: unnecessary qualification
|
||||||
|
//~| ERROR: unnecessary qualification
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
let _: fmt::Result = Ok(()); //~ ERROR: unnecessary qualification
|
||||||
|
|
||||||
|
macro_rules! m { ($a:ident, $b:ident) => {
|
||||||
$crate::foo::bar(); // issue #37357
|
$crate::foo::bar(); // issue #37357
|
||||||
::foo::bar(); // issue #38682
|
::foo::bar(); // issue #38682
|
||||||
|
foo::bar();
|
||||||
|
foo::$b(); // issue #96698
|
||||||
|
$a::bar();
|
||||||
} }
|
} }
|
||||||
m!();
|
m!(foo, bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
mod conflicting_names {
|
||||||
|
mod std {}
|
||||||
|
mod cell {}
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
let _ = ::std::env::current_dir();
|
||||||
|
let _ = core::cell::Cell::new(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//@ run-rustfix
|
//@ run-rustfix
|
||||||
#![deny(unused_qualifications)]
|
#![deny(unused_qualifications)]
|
||||||
#![allow(deprecated)]
|
#![allow(deprecated, dead_code)]
|
||||||
|
|
||||||
mod foo {
|
mod foo {
|
||||||
pub fn bar() {}
|
pub fn bar() {}
|
||||||
@ -9,13 +9,37 @@ mod foo {
|
|||||||
fn main() {
|
fn main() {
|
||||||
use foo::bar;
|
use foo::bar;
|
||||||
foo::bar(); //~ ERROR: unnecessary qualification
|
foo::bar(); //~ ERROR: unnecessary qualification
|
||||||
|
crate::foo::bar(); //~ ERROR: unnecessary qualification
|
||||||
bar();
|
bar();
|
||||||
|
|
||||||
let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
|
let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
|
||||||
|
|
||||||
macro_rules! m { () => {
|
let _ = std::string::String::new(); //~ ERROR: unnecessary qualification
|
||||||
|
let _ = ::std::env::current_dir(); //~ ERROR: unnecessary qualification
|
||||||
|
|
||||||
|
let _: std::vec::Vec<String> = std::vec::Vec::<String>::new();
|
||||||
|
//~^ ERROR: unnecessary qualification
|
||||||
|
//~| ERROR: unnecessary qualification
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
let _: std::fmt::Result = Ok(()); //~ ERROR: unnecessary qualification
|
||||||
|
|
||||||
|
macro_rules! m { ($a:ident, $b:ident) => {
|
||||||
$crate::foo::bar(); // issue #37357
|
$crate::foo::bar(); // issue #37357
|
||||||
::foo::bar(); // issue #38682
|
::foo::bar(); // issue #38682
|
||||||
|
foo::bar();
|
||||||
|
foo::$b(); // issue #96698
|
||||||
|
$a::bar();
|
||||||
} }
|
} }
|
||||||
m!();
|
m!(foo, bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
mod conflicting_names {
|
||||||
|
mod std {}
|
||||||
|
mod cell {}
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
let _ = ::std::env::current_dir();
|
||||||
|
let _ = core::cell::Cell::new(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,77 @@ LL - foo::bar();
|
|||||||
LL + bar();
|
LL + bar();
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: unnecessary qualification
|
||||||
|
--> $DIR/lint-qualification.rs:12:5
|
||||||
|
|
|
||||||
|
LL | crate::foo::bar();
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: remove the unnecessary path segments
|
||||||
|
|
|
||||||
|
LL - crate::foo::bar();
|
||||||
|
LL + bar();
|
||||||
|
|
|
||||||
|
|
||||||
|
error: unnecessary qualification
|
||||||
|
--> $DIR/lint-qualification.rs:17:13
|
||||||
|
|
|
||||||
|
LL | let _ = std::string::String::new();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: remove the unnecessary path segments
|
||||||
|
|
|
||||||
|
LL - let _ = std::string::String::new();
|
||||||
|
LL + let _ = String::new();
|
||||||
|
|
|
||||||
|
|
||||||
|
error: unnecessary qualification
|
||||||
|
--> $DIR/lint-qualification.rs:18:13
|
||||||
|
|
|
||||||
|
LL | let _ = ::std::env::current_dir();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: remove the unnecessary path segments
|
||||||
|
|
|
||||||
|
LL - let _ = ::std::env::current_dir();
|
||||||
|
LL + let _ = std::env::current_dir();
|
||||||
|
|
|
||||||
|
|
||||||
|
error: unnecessary qualification
|
||||||
|
--> $DIR/lint-qualification.rs:20:12
|
||||||
|
|
|
||||||
|
LL | let _: std::vec::Vec<String> = std::vec::Vec::<String>::new();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: remove the unnecessary path segments
|
||||||
|
|
|
||||||
|
LL - let _: std::vec::Vec<String> = std::vec::Vec::<String>::new();
|
||||||
|
LL + let _: Vec<String> = std::vec::Vec::<String>::new();
|
||||||
|
|
|
||||||
|
|
||||||
|
error: unnecessary qualification
|
||||||
|
--> $DIR/lint-qualification.rs:20:36
|
||||||
|
|
|
||||||
|
LL | let _: std::vec::Vec<String> = std::vec::Vec::<String>::new();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: remove the unnecessary path segments
|
||||||
|
|
|
||||||
|
LL - let _: std::vec::Vec<String> = std::vec::Vec::<String>::new();
|
||||||
|
LL + let _: std::vec::Vec<String> = Vec::<String>::new();
|
||||||
|
|
|
||||||
|
|
||||||
|
error: unnecessary qualification
|
||||||
|
--> $DIR/lint-qualification.rs:25:12
|
||||||
|
|
|
||||||
|
LL | let _: std::fmt::Result = Ok(());
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: remove the unnecessary path segments
|
||||||
|
|
|
||||||
|
LL - let _: std::fmt::Result = Ok(());
|
||||||
|
LL + let _: fmt::Result = Ok(());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user