Skip to content

Commit dd31c0c

Browse files
committed
resolve: Reintroduce feature gate for uniform paths in imports
1 parent 686737c commit dd31c0c

30 files changed

+168
-80
lines changed

src/doc/unstable-book/src/language-features/extern-in-paths.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ introducing `extern crate` items, using keyword `extern`.
1111

1212
For example, `extern::my_crat::a::b` will resolve to path `a::b` in crate `my_crate`.
1313

14-
`feature(extern_absolute_paths)` mode provides the same effect by resolving absolute paths like
15-
`::my_crate::a::b` to paths from extern crates by default.
14+
Absolute paths on 2018 edition (e.g. `::my_crate::a::b`) provide the same effect
15+
and resolve to extern crates (built-in or passed with `--extern`).
1616

1717
```rust,ignore
1818
#![feature(extern_in_paths)]

src/librustc_resolve/lib.rs

+29-25
Original file line numberDiff line numberDiff line change
@@ -4670,6 +4670,34 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
46704670
}
46714671
}
46724672

4673+
fn binding_description(&self, b: &NameBinding, ident: Ident, from_prelude: bool) -> String {
4674+
if b.span.is_dummy() {
4675+
let add_built_in = match b.def() {
4676+
// These already contain the "built-in" prefix or look bad with it.
4677+
Def::NonMacroAttr(..) | Def::PrimTy(..) | Def::ToolMod => false,
4678+
_ => true,
4679+
};
4680+
let (built_in, from) = if from_prelude {
4681+
("", " from prelude")
4682+
} else if b.is_extern_crate() && !b.is_import() &&
4683+
self.session.opts.externs.get(&ident.as_str()).is_some() {
4684+
("", " passed with `--extern`")
4685+
} else if add_built_in {
4686+
(" built-in", "")
4687+
} else {
4688+
("", "")
4689+
};
4690+
4691+
let article = if built_in.is_empty() { b.article() } else { "a" };
4692+
format!("{a}{built_in} {thing}{from}",
4693+
a = article, thing = b.descr(), built_in = built_in, from = from)
4694+
} else {
4695+
let introduced = if b.is_import() { "imported" } else { "defined" };
4696+
format!("the {thing} {introduced} here",
4697+
thing = b.descr(), introduced = introduced)
4698+
}
4699+
}
4700+
46734701
fn report_ambiguity_error(&self, ambiguity_error: &AmbiguityError) {
46744702
let AmbiguityError { kind, ident, b1, b2, misc1, misc2 } = *ambiguity_error;
46754703
let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() {
@@ -4685,31 +4713,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
46854713
err.span_label(ident.span, "ambiguous name");
46864714

46874715
let mut could_refer_to = |b: &NameBinding, misc: AmbiguityErrorMisc, also: &str| {
4688-
let what = if b.span.is_dummy() {
4689-
let add_built_in = match b.def() {
4690-
// These already contain the "built-in" prefix or look bad with it.
4691-
Def::NonMacroAttr(..) | Def::PrimTy(..) | Def::ToolMod => false,
4692-
_ => true,
4693-
};
4694-
let (built_in, from) = if misc == AmbiguityErrorMisc::FromPrelude {
4695-
("", " from prelude")
4696-
} else if b.is_extern_crate() && !b.is_import() &&
4697-
self.session.opts.externs.get(&ident.as_str()).is_some() {
4698-
("", " passed with `--extern`")
4699-
} else if add_built_in {
4700-
(" built-in", "")
4701-
} else {
4702-
("", "")
4703-
};
4704-
4705-
let article = if built_in.is_empty() { b.article() } else { "a" };
4706-
format!("{a}{built_in} {thing}{from}",
4707-
a = article, thing = b.descr(), built_in = built_in, from = from)
4708-
} else {
4709-
let participle = if b.is_import() { "imported" } else { "defined" };
4710-
format!("the {thing} {introduced} here",
4711-
thing = b.descr(), introduced = participle)
4712-
};
4716+
let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude);
47134717
let note_msg = format!("`{ident}` could{also} refer to {what}",
47144718
ident = ident, also = also, what = what);
47154719

src/librustc_resolve/macros.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,33 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
884884
}
885885

886886
// The first found solution was the only one, return it.
887-
if let Some((binding, ..)) = innermost_result {
887+
if let Some((binding, flags)) = innermost_result {
888+
if is_import && !self.session.features_untracked().uniform_paths {
889+
// We get to here only if there's no ambiguity, in ambiguous cases an error will
890+
// be reported anyway, so there's no reason to report an additional feature error.
891+
// The `binding` can actually be introduced by something other than `--extern`,
892+
// but its `Def` should coincide with a crate passed with `--extern`
893+
// (otherwise there would be ambiguity) and we can skip feature error in this case.
894+
if ns != TypeNS || !use_prelude ||
895+
self.extern_prelude_get(ident, true, false).is_none() {
896+
let msg = "imports can only refer to extern crate names \
897+
passed with `--extern` on stable channel";
898+
let mut err = feature_err(&self.session.parse_sess, "uniform_paths",
899+
ident.span, GateIssue::Language, msg);
900+
901+
let what = self.binding_description(binding, ident,
902+
flags.contains(Flags::MISC_FROM_PRELUDE));
903+
let note_msg = format!("this import refers to {what}", what = what);
904+
if binding.span.is_dummy() {
905+
err.note(&note_msg);
906+
} else {
907+
err.span_note(binding.span, &note_msg);
908+
err.span_label(binding.span, "not an extern crate passed with `--extern`");
909+
}
910+
err.emit();
911+
}
912+
}
913+
888914
return Ok(binding);
889915
}
890916

src/test/ui/feature-gates/feature-gate-uniform-paths.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,22 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// edition:2018
12+
1113
pub mod foo {
12-
pub use bar::Bar;
13-
//~^ ERROR unresolved import `bar`
14+
pub use bar::Bar; //~ ERROR imports can only refer to extern crate names
1415

1516
pub mod bar {
1617
pub struct Bar;
1718
}
1819
}
1920

21+
use inline; //~ ERROR imports can only refer to extern crate names
22+
23+
use Vec; //~ ERROR imports can only refer to extern crate names
24+
25+
use vec; //~ ERROR imports can only refer to extern crate names
26+
2027
fn main() {
2128
let _ = foo::Bar;
2229
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,62 @@
1-
error[E0432]: unresolved import `bar`
2-
--> $DIR/feature-gate-uniform-paths.rs:12:13
1+
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
2+
--> $DIR/feature-gate-uniform-paths.rs:14:13
33
|
4-
LL | pub use bar::Bar;
5-
| ^^^ Did you mean `self::bar`?
4+
LL | pub use bar::Bar; //~ ERROR imports can only refer to extern crate names
5+
| ^^^
6+
LL |
7+
LL | / pub mod bar {
8+
LL | | pub struct Bar;
9+
LL | | }
10+
| |_____- not an extern crate passed with `--extern`
11+
|
12+
= help: add #![feature(uniform_paths)] to the crate attributes to enable
13+
note: this import refers to the module defined here
14+
--> $DIR/feature-gate-uniform-paths.rs:16:5
15+
|
16+
LL | / pub mod bar {
17+
LL | | pub struct Bar;
18+
LL | | }
19+
| |_____^
20+
21+
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
22+
--> $DIR/feature-gate-uniform-paths.rs:21:5
23+
|
24+
LL | use inline; //~ ERROR imports can only refer to extern crate names
25+
| ^^^^^^ not an extern crate passed with `--extern`
26+
|
27+
= help: add #![feature(uniform_paths)] to the crate attributes to enable
28+
note: this import refers to the built-in attribute imported here
29+
--> $DIR/feature-gate-uniform-paths.rs:21:5
30+
|
31+
LL | use inline; //~ ERROR imports can only refer to extern crate names
32+
| ^^^^^^
33+
34+
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
35+
--> $DIR/feature-gate-uniform-paths.rs:23:5
36+
|
37+
LL | use Vec; //~ ERROR imports can only refer to extern crate names
38+
| ^^^ not an extern crate passed with `--extern`
39+
|
40+
= help: add #![feature(uniform_paths)] to the crate attributes to enable
41+
note: this import refers to the struct imported here
42+
--> $DIR/feature-gate-uniform-paths.rs:23:5
43+
|
44+
LL | use Vec; //~ ERROR imports can only refer to extern crate names
45+
| ^^^
46+
47+
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
48+
--> $DIR/feature-gate-uniform-paths.rs:25:5
49+
|
50+
LL | use vec; //~ ERROR imports can only refer to extern crate names
51+
| ^^^ not an extern crate passed with `--extern`
52+
|
53+
= help: add #![feature(uniform_paths)] to the crate attributes to enable
54+
note: this import refers to the macro imported here
55+
--> $DIR/feature-gate-uniform-paths.rs:25:5
56+
|
57+
LL | use vec; //~ ERROR imports can only refer to extern crate names
58+
| ^^^
659

7-
error: aborting due to previous error
60+
error: aborting due to 4 previous errors
861

9-
For more information about this error, try `rustc --explain E0432`.
62+
For more information about this error, try `rustc --explain E0658`.

src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
// edition:2018
1212

13+
#![feature(uniform_paths)]
14+
1315
// Tests that arbitrary crates (other than `core`, `std` and `meta`)
1416
// aren't allowed without `--extern`, even if they're in the sysroot.
1517
use alloc; //~ ERROR unresolved import `alloc`

src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: cannot import a built-in macro
2-
--> $DIR/not-whitelisted.rs:16:5
2+
--> $DIR/not-whitelisted.rs:18:5
33
|
44
LL | use test; //~ ERROR cannot import a built-in macro
55
| ^^^^
66

77
error[E0432]: unresolved import `alloc`
8-
--> $DIR/not-whitelisted.rs:15:5
8+
--> $DIR/not-whitelisted.rs:17:5
99
|
1010
LL | use alloc; //~ ERROR unresolved import `alloc`
1111
| ^^^^^ no `alloc` external crate

src/test/ui/rust-2018/local-path-suggestions-2018.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// compile-flags:--extern baz
1313
// edition:2018
1414

15+
#![feature(uniform_paths)]
16+
1517
mod foo {
1618
pub type Bar = u32;
1719
}

src/test/ui/rust-2018/local-path-suggestions-2018.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0432]: unresolved import `foo`
2-
--> $DIR/local-path-suggestions-2018.rs:20:9
2+
--> $DIR/local-path-suggestions-2018.rs:22:9
33
|
44
LL | use foo::Bar;
55
| ^^^ Did you mean `crate::foo`?
66
|
77
= note: `use` statements changed in Rust 2018; read more at <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html>
88

99
error[E0432]: unresolved import `foobar`
10-
--> $DIR/local-path-suggestions-2018.rs:29:5
10+
--> $DIR/local-path-suggestions-2018.rs:31:5
1111
|
1212
LL | use foobar::Baz;
1313
| ^^^^^^ Did you mean `baz::foobar`?

src/test/ui/rust-2018/uniform-paths-forward-compat/issue-54253.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
// edition:2018
1212

13-
// Dummy import to introduce `uniform_paths` canaries.
13+
// Dummy import that previously introduced uniform path canaries.
1414
use std;
1515

1616
// fn version() -> &'static str {""}

src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs

-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
// edition:2018
1212

13-
#![feature(uniform_paths)]
14-
1513
// This test is similar to `ambiguity-macros.rs`, but nested in a module.
1614

1715
mod foo {

src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
2-
--> $DIR/ambiguity-macros-nested.rs:18:13
2+
--> $DIR/ambiguity-macros-nested.rs:16:13
33
|
44
LL | pub use std::io;
55
| ^^^ ambiguous name
66
|
77
= note: `std` could refer to a built-in extern crate
88
= help: use `::std` to refer to this extern crate unambiguously
99
note: `std` could also refer to the module defined here
10-
--> $DIR/ambiguity-macros-nested.rs:23:13
10+
--> $DIR/ambiguity-macros-nested.rs:21:13
1111
|
1212
LL | / mod std {
1313
LL | | pub struct io;

src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs

-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
// edition:2018
1212

13-
#![feature(uniform_paths)]
14-
1513
// This test is similar to `ambiguity.rs`, but with macros defining local items.
1614

1715
use std::io;

src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
2-
--> $DIR/ambiguity-macros.rs:17:5
2+
--> $DIR/ambiguity-macros.rs:15:5
33
|
44
LL | use std::io;
55
| ^^^ ambiguous name
66
|
77
= note: `std` could refer to a built-in extern crate
88
= help: use `::std` to refer to this extern crate unambiguously
99
note: `std` could also refer to the module defined here
10-
--> $DIR/ambiguity-macros.rs:22:9
10+
--> $DIR/ambiguity-macros.rs:20:9
1111
|
1212
LL | / mod std {
1313
LL | | pub struct io;

src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs

-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
// edition:2018
1212

13-
#![feature(uniform_paths)]
14-
1513
// This test is similar to `ambiguity.rs`, but nested in a module.
1614

1715
mod foo {

src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
2-
--> $DIR/ambiguity-nested.rs:18:13
2+
--> $DIR/ambiguity-nested.rs:16:13
33
|
44
LL | pub use std::io;
55
| ^^^ ambiguous name
66
|
77
= note: `std` could refer to a built-in extern crate
88
= help: use `::std` to refer to this extern crate unambiguously
99
note: `std` could also refer to the module defined here
10-
--> $DIR/ambiguity-nested.rs:21:5
10+
--> $DIR/ambiguity-nested.rs:19:5
1111
|
1212
LL | / mod std {
1313
LL | | pub struct io;

src/test/ui/rust-2018/uniform-paths/ambiguity.rs

-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
// edition:2018
1212

13-
#![feature(uniform_paths)]
14-
1513
use std::io;
1614
//~^ ERROR `std` is ambiguous
1715

src/test/ui/rust-2018/uniform-paths/ambiguity.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
2-
--> $DIR/ambiguity.rs:15:5
2+
--> $DIR/ambiguity.rs:13:5
33
|
44
LL | use std::io;
55
| ^^^ ambiguous name
66
|
77
= note: `std` could refer to a built-in extern crate
88
= help: use `::std` to refer to this extern crate unambiguously
99
note: `std` could also refer to the module defined here
10-
--> $DIR/ambiguity.rs:18:1
10+
--> $DIR/ambiguity.rs:16:1
1111
|
1212
LL | / mod std {
1313
LL | | pub struct io;

src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// edition:2018
22

3+
#![feature(uniform_paths)]
4+
35
mod my {
46
pub mod sub {
57
pub fn bar() {}

src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
error[E0659]: `sub` is ambiguous (name vs any other name during import resolution)
2-
--> $DIR/block-scoped-shadow-nested.rs:16:13
2+
--> $DIR/block-scoped-shadow-nested.rs:18:13
33
|
44
LL | use sub::bar; //~ ERROR `sub` is ambiguous
55
| ^^^ ambiguous name
66
|
77
note: `sub` could refer to the module imported here
8-
--> $DIR/block-scoped-shadow-nested.rs:14:9
8+
--> $DIR/block-scoped-shadow-nested.rs:16:9
99
|
1010
LL | use my::sub;
1111
| ^^^^^^^
1212
note: `sub` could also refer to the module defined here
13-
--> $DIR/block-scoped-shadow-nested.rs:9:1
13+
--> $DIR/block-scoped-shadow-nested.rs:11:1
1414
|
1515
LL | / mod sub {
1616
LL | | pub fn bar() {}

0 commit comments

Comments
 (0)