remove extern_in_paths.
This commit is contained in:
parent
75a369c5b1
commit
c4f6ef25d2
@ -1,40 +0,0 @@
|
||||
# `extern_in_paths`
|
||||
|
||||
The tracking issue for this feature is: [#44660]
|
||||
|
||||
[#44660]: https://github.com/rust-lang/rust/issues/44660
|
||||
|
||||
------------------------
|
||||
|
||||
The `extern_in_paths` feature allows to refer to names from other crates "inline", without
|
||||
introducing `extern crate` items, using keyword `extern`.
|
||||
|
||||
For example, `extern::my_crat::a::b` will resolve to path `a::b` in crate `my_crate`.
|
||||
|
||||
Absolute paths on 2018 edition (e.g. `::my_crate::a::b`) provide the same effect
|
||||
and resolve to extern crates (built-in or passed with `--extern`).
|
||||
|
||||
```rust,ignore
|
||||
#![feature(extern_in_paths)]
|
||||
|
||||
// Suppose we have a dependency crate `xcrate` available through `Cargo.toml`, or `--extern`
|
||||
// options, or standard Rust distribution, or some other means.
|
||||
|
||||
use extern::xcrate::Z;
|
||||
|
||||
fn f() {
|
||||
use extern::xcrate;
|
||||
use extern::xcrate as ycrate;
|
||||
let s = xcrate::S;
|
||||
assert_eq!(format!("{:?}", s), "S");
|
||||
let z = ycrate::Z;
|
||||
assert_eq!(format!("{:?}", z), "Z");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = extern::xcrate::S;
|
||||
assert_eq!(format!("{:?}", s), "S");
|
||||
let z = Z;
|
||||
assert_eq!(format!("{:?}", z), "Z");
|
||||
}
|
||||
```
|
@ -140,7 +140,7 @@ pub enum ExternCrateSource {
|
||||
),
|
||||
// Crate is loaded by `use`.
|
||||
Use,
|
||||
/// Crate is implicitly loaded by an absolute or an `extern::` path.
|
||||
/// Crate is implicitly loaded by an absolute path.
|
||||
Path,
|
||||
}
|
||||
|
||||
|
@ -1005,7 +1005,7 @@ enum ModuleOrUniformRoot<'a> {
|
||||
CrateRootAndExternPrelude,
|
||||
|
||||
/// Virtual module that denotes resolution in extern prelude.
|
||||
/// Used for paths starting with `::` on 2018 edition or `extern::`.
|
||||
/// Used for paths starting with `::` on 2018 edition.
|
||||
ExternPrelude,
|
||||
|
||||
/// Virtual module that denotes resolution in current scope.
|
||||
@ -3817,8 +3817,7 @@ impl<'a> Resolver<'a> {
|
||||
self.resolve_self(&mut ctxt, self.current_module)));
|
||||
continue;
|
||||
}
|
||||
if name == keywords::Extern.name() ||
|
||||
name == keywords::PathRoot.name() && ident.span.rust_2018() {
|
||||
if name == keywords::PathRoot.name() && ident.span.rust_2018() {
|
||||
module = Some(ModuleOrUniformRoot::ExternPrelude);
|
||||
continue;
|
||||
}
|
||||
@ -3985,8 +3984,8 @@ impl<'a> Resolver<'a> {
|
||||
};
|
||||
|
||||
// We're only interested in `use` paths which should start with
|
||||
// `{{root}}` or `extern` currently.
|
||||
if first_name != keywords::Extern.name() && first_name != keywords::PathRoot.name() {
|
||||
// `{{root}}` currently.
|
||||
if first_name != keywords::PathRoot.name() {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,9 @@ use syntax_pos::{Span, DUMMY_SP};
|
||||
use errors::{DiagnosticBuilder, Handler};
|
||||
use visit::{self, FnKind, Visitor};
|
||||
use parse::ParseSess;
|
||||
use symbol::{keywords, Symbol};
|
||||
use symbol::Symbol;
|
||||
|
||||
use std::{env};
|
||||
use std::env;
|
||||
|
||||
macro_rules! set {
|
||||
($field: ident) => {{
|
||||
@ -375,9 +375,6 @@ declare_features! (
|
||||
// Generic associated types (RFC 1598)
|
||||
(active, generic_associated_types, "1.23.0", Some(44265), None),
|
||||
|
||||
// `extern` in paths
|
||||
(active, extern_in_paths, "1.23.0", Some(55600), None),
|
||||
|
||||
// Infer static outlives requirements (RFC 2093).
|
||||
(active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
|
||||
|
||||
@ -506,6 +503,9 @@ declare_features! (
|
||||
// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
|
||||
(removed, custom_derive, "1.0.0", Some(29644), None,
|
||||
Some("subsumed by `#[proc_macro_derive]`")),
|
||||
// Paths of the form: `extern::foo::bar`
|
||||
(removed, extern_in_paths, "1.33.0", Some(55600), None,
|
||||
Some("subsumed by `::foo::bar` paths")),
|
||||
);
|
||||
|
||||
declare_features! (
|
||||
@ -1829,25 +1829,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
visit::walk_impl_item(self, ii);
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &'a ast::Path, _id: NodeId) {
|
||||
for segment in &path.segments {
|
||||
// Identifiers we are going to check could come from a legacy macro (e.g., `#[test]`).
|
||||
// For such macros identifiers must have empty context, because this context is
|
||||
// used during name resolution and produced names must be unhygienic for compatibility.
|
||||
// On the other hand, we need the actual non-empty context for feature gate checking
|
||||
// because it's hygienic even for legacy macros. As previously stated, such context
|
||||
// cannot be kept in identifiers, so it's kept in paths instead and we take it from
|
||||
// there while keeping location info from the ident span.
|
||||
let span = segment.ident.span.with_ctxt(path.span.ctxt());
|
||||
if segment.ident.name == keywords::Extern.name() {
|
||||
gate_feature_post!(&self, extern_in_paths, span,
|
||||
"`extern` in paths is experimental");
|
||||
}
|
||||
}
|
||||
|
||||
visit::walk_path(self, path);
|
||||
}
|
||||
|
||||
fn visit_vis(&mut self, vis: &'a ast::Visibility) {
|
||||
if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node {
|
||||
gate_feature_post!(&self, crate_visibility_modifier, vis.span,
|
||||
|
@ -1299,7 +1299,7 @@ impl<'a> Parser<'a> {
|
||||
fn token_is_bare_fn_keyword(&mut self) -> bool {
|
||||
self.check_keyword(keywords::Fn) ||
|
||||
self.check_keyword(keywords::Unsafe) ||
|
||||
self.check_keyword(keywords::Extern) && self.is_extern_non_path()
|
||||
self.check_keyword(keywords::Extern)
|
||||
}
|
||||
|
||||
/// parse a `TyKind::BareFn` type:
|
||||
@ -4605,10 +4605,6 @@ impl<'a> Parser<'a> {
|
||||
self.token.is_keyword(keywords::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
|
||||
}
|
||||
|
||||
fn is_extern_non_path(&self) -> bool {
|
||||
self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
|
||||
}
|
||||
|
||||
fn is_existential_type_decl(&self) -> bool {
|
||||
self.token.is_keyword(keywords::Existential) &&
|
||||
self.look_ahead(1, |t| t.is_keyword(keywords::Type))
|
||||
@ -4712,12 +4708,10 @@ impl<'a> Parser<'a> {
|
||||
// like a path (1 token), but it fact not a path.
|
||||
// `union::b::c` - path, `union U { ... }` - not a path.
|
||||
// `crate::b::c` - path, `crate struct S;` - not a path.
|
||||
// `extern::b::c` - path, `extern crate c;` - not a path.
|
||||
} else if self.token.is_path_start() &&
|
||||
!self.token.is_qpath_start() &&
|
||||
!self.is_union_item() &&
|
||||
!self.is_crate_vis() &&
|
||||
!self.is_extern_non_path() &&
|
||||
!self.is_existential_type_decl() &&
|
||||
!self.is_auto_trait_item() {
|
||||
let pth = self.parse_path(PathStyle::Expr)?;
|
||||
@ -7113,8 +7107,7 @@ impl<'a> Parser<'a> {
|
||||
return Ok(Some(item));
|
||||
}
|
||||
|
||||
if self.check_keyword(keywords::Extern) && self.is_extern_non_path() {
|
||||
self.bump(); // `extern`
|
||||
if self.eat_keyword(keywords::Extern) {
|
||||
if self.eat_keyword(keywords::Crate) {
|
||||
return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?));
|
||||
}
|
||||
@ -7623,7 +7616,7 @@ impl<'a> Parser<'a> {
|
||||
fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
|
||||
at_end: &mut bool) -> PResult<'a, Option<Mac>>
|
||||
{
|
||||
if self.token.is_path_start() && !self.is_extern_non_path() {
|
||||
if self.token.is_path_start() {
|
||||
let prev_span = self.prev_span;
|
||||
let lo = self.span;
|
||||
let pth = self.parse_path(PathStyle::Mod)?;
|
||||
|
@ -478,7 +478,6 @@ impl Ident {
|
||||
self.name == keywords::Super.name() ||
|
||||
self.name == keywords::SelfLower.name() ||
|
||||
self.name == keywords::SelfUpper.name() ||
|
||||
self.name == keywords::Extern.name() ||
|
||||
self.name == keywords::Crate.name() ||
|
||||
self.name == keywords::PathRoot.name() ||
|
||||
self.name == keywords::DollarCrate.name()
|
||||
|
@ -1,12 +1,9 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all: extern_absolute_paths.rs extern_in_paths.rs krate2
|
||||
all: extern_absolute_paths.rs krate2
|
||||
$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 \
|
||||
-Z unstable-options --extern krate2
|
||||
cat $(TMPDIR)/save-analysis/extern_absolute_paths.json | "$(PYTHON)" validate_json.py
|
||||
$(RUSTC) extern_in_paths.rs -Zsave-analysis --edition=2018 \
|
||||
-Z unstable-options --extern krate2
|
||||
cat $(TMPDIR)/save-analysis/extern_in_paths.json | "$(PYTHON)" validate_json.py
|
||||
|
||||
krate2: krate2.rs
|
||||
$(RUSTC) $<
|
||||
|
@ -1,7 +0,0 @@
|
||||
#![feature(extern_in_paths)]
|
||||
|
||||
use extern::krate2;
|
||||
|
||||
fn main() {
|
||||
extern::krate2::hello();
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
// aux-build:xcrate.rs
|
||||
// compile-flags:--extern xcrate
|
||||
|
||||
#![feature(extern_in_paths)]
|
||||
|
||||
use extern::xcrate::Z;
|
||||
|
||||
type A = extern::xcrate::S;
|
||||
type B = for<'a> extern::xcrate::Tr<'a>;
|
||||
|
||||
fn f() {
|
||||
use extern::xcrate;
|
||||
use extern::xcrate as ycrate;
|
||||
let s = xcrate::S;
|
||||
assert_eq!(format!("{:?}", s), "S");
|
||||
let z = ycrate::Z;
|
||||
assert_eq!(format!("{:?}", z), "Z");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = extern::xcrate::S;
|
||||
assert_eq!(format!("{:?}", s), "S");
|
||||
let z = Z;
|
||||
assert_eq!(format!("{:?}", z), "Z");
|
||||
assert_eq!(A {}, extern::xcrate::S {});
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
struct S;
|
||||
|
||||
fn main() {
|
||||
let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
error[E0658]: `extern` in paths is experimental (see issue #55600)
|
||||
--> $DIR/feature-gate-extern_in_paths.rs:4:13
|
||||
|
|
||||
LL | let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: add #![feature(extern_in_paths)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
3
src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.rs
vendored
Normal file
3
src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.rs
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
let s = extern::foo::Bar; //~ ERROR expected expression, found keyword `extern`
|
||||
}
|
8
src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.stderr
vendored
Normal file
8
src/test/ui/keyword/extern/keyword-extern-as-identifier-expr.stderr
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
error: expected expression, found keyword `extern`
|
||||
--> $DIR/keyword-extern-as-identifier-expr.rs:2:13
|
||||
|
|
||||
LL | let s = extern::foo::Bar; //~ ERROR expected expression, found keyword `extern`
|
||||
| ^^^^^^ expected expression
|
||||
|
||||
error: aborting due to previous error
|
||||
|
3
src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs
vendored
Normal file
3
src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
let extern = 0; //~ ERROR expected pattern, found keyword `extern`
|
||||
}
|
8
src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr
vendored
Normal file
8
src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
error: expected pattern, found keyword `extern`
|
||||
--> $DIR/keyword-extern-as-identifier-pat.rs:2:9
|
||||
|
|
||||
LL | let extern = 0; //~ ERROR expected pattern, found keyword `extern`
|
||||
| ^^^^^^ expected pattern
|
||||
|
||||
error: aborting due to previous error
|
||||
|
3
src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs
vendored
Normal file
3
src/test/ui/keyword/extern/keyword-extern-as-identifier-type.rs
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
type A = extern::foo::bar; //~ ERROR expected `fn`, found `::`
|
||||
|
||||
fn main() {}
|
8
src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr
vendored
Normal file
8
src/test/ui/keyword/extern/keyword-extern-as-identifier-type.stderr
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
error: expected `fn`, found `::`
|
||||
--> $DIR/keyword-extern-as-identifier-type.rs:1:16
|
||||
|
|
||||
LL | type A = extern::foo::bar; //~ ERROR expected `fn`, found `::`
|
||||
| ^^ expected `fn` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
3
src/test/ui/keyword/extern/keyword-extern-as-identifier-use.rs
vendored
Normal file
3
src/test/ui/keyword/extern/keyword-extern-as-identifier-use.rs
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
use extern::foo; //~ ERROR expected identifier, found keyword `extern`
|
||||
|
||||
fn main() {}
|
12
src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr
vendored
Normal file
12
src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
error: expected identifier, found keyword `extern`
|
||||
--> $DIR/keyword-extern-as-identifier-use.rs:1:5
|
||||
|
|
||||
LL | use extern::foo; //~ ERROR expected identifier, found keyword `extern`
|
||||
| ^^^^^^ expected identifier, found keyword
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | use r#extern::foo; //~ ERROR expected identifier, found keyword `extern`
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,5 +0,0 @@
|
||||
#![feature(extern_in_paths)]
|
||||
|
||||
fn main() {
|
||||
let extern = 0; //~ ERROR cannot find unit struct/variant or constant `extern` in this scope
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
error[E0531]: cannot find unit struct/variant or constant `extern` in this scope
|
||||
--> $DIR/keyword-extern-as-identifier.rs:4:9
|
||||
|
|
||||
LL | let extern = 0; //~ ERROR cannot find unit struct/variant or constant `extern` in this scope
|
||||
| ^^^^^^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0531`.
|
@ -1,5 +0,0 @@
|
||||
#[derive(Debug)]
|
||||
pub struct S;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Z;
|
@ -1,5 +0,0 @@
|
||||
#![feature(extern_in_paths)]
|
||||
|
||||
use extern::xcrate::S; //~ ERROR unresolved import `extern::xcrate`
|
||||
|
||||
fn main() {}
|
@ -1,9 +0,0 @@
|
||||
error[E0432]: unresolved import `extern::xcrate`
|
||||
--> $DIR/non-existent-1.rs:3:13
|
||||
|
|
||||
LL | use extern::xcrate::S; //~ ERROR unresolved import `extern::xcrate`
|
||||
| ^^^^^^ could not find `xcrate` in `extern`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
@ -1,6 +0,0 @@
|
||||
#![feature(extern_in_paths)]
|
||||
|
||||
fn main() {
|
||||
let s = extern::xcrate::S;
|
||||
//~^ ERROR failed to resolve: could not find `xcrate` in `extern`
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
error[E0433]: failed to resolve: could not find `xcrate` in `extern`
|
||||
--> $DIR/non-existent-2.rs:4:21
|
||||
|
|
||||
LL | let s = extern::xcrate::S;
|
||||
| ^^^^^^ could not find `xcrate` in `extern`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -1,5 +0,0 @@
|
||||
#![feature(extern_in_paths)]
|
||||
|
||||
use extern::ycrate; //~ ERROR unresolved import `extern::ycrate`
|
||||
|
||||
fn main() {}
|
@ -1,9 +0,0 @@
|
||||
error[E0432]: unresolved import `extern::ycrate`
|
||||
--> $DIR/non-existent-3.rs:3:5
|
||||
|
|
||||
LL | use extern::ycrate; //~ ERROR unresolved import `extern::ycrate`
|
||||
| ^^^^^^^^^^^^^^ no `ycrate` external crate
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
@ -1,13 +0,0 @@
|
||||
// aux-build:xcrate.rs
|
||||
// compile-flags:--extern xcrate
|
||||
|
||||
#![feature(extern_in_paths)]
|
||||
|
||||
use extern; //~ ERROR unresolved import `extern`
|
||||
//~^ NOTE no `extern` in the root
|
||||
use extern::*; //~ ERROR cannot glob-import all possible crates
|
||||
|
||||
fn main() {
|
||||
let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate`
|
||||
//~^ NOTE not a value
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
error: cannot glob-import all possible crates
|
||||
--> $DIR/single-segment.rs:8:5
|
||||
|
|
||||
LL | use extern::*; //~ ERROR cannot glob-import all possible crates
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0432]: unresolved import `extern`
|
||||
--> $DIR/single-segment.rs:6:5
|
||||
|
|
||||
LL | use extern; //~ ERROR unresolved import `extern`
|
||||
| ^^^^^^ no `extern` in the root
|
||||
|
||||
error[E0423]: expected value, found module `extern::xcrate`
|
||||
--> $DIR/single-segment.rs:11:13
|
||||
|
|
||||
LL | let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate`
|
||||
| ^^^^^^^^^^^^^^ not a value
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors occurred: E0423, E0432.
|
||||
For more information about an error, try `rustc --explain E0423`.
|
Loading…
Reference in New Issue
Block a user