Skip to content

rustc_resolve: don't allow paths starting with ::crate. #53347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "chalk-engine"
version = "0.6.0"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
Expand Down Expand Up @@ -1897,7 +1897,7 @@ dependencies = [
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fmt_macros 0.0.0",
"graphviz 0.0.0",
Expand Down Expand Up @@ -2408,7 +2408,7 @@ name = "rustc_traits"
version = "0.0.0"
dependencies = [
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"graphviz 0.0.0",
"log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
Expand Down Expand Up @@ -3135,7 +3135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1"
"checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275"
"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e"
"checksum chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a146c19172c7eea48ea55a7123ac95da786639bc665097f1e14034ee5f1d8699"
"checksum chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25ce2f28f55ed544a2a3756b7acf41dd7d6f27acffb2086439950925506af7d0"
"checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e"
"checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
Expand Down
9 changes: 2 additions & 7 deletions src/doc/unstable-book/src/language-features/crate-in-paths.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ The tracking issue for this feature is: [#44660]
The `crate_in_paths` feature allows to explicitly refer to the crate root in absolute paths
using keyword `crate`.

`crate` can be used *only* in absolute paths, i.e. either in `::crate::a::b::c` form or in `use`
items where the starting `::` is added implicitly.
Paths like `crate::a::b::c` are not accepted currently.

This feature is required in `feature(extern_absolute_paths)` mode to refer to any absolute path
in the local crate (absolute paths refer to extern crates by default in that mode), but can be
used without `feature(extern_absolute_paths)` as well.
Expand All @@ -39,15 +35,14 @@ mod n
use crate as root;
pub fn check() {
assert_eq!(f(), 1);
// `::` is required in non-import paths
assert_eq!(::crate::m::g(), 2);
assert_eq!(crate::m::g(), 2);
assert_eq!(root::m::h(), 3);
}
}

fn main() {
assert_eq!(f(), 1);
assert_eq!(::crate::m::g(), 2);
assert_eq!(crate::m::g(), 2);
assert_eq!(root::m::h(), 3);
n::check();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The `extern_absolute_paths` feature enables mode allowing to refer to names from
`::my_crate::a::b` will resolve to path `a::b` in crate `my_crate`.

`feature(crate_in_paths)` can be used in `feature(extern_absolute_paths)` mode for referring
to absolute paths in the local crate (`::crate::a::b`).
to absolute paths in the local crate (`crate::a::b`).

`feature(extern_in_paths)` provides the same effect by using keyword `extern` to refer to
paths from other crates (`extern::my_crate::a::b`).
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ syntax_pos = { path = "../libsyntax_pos" }
backtrace = "0.3.3"
parking_lot = "0.5.5"
byteorder = { version = "1.1", features = ["i128"]}
chalk-engine = { version = "0.6.0", default-features=false }
chalk-engine = { version = "0.7.0", default-features=false }
rustc_fs_util = { path = "../librustc_fs_util" }

# Note that these dependencies are a lie, they're just here to get linkage to
Expand Down
79 changes: 36 additions & 43 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3459,64 +3459,57 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
let name = ident.name;

if i == 0 && ns == TypeNS && name == keywords::SelfValue.name() {
let mut ctxt = ident.span.ctxt().modern();
module = Some(ModuleOrUniformRoot::Module(
self.resolve_self(&mut ctxt, self.current_module)));
continue
} else if allow_super && ns == TypeNS && name == keywords::Super.name() {
let mut ctxt = ident.span.ctxt().modern();
let self_module_parent = match i {
0 => self.resolve_self(&mut ctxt, self.current_module).parent,
_ => match module {
Some(ModuleOrUniformRoot::Module(module)) => module.parent,
_ => None,
},
};
if let Some(parent) = self_module_parent {
module = Some(ModuleOrUniformRoot::Module(
self.resolve_self(&mut ctxt, parent)));
continue
} else {
allow_super &= ns == TypeNS &&
(name == keywords::SelfValue.name() ||
name == keywords::Super.name());

if ns == TypeNS {
if allow_super && name == keywords::Super.name() {
let mut ctxt = ident.span.ctxt().modern();
let self_module = match i {
0 => Some(self.resolve_self(&mut ctxt, self.current_module)),
_ => match module {
Some(ModuleOrUniformRoot::Module(module)) => Some(module),
_ => None,
},
};
if let Some(self_module) = self_module {
if let Some(parent) = self_module.parent {
module = Some(ModuleOrUniformRoot::Module(
self.resolve_self(&mut ctxt, parent)));
continue;
}
}
let msg = "There are too many initial `super`s.".to_string();
return PathResult::Failed(ident.span, msg, false);
}
}
allow_super = false;

if ns == TypeNS {
if i == 0 {
if name == keywords::SelfValue.name() {
let mut ctxt = ident.span.ctxt().modern();
module = Some(ModuleOrUniformRoot::Module(
self.resolve_self(&mut ctxt, self.current_module)));
continue;
}
if name == keywords::Extern.name() ||
name == keywords::CrateRoot.name() &&
self.session.features_untracked().extern_absolute_paths &&
self.session.rust_2018() {
module = Some(ModuleOrUniformRoot::UniformRoot(name));
continue;
}
}
if (i == 0 && name == keywords::CrateRoot.name()) ||
(i == 0 && name == keywords::Crate.name()) ||
(i == 0 && name == keywords::DollarCrate.name()) ||
(i == 1 && name == keywords::Crate.name() &&
path[0].name == keywords::CrateRoot.name()) {
// `::a::b`, `crate::a::b`, `::crate::a::b` or `$crate::a::b`
module = Some(ModuleOrUniformRoot::Module(
self.resolve_crate_root(ident)));
continue
if name == keywords::CrateRoot.name() ||
name == keywords::Crate.name() ||
name == keywords::DollarCrate.name() {
// `::a::b`, `crate::a::b` or `$crate::a::b`
module = Some(ModuleOrUniformRoot::Module(
self.resolve_crate_root(ident)));
continue;
}
}
}

// Report special messages for path segment keywords in wrong positions.
if name == keywords::CrateRoot.name() && i != 0 ||
name == keywords::DollarCrate.name() && i != 0 ||
name == keywords::SelfValue.name() && i != 0 ||
name == keywords::SelfType.name() && i != 0 ||
name == keywords::Super.name() && i != 0 ||
name == keywords::Extern.name() && i != 0 ||
// we allow crate::foo and ::crate::foo but nothing else
name == keywords::Crate.name() && i > 1 &&
path[0].name != keywords::CrateRoot.name() ||
name == keywords::Crate.name() && path.len() == 1 {
if ident.is_path_segment_keyword() && i != 0 {
let name_str = if name == keywords::CrateRoot.name() {
"crate root".to_string()
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_traits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
chalk-engine = { version = "0.6.0", default-features=false }
chalk-engine = { version = "0.7.0", default-features=false }
4 changes: 2 additions & 2 deletions src/test/run-pass/rfc-2126-crate-paths/crate-path-absolute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ mod n
use crate as root;
pub fn check() {
assert_eq!(f(), 1);
assert_eq!(::crate::m::g(), 2);
assert_eq!(crate::m::g(), 2);
assert_eq!(root::m::h(), 3);
}
}

fn main() {
assert_eq!(f(), 1);
assert_eq!(::crate::m::g(), 2);
assert_eq!(crate::m::g(), 2);
assert_eq!(root::m::h(), 3);
n::check();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
mod m {
pub struct Z;
pub struct S1(crate (::m::Z)); // OK
pub struct S2(::crate ::m::Z); // OK
pub struct S2((crate ::m::Z)); // OK
pub struct S3(crate ::m::Z); // OK
pub struct S4(crate crate::m::Z); // OK
}

fn main() {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/feature-gates/feature-gate-crate_in_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
struct S;

fn main() {
let _ = ::crate::S; //~ ERROR `crate` in paths is experimental
let _ = crate::S; //~ ERROR `crate` in paths is experimental
}
6 changes: 3 additions & 3 deletions src/test/ui/feature-gates/feature-gate-crate_in_paths.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0658]: `crate` in paths is experimental (see issue #45477)
--> $DIR/feature-gate-crate_in_paths.rs:14:15
--> $DIR/feature-gate-crate_in_paths.rs:14:13
|
LL | let _ = ::crate::S; //~ ERROR `crate` in paths is experimental
| ^^^^^
LL | let _ = crate::S; //~ ERROR `crate` in paths is experimental
| ^^^^^
|
= help: add #![feature(crate_in_paths)] to the crate attributes to enable

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct S;
pub mod m {
fn f() {
let s = ::m::crate::S; //~ ERROR failed to resolve
let s1 = ::crate::S; //~ ERROR failed to resolve
let s2 = crate::S; // no error
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
error[E0433]: failed to resolve. Could not find `crate` in `m`
error[E0433]: failed to resolve. `crate` in paths can only be used in start position
--> $DIR/crate-path-non-absolute.rs:17:22
|
LL | let s = ::m::crate::S; //~ ERROR failed to resolve
| ^^^^^ Could not find `crate` in `m`
| ^^^^^ `crate` in paths can only be used in start position

error: aborting due to previous error
error[E0433]: failed to resolve. global paths cannot start with `crate`
--> $DIR/crate-path-non-absolute.rs:18:20
|
LL | let s1 = ::crate::S; //~ ERROR failed to resolve
| ^^^^^ global paths cannot start with `crate`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0433`.
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
#![feature(crate_in_paths)]

fn main() {
let crate = 0; //~ ERROR failed to resolve. `crate` in paths can only be used in start position
let crate = 0;
//~^ ERROR expected unit struct/variant or constant, found module `crate`
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
error[E0433]: failed to resolve. `crate` in paths can only be used in start position
error[E0532]: expected unit struct/variant or constant, found module `crate`
--> $DIR/keyword-crate-as-identifier.rs:14:9
|
LL | let crate = 0; //~ ERROR failed to resolve. `crate` in paths can only be used in start position
| ^^^^^ `crate` in paths can only be used in start position
LL | let crate = 0;
| ^^^^^ not a unit struct/variant or constant

error: aborting due to previous error

For more information about this error, try `rustc --explain E0433`.
For more information about this error, try `rustc --explain E0532`.
2 changes: 1 addition & 1 deletion src/test/ui/rust-2018/edition-lint-paths.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn main() {
//~^ ERROR absolute
//~| WARN this was previously accepted
let x = bar::Bar;
let x = ::crate::bar::Bar;
let x = crate::bar::Bar;
let x = self::bar::Bar;
foo::test();

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/rust-2018/edition-lint-paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn main() {
//~^ ERROR absolute
//~| WARN this was previously accepted
let x = bar::Bar;
let x = ::crate::bar::Bar;
let x = crate::bar::Bar;
let x = self::bar::Bar;
foo::test();

Expand Down