Auto merge of #46613 - petrochenkov:absext, r=nikomatsakis
Resolve absolute paths as extern under a feature flag cc https://github.com/rust-lang/rust/issues/44660 r? @nikomatsakis
This commit is contained in:
commit
691f022767
15 changed files with 264 additions and 57 deletions
|
@ -357,6 +357,7 @@ impl CrateStore for DummyCrateStore {
|
||||||
pub trait CrateLoader {
|
pub trait CrateLoader {
|
||||||
fn process_item(&mut self, item: &ast::Item, defs: &Definitions);
|
fn process_item(&mut self, item: &ast::Item, defs: &Definitions);
|
||||||
fn postprocess(&mut self, krate: &ast::Crate);
|
fn postprocess(&mut self, krate: &ast::Crate);
|
||||||
|
fn resolve_crate_from_path(&mut self, name: Symbol, span: Span) -> CrateNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is used when generating the command line to pass through to
|
// This method is used when generating the command line to pass through to
|
||||||
|
|
|
@ -71,14 +71,6 @@ fn dump_crates(cstore: &CStore) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct ExternCrateInfo {
|
|
||||||
ident: Symbol,
|
|
||||||
name: Symbol,
|
|
||||||
id: ast::NodeId,
|
|
||||||
dep_kind: DepKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extra info about a crate loaded for plugins or exported macros.
|
// Extra info about a crate loaded for plugins or exported macros.
|
||||||
struct ExtensionCrate {
|
struct ExtensionCrate {
|
||||||
metadata: PMDSource,
|
metadata: PMDSource,
|
||||||
|
@ -117,34 +109,6 @@ impl<'a> CrateLoader<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_crate_info(&self, i: &ast::Item) -> Option<ExternCrateInfo> {
|
|
||||||
match i.node {
|
|
||||||
ast::ItemKind::ExternCrate(ref path_opt) => {
|
|
||||||
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
|
|
||||||
i.ident, path_opt);
|
|
||||||
let name = match *path_opt {
|
|
||||||
Some(name) => {
|
|
||||||
validate_crate_name(Some(self.sess), &name.as_str(),
|
|
||||||
Some(i.span));
|
|
||||||
name
|
|
||||||
}
|
|
||||||
None => i.ident.name,
|
|
||||||
};
|
|
||||||
Some(ExternCrateInfo {
|
|
||||||
ident: i.ident.name,
|
|
||||||
name,
|
|
||||||
id: i.id,
|
|
||||||
dep_kind: if attr::contains_name(&i.attrs, "no_link") {
|
|
||||||
DepKind::UnexportedMacrosOnly
|
|
||||||
} else {
|
|
||||||
DepKind::Explicit
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
|
fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
|
||||||
-> Option<CrateNum> {
|
-> Option<CrateNum> {
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
|
@ -478,17 +442,17 @@ impl<'a> CrateLoader<'a> {
|
||||||
})).collect()
|
})).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> ExtensionCrate {
|
fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol)
|
||||||
info!("read extension crate {} `extern crate {} as {}` dep_kind={:?}",
|
-> ExtensionCrate {
|
||||||
info.id, info.name, info.ident, info.dep_kind);
|
info!("read extension crate `extern crate {} as {}`", orig_name, rename);
|
||||||
let target_triple = &self.sess.opts.target_triple[..];
|
let target_triple = &self.sess.opts.target_triple[..];
|
||||||
let is_cross = target_triple != config::host_triple();
|
let is_cross = target_triple != config::host_triple();
|
||||||
let mut target_only = false;
|
let mut target_only = false;
|
||||||
let mut locate_ctxt = locator::Context {
|
let mut locate_ctxt = locator::Context {
|
||||||
sess: self.sess,
|
sess: self.sess,
|
||||||
span,
|
span,
|
||||||
ident: info.ident,
|
ident: orig_name,
|
||||||
crate_name: info.name,
|
crate_name: rename,
|
||||||
hash: None,
|
hash: None,
|
||||||
filesearch: self.sess.host_filesearch(PathKind::Crate),
|
filesearch: self.sess.host_filesearch(PathKind::Crate),
|
||||||
target: &self.sess.host,
|
target: &self.sess.host,
|
||||||
|
@ -625,12 +589,8 @@ impl<'a> CrateLoader<'a> {
|
||||||
span: Span,
|
span: Span,
|
||||||
name: &str)
|
name: &str)
|
||||||
-> Option<(PathBuf, CrateDisambiguator, DefIndex)> {
|
-> Option<(PathBuf, CrateDisambiguator, DefIndex)> {
|
||||||
let ekrate = self.read_extension_crate(span, &ExternCrateInfo {
|
let name = Symbol::intern(name);
|
||||||
name: Symbol::intern(name),
|
let ekrate = self.read_extension_crate(span, name, name);
|
||||||
ident: Symbol::intern(name),
|
|
||||||
id: ast::DUMMY_NODE_ID,
|
|
||||||
dep_kind: DepKind::UnexportedMacrosOnly,
|
|
||||||
});
|
|
||||||
|
|
||||||
if ekrate.target_only {
|
if ekrate.target_only {
|
||||||
// Need to abort before syntax expansion.
|
// Need to abort before syntax expansion.
|
||||||
|
@ -1098,21 +1058,37 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
|
||||||
|
|
||||||
fn process_item(&mut self, item: &ast::Item, definitions: &Definitions) {
|
fn process_item(&mut self, item: &ast::Item, definitions: &Definitions) {
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::ItemKind::ExternCrate(_) => {
|
ast::ItemKind::ExternCrate(rename) => {
|
||||||
let info = self.extract_crate_info(item).unwrap();
|
debug!("resolving extern crate stmt. ident: {} rename: {:?}", item.ident, rename);
|
||||||
|
let rename = match rename {
|
||||||
|
Some(rename) => {
|
||||||
|
validate_crate_name(Some(self.sess), &rename.as_str(), Some(item.span));
|
||||||
|
rename
|
||||||
|
}
|
||||||
|
None => item.ident.name,
|
||||||
|
};
|
||||||
|
let dep_kind = if attr::contains_name(&item.attrs, "no_link") {
|
||||||
|
DepKind::UnexportedMacrosOnly
|
||||||
|
} else {
|
||||||
|
DepKind::Explicit
|
||||||
|
};
|
||||||
|
|
||||||
let (cnum, ..) = self.resolve_crate(
|
let (cnum, ..) = self.resolve_crate(
|
||||||
&None, info.ident, info.name, None, item.span, PathKind::Crate, info.dep_kind,
|
&None, item.ident.name, rename, None, item.span, PathKind::Crate, dep_kind,
|
||||||
);
|
);
|
||||||
|
|
||||||
let def_id = definitions.opt_local_def_id(item.id).unwrap();
|
let def_id = definitions.opt_local_def_id(item.id).unwrap();
|
||||||
let len = definitions.def_path(def_id.index).data.len();
|
let path_len = definitions.def_path(def_id.index).data.len();
|
||||||
|
|
||||||
let extern_crate =
|
let extern_crate = ExternCrate { def_id, span: item.span, direct: true, path_len };
|
||||||
ExternCrate { def_id: def_id, span: item.span, direct: true, path_len: len };
|
|
||||||
self.update_extern_crate(cnum, extern_crate, &mut FxHashSet());
|
self.update_extern_crate(cnum, extern_crate, &mut FxHashSet());
|
||||||
self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
self.cstore.add_extern_mod_stmt_cnum(item.id, cnum);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_crate_from_path(&mut self, name: Symbol, span: Span) -> CrateNum {
|
||||||
|
self.resolve_crate(&None, name, name, None, span, PathKind::Crate, DepKind::Explicit).0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
|
||||||
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
|
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
|
||||||
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
|
||||||
use syntax::feature_gate::{feature_err, emit_feature_err, GateIssue};
|
use syntax::feature_gate::{feature_err, emit_feature_err, GateIssue};
|
||||||
|
use syntax::parse::token;
|
||||||
|
|
||||||
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
|
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
|
||||||
use errors::{DiagnosticBuilder, DiagnosticId};
|
use errors::{DiagnosticBuilder, DiagnosticId};
|
||||||
|
@ -2959,6 +2960,16 @@ impl<'a> Resolver<'a> {
|
||||||
// `$crate::a::b`
|
// `$crate::a::b`
|
||||||
module = Some(self.resolve_crate_root(ident.node.ctxt));
|
module = Some(self.resolve_crate_root(ident.node.ctxt));
|
||||||
continue
|
continue
|
||||||
|
} else if i == 1 && self.session.features.borrow().extern_absolute_paths &&
|
||||||
|
path[0].node.name == keywords::CrateRoot.name() &&
|
||||||
|
!token::Ident(ident.node).is_path_segment_keyword() {
|
||||||
|
// `::extern_crate::a::b`
|
||||||
|
let crate_id = self.crate_loader.resolve_crate_from_path(name, ident.span);
|
||||||
|
let crate_root =
|
||||||
|
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
||||||
|
self.populate_module_if_necessary(crate_root);
|
||||||
|
module = Some(crate_root);
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,14 @@ use self::ImportDirectiveSubclass::*;
|
||||||
|
|
||||||
use {AmbiguityError, Module, PerNS};
|
use {AmbiguityError, Module, PerNS};
|
||||||
use Namespace::{self, TypeNS, MacroNS};
|
use Namespace::{self, TypeNS, MacroNS};
|
||||||
use {NameBinding, NameBindingKind, PathResult, PrivacyError};
|
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
|
||||||
use Resolver;
|
use Resolver;
|
||||||
use {names_to_string, module_to_string};
|
use {names_to_string, module_to_string};
|
||||||
use {resolve_error, ResolutionError};
|
use {resolve_error, ResolutionError};
|
||||||
|
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::lint::builtin::PUB_USE_OF_PRIVATE_EXTERN_CRATE;
|
use rustc::lint::builtin::PUB_USE_OF_PRIVATE_EXTERN_CRATE;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||||
use rustc::hir::def::*;
|
use rustc::hir::def::*;
|
||||||
use rustc::session::DiagnosticMessageId;
|
use rustc::session::DiagnosticMessageId;
|
||||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
||||||
|
@ -602,8 +602,60 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||||
// If appropriate, returns an error to report.
|
// If appropriate, returns an error to report.
|
||||||
fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Span, String)> {
|
fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Span, String)> {
|
||||||
self.current_module = directive.parent;
|
self.current_module = directive.parent;
|
||||||
|
|
||||||
let ImportDirective { ref module_path, span, .. } = *directive;
|
let ImportDirective { ref module_path, span, .. } = *directive;
|
||||||
|
|
||||||
|
// Extern crate mode for absolute paths needs some
|
||||||
|
// special support for single-segment imports.
|
||||||
|
let extern_absolute_paths = self.session.features.borrow().extern_absolute_paths;
|
||||||
|
if module_path.len() == 1 && module_path[0].node.name == keywords::CrateRoot.name() {
|
||||||
|
match directive.subclass {
|
||||||
|
GlobImport { .. } if extern_absolute_paths => {
|
||||||
|
return Some((directive.span,
|
||||||
|
"cannot glob-import all possible crates".to_string()));
|
||||||
|
}
|
||||||
|
SingleImport { source, target, .. } => {
|
||||||
|
let crate_root = if source.name == keywords::Crate.name() {
|
||||||
|
if target.name == keywords::Crate.name() {
|
||||||
|
return Some((directive.span,
|
||||||
|
"crate root imports need to be explicitly named: \
|
||||||
|
`use crate as name;`".to_string()));
|
||||||
|
} else {
|
||||||
|
Some(self.resolve_crate_root(source.ctxt.modern()))
|
||||||
|
}
|
||||||
|
} else if extern_absolute_paths &&
|
||||||
|
!token::Ident(source).is_path_segment_keyword() {
|
||||||
|
let crate_id =
|
||||||
|
self.crate_loader.resolve_crate_from_path(source.name, directive.span);
|
||||||
|
let crate_root =
|
||||||
|
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
||||||
|
self.populate_module_if_necessary(crate_root);
|
||||||
|
Some(crate_root)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(crate_root) = crate_root {
|
||||||
|
let binding = (crate_root, ty::Visibility::Public, directive.span,
|
||||||
|
directive.expansion).to_name_binding(self.arenas);
|
||||||
|
let binding = self.arenas.alloc_name_binding(NameBinding {
|
||||||
|
kind: NameBindingKind::Import {
|
||||||
|
binding,
|
||||||
|
directive,
|
||||||
|
used: Cell::new(false),
|
||||||
|
legacy_self_import: false,
|
||||||
|
},
|
||||||
|
vis: directive.vis.get(),
|
||||||
|
span: directive.span,
|
||||||
|
expansion: directive.expansion,
|
||||||
|
});
|
||||||
|
let _ = self.try_define(directive.parent, target, TypeNS, binding);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let module_result = self.resolve_path(&module_path, None, true, span);
|
let module_result = self.resolve_path(&module_path, None, true, span);
|
||||||
let module = match module_result {
|
let module = match module_result {
|
||||||
PathResult::Module(module) => module,
|
PathResult::Module(module) => module,
|
||||||
|
|
|
@ -430,6 +430,9 @@ declare_features! (
|
||||||
|
|
||||||
// generic associated types (RFC 1598)
|
// generic associated types (RFC 1598)
|
||||||
(active, generic_associated_types, "1.23.0", Some(44265)),
|
(active, generic_associated_types, "1.23.0", Some(44265)),
|
||||||
|
|
||||||
|
// Resolve absolute paths as paths from other crates
|
||||||
|
(active, extern_absolute_paths, "1.24.0", Some(44660)),
|
||||||
);
|
);
|
||||||
|
|
||||||
declare_features! (
|
declare_features! (
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct S;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Z;
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(extern_absolute_paths)]
|
||||||
|
|
||||||
|
use xcrate::S; //~ ERROR can't find crate for `xcrate`
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(extern_absolute_paths)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = ::xcrate::S; //~ ERROR can't find crate for `xcrate`
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(extern_absolute_paths)]
|
||||||
|
|
||||||
|
use ycrate; //~ ERROR can't find crate for `ycrate`
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// aux-build:xcrate.rs
|
||||||
|
|
||||||
|
#![feature(crate_in_paths)]
|
||||||
|
#![feature(extern_absolute_paths)]
|
||||||
|
|
||||||
|
use crate; //~ ERROR unresolved import `crate`
|
||||||
|
//~^ NOTE crate root imports need to be explicitly named: `use crate as name;`
|
||||||
|
use *; //~ ERROR unresolved import `*`
|
||||||
|
//~^ NOTE cannot glob-import all possible crates
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = ::xcrate; //~ ERROR expected value, found module `xcrate`
|
||||||
|
//~^ NOTE not a value
|
||||||
|
}
|
|
@ -11,10 +11,12 @@
|
||||||
#![feature(crate_in_paths)]
|
#![feature(crate_in_paths)]
|
||||||
|
|
||||||
use crate::m::f;
|
use crate::m::f;
|
||||||
|
use crate as root;
|
||||||
|
|
||||||
mod m {
|
mod m {
|
||||||
pub fn f() -> u8 { 1 }
|
pub fn f() -> u8 { 1 }
|
||||||
pub fn g() -> u8 { 2 }
|
pub fn g() -> u8 { 2 }
|
||||||
|
pub fn h() -> u8 { 3 }
|
||||||
|
|
||||||
// OK, visibilities are implicitly absolute like imports
|
// OK, visibilities are implicitly absolute like imports
|
||||||
pub(in crate::m) struct S;
|
pub(in crate::m) struct S;
|
||||||
|
@ -23,14 +25,17 @@ mod m {
|
||||||
mod n
|
mod n
|
||||||
{
|
{
|
||||||
use crate::m::f;
|
use crate::m::f;
|
||||||
|
use crate as root;
|
||||||
pub fn check() {
|
pub fn check() {
|
||||||
assert_eq!(f(), 1);
|
assert_eq!(f(), 1);
|
||||||
assert_eq!(::crate::m::g(), 2);
|
assert_eq!(::crate::m::g(), 2);
|
||||||
|
assert_eq!(root::m::h(), 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(f(), 1);
|
assert_eq!(f(), 1);
|
||||||
assert_eq!(::crate::m::g(), 2);
|
assert_eq!(::crate::m::g(), 2);
|
||||||
|
assert_eq!(root::m::h(), 3);
|
||||||
n::check();
|
n::check();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct S;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Z;
|
31
src/test/run-pass/rfc-2126-extern-absolute-paths/basic.rs
Normal file
31
src/test/run-pass/rfc-2126-extern-absolute-paths/basic.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// aux-build:xcrate.rs
|
||||||
|
|
||||||
|
#![feature(extern_absolute_paths)]
|
||||||
|
|
||||||
|
use xcrate::Z;
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
use xcrate;
|
||||||
|
use 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 = ::xcrate::S;
|
||||||
|
assert_eq!(format!("{:?}", s), "S");
|
||||||
|
let z = Z;
|
||||||
|
assert_eq!(format!("{:?}", z), "Z");
|
||||||
|
}
|
15
src/test/ui/feature-gate-extern_absolute_paths.rs
Normal file
15
src/test/ui/feature-gate-extern_absolute_paths.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use core::default; //~ ERROR unresolved import `core`
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: u8 = ::core::default::Default(); //~ ERROR failed to resolve
|
||||||
|
}
|
14
src/test/ui/feature-gate-extern_absolute_paths.stderr
Normal file
14
src/test/ui/feature-gate-extern_absolute_paths.stderr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0432]: unresolved import `core`
|
||||||
|
--> $DIR/feature-gate-extern_absolute_paths.rs:11:5
|
||||||
|
|
|
||||||
|
11 | use core::default; //~ ERROR unresolved import `core`
|
||||||
|
| ^^^^ Maybe a missing `extern crate core;`?
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve. Maybe a missing `extern crate core;`?
|
||||||
|
--> $DIR/feature-gate-extern_absolute_paths.rs:14:19
|
||||||
|
|
|
||||||
|
14 | let _: u8 = ::core::default::Default(); //~ ERROR failed to resolve
|
||||||
|
| ^^^^ Maybe a missing `extern crate core;`?
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Reference in a new issue