Skip to content

Commit ca4fc54

Browse files
authored
Rollup merge of #113811 - jieyouxu:fix-unused-qualifications-suggestion, r=oli-obk
Fix removal span calculation of `unused_qualifications` suggestion Given a path such as `std::ops::Index<str>`, calculate the unnecessary qualification removal span by computing the beginning of the entire span until the ident span of the last path segment, which handles generic arguments and lifetime arguments in the last path segment. Previous logic only kept the ident span of the last path segment which is incorrect. Closes #113808.
2 parents b3893c5 + 33bd453 commit ca4fc54

10 files changed

+138
-22
lines changed

compiler/rustc_lint/src/context.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -956,11 +956,11 @@ pub trait LintContext: Sized {
956956
db.span_note(glob_reexport_span, format!("the name `{}` in the {} namespace is supposed to be publicly re-exported here", name, namespace));
957957
db.span_note(private_item_span, "but the private item here shadows it".to_owned());
958958
}
959-
BuiltinLintDiagnostics::UnusedQualifications { path_span, unqualified_path } => {
959+
BuiltinLintDiagnostics::UnusedQualifications { removal_span } => {
960960
db.span_suggestion_verbose(
961-
path_span,
962-
"replace it with the unqualified path",
963-
unqualified_path,
961+
removal_span,
962+
"remove the unnecessary path segments",
963+
"",
964964
Applicability::MachineApplicable
965965
);
966966
}

compiler/rustc_lint_defs/src/lib.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -551,10 +551,8 @@ pub enum BuiltinLintDiagnostics {
551551
private_item_span: Span,
552552
},
553553
UnusedQualifications {
554-
/// The span of the unnecessarily-qualified path.
555-
path_span: Span,
556-
/// The replacement unqualified path.
557-
unqualified_path: Ident,
554+
/// The span of the unnecessarily-qualified path to remove.
555+
removal_span: Span,
558556
},
559557
}
560558

compiler/rustc_resolve/src/late.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3911,8 +3911,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
39113911
&& path[0].ident.name != kw::PathRoot
39123912
&& path[0].ident.name != kw::DollarCrate
39133913
{
3914+
let last_segment = *path.last().unwrap();
39143915
let unqualified_result = {
3915-
match self.resolve_path(&[*path.last().unwrap()], Some(ns), None) {
3916+
match self.resolve_path(&[last_segment], Some(ns), None) {
39163917
PathResult::NonModule(path_res) => path_res.expect_full_res(),
39173918
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
39183919
module.res().unwrap()
@@ -3928,8 +3929,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
39283929
finalize.path_span,
39293930
"unnecessary qualification",
39303931
lint::BuiltinLintDiagnostics::UnusedQualifications {
3931-
path_span: finalize.path_span,
3932-
unqualified_path: path.last().unwrap().ident
3932+
removal_span: finalize.path_span.until(last_segment.ident.span),
39333933
}
39343934
)
39353935
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// run-rustfix
2+
#![deny(unused_qualifications)]
3+
#![allow(deprecated)]
4+
5+
mod foo {
6+
pub fn bar() {}
7+
}
8+
9+
fn main() {
10+
use foo::bar;
11+
bar(); //~ ERROR: unnecessary qualification
12+
bar();
13+
14+
let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
15+
16+
macro_rules! m { () => {
17+
$crate::foo::bar(); // issue #37357
18+
::foo::bar(); // issue #38682
19+
} }
20+
m!();
21+
}

tests/ui/lint/lint-qualification.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// run-rustfix
12
#![deny(unused_qualifications)]
23
#![allow(deprecated)]
34

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
error: unnecessary qualification
2-
--> $DIR/lint-qualification.rs:10:5
2+
--> $DIR/lint-qualification.rs:11:5
33
|
44
LL | foo::bar();
55
| ^^^^^^^^
66
|
77
note: the lint level is defined here
8-
--> $DIR/lint-qualification.rs:1:9
8+
--> $DIR/lint-qualification.rs:2:9
99
|
1010
LL | #![deny(unused_qualifications)]
1111
| ^^^^^^^^^^^^^^^^^^^^^
12-
help: replace it with the unqualified path
12+
help: remove the unnecessary path segments
13+
|
14+
LL - foo::bar();
15+
LL + bar();
1316
|
14-
LL | bar();
15-
| ~~~
1617

1718
error: aborting due to previous error
1819

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// run-rustfix
2+
3+
#![deny(unused_qualifications)]
4+
#![feature(unsized_fn_params)]
5+
6+
#[allow(unused_imports)]
7+
use std::ops;
8+
use std::ops::Index;
9+
10+
pub struct A;
11+
12+
impl Index<str> for A {
13+
//~^ ERROR unnecessary qualification
14+
type Output = ();
15+
fn index(&self, _: str) -> &Self::Output {
16+
&()
17+
}
18+
}
19+
20+
mod inner {
21+
pub trait Trait<T> {}
22+
}
23+
24+
// the import needs to be here for the lint to show up
25+
#[allow(unused_imports)]
26+
use inner::Trait;
27+
28+
impl Trait<u8> for () {}
29+
//~^ ERROR unnecessary qualification
30+
31+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// run-rustfix
2+
3+
#![deny(unused_qualifications)]
4+
#![feature(unsized_fn_params)]
5+
6+
#[allow(unused_imports)]
7+
use std::ops;
8+
use std::ops::Index;
9+
10+
pub struct A;
11+
12+
impl ops::Index<str> for A {
13+
//~^ ERROR unnecessary qualification
14+
type Output = ();
15+
fn index(&self, _: str) -> &Self::Output {
16+
&()
17+
}
18+
}
19+
20+
mod inner {
21+
pub trait Trait<T> {}
22+
}
23+
24+
// the import needs to be here for the lint to show up
25+
#[allow(unused_imports)]
26+
use inner::Trait;
27+
28+
impl inner::Trait<u8> for () {}
29+
//~^ ERROR unnecessary qualification
30+
31+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error: unnecessary qualification
2+
--> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:12:6
3+
|
4+
LL | impl ops::Index<str> for A {
5+
| ^^^^^^^^^^^^^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:3:9
9+
|
10+
LL | #![deny(unused_qualifications)]
11+
| ^^^^^^^^^^^^^^^^^^^^^
12+
help: remove the unnecessary path segments
13+
|
14+
LL - impl ops::Index<str> for A {
15+
LL + impl Index<str> for A {
16+
|
17+
18+
error: unnecessary qualification
19+
--> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:28:6
20+
|
21+
LL | impl inner::Trait<u8> for () {}
22+
| ^^^^^^^^^^^^^^^^
23+
|
24+
help: remove the unnecessary path segments
25+
|
26+
LL - impl inner::Trait<u8> for () {}
27+
LL + impl Trait<u8> for () {}
28+
|
29+
30+
error: aborting due to 2 previous errors
31+

tests/ui/resolve/unused-qualifications-suggestion.stderr

+8-6
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,23 @@ note: the lint level is defined here
99
|
1010
LL | #![deny(unused_qualifications)]
1111
| ^^^^^^^^^^^^^^^^^^^^^
12-
help: replace it with the unqualified path
12+
help: remove the unnecessary path segments
13+
|
14+
LL - foo::bar();
15+
LL + bar();
1316
|
14-
LL | bar();
15-
| ~~~
1617

1718
error: unnecessary qualification
1819
--> $DIR/unused-qualifications-suggestion.rs:21:5
1920
|
2021
LL | baz::qux::quux();
2122
| ^^^^^^^^^^^^^^
2223
|
23-
help: replace it with the unqualified path
24+
help: remove the unnecessary path segments
25+
|
26+
LL - baz::qux::quux();
27+
LL + quux();
2428
|
25-
LL | quux();
26-
| ~~~~
2729

2830
error: aborting due to 2 previous errors
2931

0 commit comments

Comments
 (0)