rustc_resolve: always include core, std and meta in the extern prelude.
This commit is contained in:
parent
9eb7a3c76f
commit
38c82a2180
@ -100,6 +100,18 @@ enum LoadResult {
|
||||
Loaded(Library),
|
||||
}
|
||||
|
||||
enum LoadError<'a> {
|
||||
LocatorError(locator::Context<'a>),
|
||||
}
|
||||
|
||||
impl<'a> LoadError<'a> {
|
||||
fn report(self) -> ! {
|
||||
match self {
|
||||
LoadError::LocatorError(mut locate_ctxt) => locate_ctxt.report_errs(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> CrateLoader<'a> {
|
||||
pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self {
|
||||
CrateLoader {
|
||||
@ -268,16 +280,17 @@ impl<'a> CrateLoader<'a> {
|
||||
(cnum, cmeta)
|
||||
}
|
||||
|
||||
fn resolve_crate(&mut self,
|
||||
root: &Option<CratePaths>,
|
||||
ident: Symbol,
|
||||
name: Symbol,
|
||||
hash: Option<&Svh>,
|
||||
extra_filename: Option<&str>,
|
||||
span: Span,
|
||||
path_kind: PathKind,
|
||||
mut dep_kind: DepKind)
|
||||
-> (CrateNum, Lrc<cstore::CrateMetadata>) {
|
||||
fn resolve_crate<'b>(
|
||||
&'b mut self,
|
||||
root: &'b Option<CratePaths>,
|
||||
ident: Symbol,
|
||||
name: Symbol,
|
||||
hash: Option<&'b Svh>,
|
||||
extra_filename: Option<&'b str>,
|
||||
span: Span,
|
||||
path_kind: PathKind,
|
||||
mut dep_kind: DepKind,
|
||||
) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
|
||||
info!("resolving crate `extern crate {} as {}`", name, ident);
|
||||
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
|
||||
LoadResult::Previous(cnum)
|
||||
@ -321,7 +334,7 @@ impl<'a> CrateLoader<'a> {
|
||||
};
|
||||
|
||||
self.load(&mut proc_macro_locator)
|
||||
}).unwrap_or_else(|| locate_ctxt.report_errs())
|
||||
}).ok_or_else(move || LoadError::LocatorError(locate_ctxt))?
|
||||
};
|
||||
|
||||
match result {
|
||||
@ -333,10 +346,10 @@ impl<'a> CrateLoader<'a> {
|
||||
data.dep_kind.with_lock(|data_dep_kind| {
|
||||
*data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
|
||||
});
|
||||
(cnum, data)
|
||||
Ok((cnum, data))
|
||||
}
|
||||
LoadResult::Loaded(library) => {
|
||||
self.register_crate(root, ident, span, library, dep_kind)
|
||||
Ok(self.register_crate(root, ident, span, library, dep_kind))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -441,7 +454,7 @@ impl<'a> CrateLoader<'a> {
|
||||
let (local_cnum, ..) = self.resolve_crate(
|
||||
root, dep.name, dep.name, Some(&dep.hash), Some(&dep.extra_filename), span,
|
||||
PathKind::Dependency, dep_kind,
|
||||
);
|
||||
).unwrap_or_else(|err| err.report());
|
||||
local_cnum
|
||||
})).collect()
|
||||
}
|
||||
@ -695,7 +708,8 @@ impl<'a> CrateLoader<'a> {
|
||||
|
||||
let dep_kind = DepKind::Implicit;
|
||||
let (cnum, data) =
|
||||
self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind);
|
||||
self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind)
|
||||
.unwrap_or_else(|err| err.report());
|
||||
|
||||
// Sanity check the loaded crate to ensure it is indeed a panic runtime
|
||||
// and the panic strategy is indeed what we thought it was.
|
||||
@ -803,7 +817,8 @@ impl<'a> CrateLoader<'a> {
|
||||
let dep_kind = DepKind::Explicit;
|
||||
let (_, data) =
|
||||
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
|
||||
PathKind::Crate, dep_kind);
|
||||
PathKind::Crate, dep_kind)
|
||||
.unwrap_or_else(|err| err.report());
|
||||
|
||||
// Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
|
||||
if !data.root.sanitizer_runtime {
|
||||
@ -826,7 +841,8 @@ impl<'a> CrateLoader<'a> {
|
||||
let dep_kind = DepKind::Implicit;
|
||||
let (_, data) =
|
||||
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
|
||||
PathKind::Crate, dep_kind);
|
||||
PathKind::Crate, dep_kind)
|
||||
.unwrap_or_else(|err| err.report());
|
||||
|
||||
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
|
||||
if !data.root.profiler_runtime {
|
||||
@ -946,7 +962,8 @@ impl<'a> CrateLoader<'a> {
|
||||
None,
|
||||
DUMMY_SP,
|
||||
PathKind::Crate,
|
||||
DepKind::Implicit);
|
||||
DepKind::Implicit)
|
||||
.unwrap_or_else(|err| err.report());
|
||||
self.sess.injected_allocator.set(Some(cnum));
|
||||
data
|
||||
})
|
||||
@ -1103,7 +1120,7 @@ impl<'a> CrateLoader<'a> {
|
||||
let (cnum, ..) = self.resolve_crate(
|
||||
&None, item.ident.name, orig_name, None, None,
|
||||
item.span, PathKind::Crate, dep_kind,
|
||||
);
|
||||
).unwrap_or_else(|err| err.report());
|
||||
|
||||
let def_id = definitions.opt_local_def_id(item.id).unwrap();
|
||||
let path_len = definitions.def_path(def_id.index).data.len();
|
||||
@ -1131,7 +1148,7 @@ impl<'a> CrateLoader<'a> {
|
||||
) -> CrateNum {
|
||||
let cnum = self.resolve_crate(
|
||||
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
|
||||
).0;
|
||||
).unwrap_or_else(|err| err.report()).0;
|
||||
|
||||
self.update_extern_crate(
|
||||
cnum,
|
||||
@ -1147,4 +1164,28 @@ impl<'a> CrateLoader<'a> {
|
||||
|
||||
cnum
|
||||
}
|
||||
|
||||
pub fn maybe_process_path_extern(
|
||||
&mut self,
|
||||
name: Symbol,
|
||||
span: Span,
|
||||
) -> Option<CrateNum> {
|
||||
let cnum = self.resolve_crate(
|
||||
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
|
||||
).ok()?.0;
|
||||
|
||||
self.update_extern_crate(
|
||||
cnum,
|
||||
ExternCrate {
|
||||
src: ExternCrateSource::Path,
|
||||
span,
|
||||
// to have the least priority in `update_extern_crate`
|
||||
path_len: usize::max_value(),
|
||||
direct: true,
|
||||
},
|
||||
&mut FxHashSet(),
|
||||
);
|
||||
|
||||
Some(cnum)
|
||||
}
|
||||
}
|
||||
|
@ -1674,13 +1674,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
|
||||
let mut extern_prelude: FxHashSet<Name> =
|
||||
session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();
|
||||
if !attr::contains_name(&krate.attrs, "no_core") {
|
||||
if !attr::contains_name(&krate.attrs, "no_std") {
|
||||
extern_prelude.insert(Symbol::intern("std"));
|
||||
} else {
|
||||
extern_prelude.insert(Symbol::intern("core"));
|
||||
}
|
||||
}
|
||||
|
||||
// HACK(eddyb) this ignore the `no_{core,std}` attributes.
|
||||
// FIXME(eddyb) warn (elsewhere) if core/std is used with `no_{core,std}`.
|
||||
// if !attr::contains_name(&krate.attrs, "no_core") {
|
||||
// if !attr::contains_name(&krate.attrs, "no_std") {
|
||||
extern_prelude.insert(Symbol::intern("core"));
|
||||
extern_prelude.insert(Symbol::intern("std"));
|
||||
extern_prelude.insert(Symbol::intern("meta"));
|
||||
|
||||
let mut invocations = FxHashMap();
|
||||
invocations.insert(Mark::root(),
|
||||
@ -1982,7 +1983,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
"access to extern crates through prelude is experimental").emit();
|
||||
}
|
||||
|
||||
let crate_root = self.load_extern_prelude_crate_if_needed(ident);
|
||||
let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
|
||||
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
||||
self.populate_module_if_necessary(&crate_root);
|
||||
|
||||
let binding = (crate_root, ty::Visibility::Public,
|
||||
ident.span, Mark::root()).to_name_binding(self.arenas);
|
||||
@ -2010,13 +2013,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
None
|
||||
}
|
||||
|
||||
fn load_extern_prelude_crate_if_needed(&mut self, ident: Ident) -> Module<'a> {
|
||||
let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
|
||||
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
||||
self.populate_module_if_necessary(&crate_root);
|
||||
crate_root
|
||||
}
|
||||
|
||||
fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
|
||||
-> Option<Module<'a>> {
|
||||
if !module.expansion.is_descendant_of(span.ctxt().outer()) {
|
||||
@ -4427,15 +4423,24 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||
|
||||
if self.session.features_untracked().extern_prelude {
|
||||
let extern_prelude_names = self.extern_prelude.clone();
|
||||
for &krate_name in extern_prelude_names.iter() {
|
||||
let krate_ident = Ident::with_empty_ctxt(krate_name);
|
||||
let external_prelude_module = self.load_extern_prelude_crate_if_needed(krate_ident);
|
||||
for &name in extern_prelude_names.iter() {
|
||||
let ident = Ident::with_empty_ctxt(name);
|
||||
match self.crate_loader.maybe_process_path_extern(name, ident.span) {
|
||||
Some(crate_id) => {
|
||||
let crate_root = self.get_module(DefId {
|
||||
krate: crate_id,
|
||||
index: CRATE_DEF_INDEX,
|
||||
});
|
||||
self.populate_module_if_necessary(&crate_root);
|
||||
|
||||
suggestions.extend(
|
||||
self.lookup_import_candidates_from_module(
|
||||
lookup_name, namespace, external_prelude_module, krate_ident, &filter_fn
|
||||
)
|
||||
);
|
||||
suggestions.extend(
|
||||
self.lookup_import_candidates_from_module(
|
||||
lookup_name, namespace, crate_root, ident, &filter_fn
|
||||
)
|
||||
);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
17
src/test/ui/rfc-2126-extern-absolute-paths/meta.rs
Normal file
17
src/test/ui/rfc-2126-extern-absolute-paths/meta.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// edition:2018
|
||||
|
||||
// Tests that `meta` is whitelisted, even if the crate doesn't exist
|
||||
// yet (i.e. it causes a different error than `not-whitelisted.rs`).
|
||||
use meta; //~ ERROR can't find crate for `meta`
|
||||
|
||||
fn main() {}
|
9
src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr
Normal file
9
src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0463]: can't find crate for `meta`
|
||||
--> $DIR/meta.rs:15:5
|
||||
|
|
||||
LL | use meta; //~ ERROR can't find crate for `meta`
|
||||
| ^^^^ can't find crate
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0463`.
|
@ -0,0 +1,19 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// edition:2018
|
||||
|
||||
// Tests that arbitrary crates (other than `core`, `std` and `meta`)
|
||||
// aren't allowed without `--extern`, even if they're in the sysroot.
|
||||
use alloc; //~ ERROR unresolved import `alloc`
|
||||
use test; //~ ERROR unresolved import `test`
|
||||
use proc_macro; //~ ERROR unresolved import `proc_macro`
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,21 @@
|
||||
error[E0432]: unresolved import `alloc`
|
||||
--> $DIR/not-whitelisted.rs:15:5
|
||||
|
|
||||
LL | use alloc; //~ ERROR unresolved import `alloc`
|
||||
| ^^^^^ no `alloc` external crate
|
||||
|
||||
error[E0432]: unresolved import `test`
|
||||
--> $DIR/not-whitelisted.rs:16:5
|
||||
|
|
||||
LL | use test; //~ ERROR unresolved import `test`
|
||||
| ^^^^ no `test` external crate
|
||||
|
||||
error[E0432]: unresolved import `proc_macro`
|
||||
--> $DIR/not-whitelisted.rs:17:5
|
||||
|
|
||||
LL | use proc_macro; //~ ERROR unresolved import `proc_macro`
|
||||
| ^^^^^^^^^^ no `proc_macro` external crate
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
@ -0,0 +1,24 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// run-pass
|
||||
// edition:2018
|
||||
|
||||
// Tests that `core` and `std` are always available.
|
||||
use core::iter;
|
||||
use std::io;
|
||||
// FIXME(eddyb) Add a `meta` crate to the distribution.
|
||||
// use meta;
|
||||
|
||||
fn main() {
|
||||
for _ in iter::once(()) {
|
||||
io::stdout();
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
// edition:2018
|
||||
// compile-pass
|
||||
// aux-build:remove-extern-crate.rs
|
||||
// compile-flags:--extern remove_extern_crate --extern core
|
||||
// compile-flags:--extern remove_extern_crate
|
||||
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
// edition:2018
|
||||
// compile-pass
|
||||
// aux-build:remove-extern-crate.rs
|
||||
// compile-flags:--extern remove_extern_crate --extern core
|
||||
// compile-flags:--extern remove_extern_crate
|
||||
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user