Skip to content

Commit 8317fef

Browse files
committed
Auto merge of #152996 - mu001999-contrib:feat/extend-import-self, r=petrochenkov
Replacing `self` overwriting with proper resolution Reference PR: - rust-lang/reference#2221 As a follow-up PR to #146972 ([step 1](#152996 (comment))), after this PR: ~~1. Trailing `self` can appear in paths (as the consensus in #146972 (comment) (in future) ~~2. [E0429](https://doc.rust-lang.org/stable/error_codes/E0429.html#error-code-e0429) will be no longer emitted, `use ...::self [as target];` will be equivalent to `use ...::{self [as target]};`~~ (in future) 3. Things like `struct S {}; use S::{self as Other};` will be rejected --- This PR used to add a new lint `redundant_self`, which would lint `use ...::self [as target];` and `use ...::{self [as target]};`, and fixes all warnings emitted by this lint. But this lint and clippy lint [unnecessary_self_imports](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports) have some overlap. And `use std::io::self;` is not equivalent to `use std::io` in fact for now, the new lint will also cause the following known issue: > Removing `::{self}` will cause any non-module items at the same path to also be imported. This might cause a naming conflict (rust-lang/rustfmt#3568). So I removed this lint, and I think what it does should be done by extending the clippy lint `unnecessary_self_imports`. r? petrochenkov
2 parents 25a54d4 + eb00f78 commit 8317fef

21 files changed

+1268
-101
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -626,42 +626,42 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
626626

627627
match use_tree.kind {
628628
ast::UseTreeKind::Simple(rename) => {
629-
let mut ident = use_tree.ident();
630629
let mut module_path = prefix;
631-
let mut source = module_path.pop().unwrap();
630+
let source = module_path.pop().unwrap();
632631

633632
// `true` for `...::{self [as target]}` imports, `false` otherwise.
634633
let type_ns_only = nested && source.ident.name == kw::SelfLower;
635634

635+
// Suggest `use prefix::{self};` for `use prefix::self;`
636636
if source.ident.name == kw::SelfLower
637-
&& let Some(parent) = module_path.pop()
637+
&& let Some(parent) = module_path.last()
638+
&& !type_ns_only
639+
&& (parent.ident.name != kw::PathRoot
640+
|| self.r.path_root_is_crate_root(parent.ident))
638641
{
639-
// Suggest `use prefix::{self};` for `use prefix::self;`
640-
if !type_ns_only
641-
&& (parent.ident.name != kw::PathRoot
642-
|| self.r.path_root_is_crate_root(parent.ident))
643-
{
644-
let span_with_rename = match rename {
645-
Some(rename) => source.ident.span.to(rename.span),
646-
None => source.ident.span,
647-
};
648-
649-
self.r.report_error(
650-
parent.ident.span.shrink_to_hi().to(source.ident.span),
651-
ResolutionError::SelfImportsOnlyAllowedWithin {
652-
root: parent.ident.name == kw::PathRoot,
653-
span_with_rename,
654-
},
655-
);
656-
}
642+
let span_with_rename = match rename {
643+
Some(rename) => source.ident.span.to(rename.span),
644+
None => source.ident.span,
645+
};
657646

658-
let self_span = source.ident.span;
659-
source = parent;
660-
if rename.is_none() {
661-
ident = Ident::new(source.ident.name, self_span);
662-
}
647+
self.r.report_error(
648+
parent.ident.span.shrink_to_hi().to(source.ident.span),
649+
ResolutionError::SelfImportsOnlyAllowedWithin {
650+
root: parent.ident.name == kw::PathRoot,
651+
span_with_rename,
652+
},
653+
);
663654
}
664655

656+
let ident = if source.ident.name == kw::SelfLower
657+
&& rename.is_none()
658+
&& let Some(parent) = module_path.last()
659+
{
660+
Ident::new(parent.ident.name, source.ident.span)
661+
} else {
662+
use_tree.ident()
663+
};
664+
665665
match source.ident.name {
666666
kw::DollarCrate => {
667667
if !module_path.is_empty() {
@@ -698,7 +698,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
698698
}
699699
}
700700
// Deny `use ::{self};` after edition 2015
701-
kw::PathRoot if !self.r.path_root_is_crate_root(source.ident) => {
701+
kw::SelfLower
702+
if let Some(parent) = module_path.last()
703+
&& parent.ident.name == kw::PathRoot
704+
&& !self.r.path_root_is_crate_root(parent.ident) =>
705+
{
702706
self.r.dcx().span_err(use_tree.span(), "extern prelude cannot be imported");
703707
return;
704708
}

compiler/rustc_resolve/src/ident.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -959,12 +959,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
959959
) -> Result<Decl<'ra>, Determinacy> {
960960
match module {
961961
ModuleOrUniformRoot::Module(module) => {
962-
if ns == TypeNS
963-
&& ident.name == kw::Super
964-
&& let Some(module) =
965-
self.resolve_super_in_module(ident, Some(module), parent_scope)
966-
{
967-
return Ok(module.self_decl.unwrap());
962+
if ns == TypeNS {
963+
if ident.name == kw::SelfLower {
964+
return Ok(module.self_decl.unwrap());
965+
}
966+
if ident.name == kw::Super
967+
&& let Some(module) =
968+
self.resolve_super_in_module(ident, Some(module), parent_scope)
969+
{
970+
return Ok(module.self_decl.unwrap());
971+
}
968972
}
969973

970974
let (ident_key, def) = IdentKey::new_adjusted(ident, module.expansion);
@@ -1032,7 +1036,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10321036
{
10331037
let module = self.resolve_crate_root(ident);
10341038
return Ok(module.self_decl.unwrap());
1035-
} else if ident.name == kw::Super || ident.name == kw::SelfLower {
1039+
} else if ident.name == kw::Super {
10361040
// FIXME: Implement these with renaming requirements so that e.g.
10371041
// `use super;` doesn't work, but `use super as name;` does.
10381042
// Fall through here to get an error from `early_resolve_...`.

tests/ui/imports/cycle-import-in-std-1.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
error[E0432]: unresolved import `ops`
2-
--> $DIR/cycle-import-in-std-1.rs:5:11
2+
--> $DIR/cycle-import-in-std-1.rs:5:5
33
|
44
LL | use ops::{self as std};
5-
| ^^^^^^^^^^^ no external crate `ops`
5+
| ^^^
66
|
7-
= help: consider importing this module instead:
8-
std::ops
7+
help: a similar path exists
8+
|
9+
LL | use core::ops::{self as std};
10+
| ++++++
911

1012
error: aborting due to 1 previous error
1113

tests/ui/imports/cycle-import-in-std-2.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
error[E0432]: unresolved import `ops`
2-
--> $DIR/cycle-import-in-std-2.rs:5:11
2+
--> $DIR/cycle-import-in-std-2.rs:5:5
33
|
44
LL | use ops::{self as std};
5-
| ^^^^^^^^^^^ no external crate `ops`
5+
| ^^^
66
|
7-
= help: consider importing this module instead:
8-
std::ops
7+
help: a similar path exists
8+
|
9+
LL | use core::ops::{self as std};
10+
| ++++++
911

1012
error: aborting due to 1 previous error
1113

tests/ui/imports/issue-28388-1.stderr

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0432]: unresolved import `foo`
22
--> $DIR/issue-28388-1.rs:4:5
33
|
44
LL | use foo::{};
5-
| ^^^ no `foo` in the root
5+
| ^^^ use of unresolved module or unlinked crate `foo`
6+
|
7+
help: you might be missing a crate named `foo`, add it to your project and import it in your code
8+
|
9+
LL + extern crate foo;
10+
|
611

712
error: aborting due to 1 previous error
813

tests/ui/imports/issue-38293.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0432]: unresolved import `foo::f`
2-
--> $DIR/issue-38293.rs:7:14
2+
--> $DIR/issue-38293.rs:7:10
33
|
44
LL | use foo::f::{self};
5-
| ^^^^ no `f` in `foo`
5+
| ^ expected type, found function `f` in `foo`
66

77
error[E0423]: expected function, found module `baz`
88
--> $DIR/issue-38293.rs:16:5

tests/ui/imports/issue-45829/import-self.stderr

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ LL | use foo::self;
4747
= note: `foo` must be defined only once in the type namespace of this module
4848
help: you can use `as` to change the binding name of the import
4949
|
50-
LL - use foo::self;
51-
LL + use foo as other_foo;
52-
|
50+
LL | use foo::self as other_foo;
51+
| ++++++++++++
5352

5453
error[E0252]: the name `A` is defined multiple times
5554
--> $DIR/import-self.rs:16:11

tests/ui/privacy/private-variant-reexport.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod m2 {
88
}
99

1010
mod m3 {
11-
pub use ::E::V::{self}; //~ ERROR `V` is only public within the crate, and cannot be re-exported outside
11+
pub use ::E::V::{self}; //~ ERROR unresolved import `E::V`
1212
}
1313

1414
#[deny(unused_imports)]

tests/ui/privacy/private-variant-reexport.stderr

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ note: consider marking `V` as `pub` in the imported module
2222
LL | pub use ::E::{V};
2323
| ^
2424

25-
error[E0365]: `V` is only public within the crate, and cannot be re-exported outside
26-
--> $DIR/private-variant-reexport.rs:11:22
25+
error[E0432]: unresolved import `E::V`
26+
--> $DIR/private-variant-reexport.rs:11:18
2727
|
2828
LL | pub use ::E::V::{self};
29-
| ^^^^ re-export of crate public `V`
30-
|
31-
= note: consider declaring type or module `V` with `pub`
29+
| ^ `V` is a variant, not a module
3230

3331
error: glob import doesn't reexport anything with visibility `pub` because no imported item is public enough
3432
--> $DIR/private-variant-reexport.rs:16:13
@@ -56,5 +54,5 @@ LL | pub use ::E::*;
5654

5755
error: aborting due to 5 previous errors
5856

59-
Some errors have detailed explanations: E0364, E0365.
57+
Some errors have detailed explanations: E0364, E0432.
6058
For more information about an error, try `rustc --explain E0364`.

tests/ui/resolve/resolve-bad-import-prefix.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use {}; // OK
88
use ::{}; // OK
99
use m::{}; // OK
1010
use E::{}; // OK
11-
use S::{}; // FIXME, this and `use S::{self};` should be an error
11+
use S::{}; //~ ERROR unresolved import `S`
1212
use Tr::{}; // FIXME, this and `use Tr::{self};` should be an error
1313
use Nonexistent::{}; //~ ERROR unresolved import `Nonexistent`
1414

0 commit comments

Comments
 (0)