Skip to content

Commit 38c82a2

Browse files
committed
rustc_resolve: always include core, std and meta in the extern prelude.
1 parent 9eb7a3c commit 38c82a2

File tree

9 files changed

+181
-45
lines changed

9 files changed

+181
-45
lines changed

src/librustc_metadata/creader.rs

+61-20
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ enum LoadResult {
100100
Loaded(Library),
101101
}
102102

103+
enum LoadError<'a> {
104+
LocatorError(locator::Context<'a>),
105+
}
106+
107+
impl<'a> LoadError<'a> {
108+
fn report(self) -> ! {
109+
match self {
110+
LoadError::LocatorError(mut locate_ctxt) => locate_ctxt.report_errs(),
111+
}
112+
}
113+
}
114+
103115
impl<'a> CrateLoader<'a> {
104116
pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self {
105117
CrateLoader {
@@ -268,16 +280,17 @@ impl<'a> CrateLoader<'a> {
268280
(cnum, cmeta)
269281
}
270282

271-
fn resolve_crate(&mut self,
272-
root: &Option<CratePaths>,
273-
ident: Symbol,
274-
name: Symbol,
275-
hash: Option<&Svh>,
276-
extra_filename: Option<&str>,
277-
span: Span,
278-
path_kind: PathKind,
279-
mut dep_kind: DepKind)
280-
-> (CrateNum, Lrc<cstore::CrateMetadata>) {
283+
fn resolve_crate<'b>(
284+
&'b mut self,
285+
root: &'b Option<CratePaths>,
286+
ident: Symbol,
287+
name: Symbol,
288+
hash: Option<&'b Svh>,
289+
extra_filename: Option<&'b str>,
290+
span: Span,
291+
path_kind: PathKind,
292+
mut dep_kind: DepKind,
293+
) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
281294
info!("resolving crate `extern crate {} as {}`", name, ident);
282295
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
283296
LoadResult::Previous(cnum)
@@ -321,7 +334,7 @@ impl<'a> CrateLoader<'a> {
321334
};
322335

323336
self.load(&mut proc_macro_locator)
324-
}).unwrap_or_else(|| locate_ctxt.report_errs())
337+
}).ok_or_else(move || LoadError::LocatorError(locate_ctxt))?
325338
};
326339

327340
match result {
@@ -333,10 +346,10 @@ impl<'a> CrateLoader<'a> {
333346
data.dep_kind.with_lock(|data_dep_kind| {
334347
*data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
335348
});
336-
(cnum, data)
349+
Ok((cnum, data))
337350
}
338351
LoadResult::Loaded(library) => {
339-
self.register_crate(root, ident, span, library, dep_kind)
352+
Ok(self.register_crate(root, ident, span, library, dep_kind))
340353
}
341354
}
342355
}
@@ -441,7 +454,7 @@ impl<'a> CrateLoader<'a> {
441454
let (local_cnum, ..) = self.resolve_crate(
442455
root, dep.name, dep.name, Some(&dep.hash), Some(&dep.extra_filename), span,
443456
PathKind::Dependency, dep_kind,
444-
);
457+
).unwrap_or_else(|err| err.report());
445458
local_cnum
446459
})).collect()
447460
}
@@ -695,7 +708,8 @@ impl<'a> CrateLoader<'a> {
695708

696709
let dep_kind = DepKind::Implicit;
697710
let (cnum, data) =
698-
self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind);
711+
self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind)
712+
.unwrap_or_else(|err| err.report());
699713

700714
// Sanity check the loaded crate to ensure it is indeed a panic runtime
701715
// and the panic strategy is indeed what we thought it was.
@@ -803,7 +817,8 @@ impl<'a> CrateLoader<'a> {
803817
let dep_kind = DepKind::Explicit;
804818
let (_, data) =
805819
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
806-
PathKind::Crate, dep_kind);
820+
PathKind::Crate, dep_kind)
821+
.unwrap_or_else(|err| err.report());
807822

808823
// Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
809824
if !data.root.sanitizer_runtime {
@@ -826,7 +841,8 @@ impl<'a> CrateLoader<'a> {
826841
let dep_kind = DepKind::Implicit;
827842
let (_, data) =
828843
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
829-
PathKind::Crate, dep_kind);
844+
PathKind::Crate, dep_kind)
845+
.unwrap_or_else(|err| err.report());
830846

831847
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
832848
if !data.root.profiler_runtime {
@@ -946,7 +962,8 @@ impl<'a> CrateLoader<'a> {
946962
None,
947963
DUMMY_SP,
948964
PathKind::Crate,
949-
DepKind::Implicit);
965+
DepKind::Implicit)
966+
.unwrap_or_else(|err| err.report());
950967
self.sess.injected_allocator.set(Some(cnum));
951968
data
952969
})
@@ -1103,7 +1120,7 @@ impl<'a> CrateLoader<'a> {
11031120
let (cnum, ..) = self.resolve_crate(
11041121
&None, item.ident.name, orig_name, None, None,
11051122
item.span, PathKind::Crate, dep_kind,
1106-
);
1123+
).unwrap_or_else(|err| err.report());
11071124

11081125
let def_id = definitions.opt_local_def_id(item.id).unwrap();
11091126
let path_len = definitions.def_path(def_id.index).data.len();
@@ -1131,7 +1148,7 @@ impl<'a> CrateLoader<'a> {
11311148
) -> CrateNum {
11321149
let cnum = self.resolve_crate(
11331150
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
1134-
).0;
1151+
).unwrap_or_else(|err| err.report()).0;
11351152

11361153
self.update_extern_crate(
11371154
cnum,
@@ -1147,4 +1164,28 @@ impl<'a> CrateLoader<'a> {
11471164

11481165
cnum
11491166
}
1167+
1168+
pub fn maybe_process_path_extern(
1169+
&mut self,
1170+
name: Symbol,
1171+
span: Span,
1172+
) -> Option<CrateNum> {
1173+
let cnum = self.resolve_crate(
1174+
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
1175+
).ok()?.0;
1176+
1177+
self.update_extern_crate(
1178+
cnum,
1179+
ExternCrate {
1180+
src: ExternCrateSource::Path,
1181+
span,
1182+
// to have the least priority in `update_extern_crate`
1183+
path_len: usize::max_value(),
1184+
direct: true,
1185+
},
1186+
&mut FxHashSet(),
1187+
);
1188+
1189+
Some(cnum)
1190+
}
11501191
}

src/librustc_resolve/lib.rs

+28-23
Original file line numberDiff line numberDiff line change
@@ -1674,13 +1674,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
16741674

16751675
let mut extern_prelude: FxHashSet<Name> =
16761676
session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();
1677-
if !attr::contains_name(&krate.attrs, "no_core") {
1678-
if !attr::contains_name(&krate.attrs, "no_std") {
1679-
extern_prelude.insert(Symbol::intern("std"));
1680-
} else {
1681-
extern_prelude.insert(Symbol::intern("core"));
1682-
}
1683-
}
1677+
1678+
// HACK(eddyb) this ignore the `no_{core,std}` attributes.
1679+
// FIXME(eddyb) warn (elsewhere) if core/std is used with `no_{core,std}`.
1680+
// if !attr::contains_name(&krate.attrs, "no_core") {
1681+
// if !attr::contains_name(&krate.attrs, "no_std") {
1682+
extern_prelude.insert(Symbol::intern("core"));
1683+
extern_prelude.insert(Symbol::intern("std"));
1684+
extern_prelude.insert(Symbol::intern("meta"));
16841685

16851686
let mut invocations = FxHashMap();
16861687
invocations.insert(Mark::root(),
@@ -1982,7 +1983,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
19821983
"access to extern crates through prelude is experimental").emit();
19831984
}
19841985

1985-
let crate_root = self.load_extern_prelude_crate_if_needed(ident);
1986+
let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
1987+
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
1988+
self.populate_module_if_necessary(&crate_root);
19861989

19871990
let binding = (crate_root, ty::Visibility::Public,
19881991
ident.span, Mark::root()).to_name_binding(self.arenas);
@@ -2010,13 +2013,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
20102013
None
20112014
}
20122015

2013-
fn load_extern_prelude_crate_if_needed(&mut self, ident: Ident) -> Module<'a> {
2014-
let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
2015-
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
2016-
self.populate_module_if_necessary(&crate_root);
2017-
crate_root
2018-
}
2019-
20202016
fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
20212017
-> Option<Module<'a>> {
20222018
if !module.expansion.is_descendant_of(span.ctxt().outer()) {
@@ -4427,15 +4423,24 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
44274423

44284424
if self.session.features_untracked().extern_prelude {
44294425
let extern_prelude_names = self.extern_prelude.clone();
4430-
for &krate_name in extern_prelude_names.iter() {
4431-
let krate_ident = Ident::with_empty_ctxt(krate_name);
4432-
let external_prelude_module = self.load_extern_prelude_crate_if_needed(krate_ident);
4426+
for &name in extern_prelude_names.iter() {
4427+
let ident = Ident::with_empty_ctxt(name);
4428+
match self.crate_loader.maybe_process_path_extern(name, ident.span) {
4429+
Some(crate_id) => {
4430+
let crate_root = self.get_module(DefId {
4431+
krate: crate_id,
4432+
index: CRATE_DEF_INDEX,
4433+
});
4434+
self.populate_module_if_necessary(&crate_root);
44334435

4434-
suggestions.extend(
4435-
self.lookup_import_candidates_from_module(
4436-
lookup_name, namespace, external_prelude_module, krate_ident, &filter_fn
4437-
)
4438-
);
4436+
suggestions.extend(
4437+
self.lookup_import_candidates_from_module(
4438+
lookup_name, namespace, crate_root, ident, &filter_fn
4439+
)
4440+
);
4441+
}
4442+
None => {}
4443+
}
44394444
}
44404445
}
44414446

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// edition:2018
12+
13+
// Tests that `meta` is whitelisted, even if the crate doesn't exist
14+
// yet (i.e. it causes a different error than `not-whitelisted.rs`).
15+
use meta; //~ ERROR can't find crate for `meta`
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0463]: can't find crate for `meta`
2+
--> $DIR/meta.rs:15:5
3+
|
4+
LL | use meta; //~ ERROR can't find crate for `meta`
5+
| ^^^^ can't find crate
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0463`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// edition:2018
12+
13+
// Tests that arbitrary crates (other than `core`, `std` and `meta`)
14+
// aren't allowed without `--extern`, even if they're in the sysroot.
15+
use alloc; //~ ERROR unresolved import `alloc`
16+
use test; //~ ERROR unresolved import `test`
17+
use proc_macro; //~ ERROR unresolved import `proc_macro`
18+
19+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0432]: unresolved import `alloc`
2+
--> $DIR/not-whitelisted.rs:15:5
3+
|
4+
LL | use alloc; //~ ERROR unresolved import `alloc`
5+
| ^^^^^ no `alloc` external crate
6+
7+
error[E0432]: unresolved import `test`
8+
--> $DIR/not-whitelisted.rs:16:5
9+
|
10+
LL | use test; //~ ERROR unresolved import `test`
11+
| ^^^^ no `test` external crate
12+
13+
error[E0432]: unresolved import `proc_macro`
14+
--> $DIR/not-whitelisted.rs:17:5
15+
|
16+
LL | use proc_macro; //~ ERROR unresolved import `proc_macro`
17+
| ^^^^^^^^^^ no `proc_macro` external crate
18+
19+
error: aborting due to 3 previous errors
20+
21+
For more information about this error, try `rustc --explain E0432`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// run-pass
12+
// edition:2018
13+
14+
// Tests that `core` and `std` are always available.
15+
use core::iter;
16+
use std::io;
17+
// FIXME(eddyb) Add a `meta` crate to the distribution.
18+
// use meta;
19+
20+
fn main() {
21+
for _ in iter::once(()) {
22+
io::stdout();
23+
}
24+
}

src/test/ui/rust-2018/remove-extern-crate.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// edition:2018
1313
// compile-pass
1414
// aux-build:remove-extern-crate.rs
15-
// compile-flags:--extern remove_extern_crate --extern core
15+
// compile-flags:--extern remove_extern_crate
1616

1717
#![warn(rust_2018_idioms)]
1818

src/test/ui/rust-2018/remove-extern-crate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// edition:2018
1313
// compile-pass
1414
// aux-build:remove-extern-crate.rs
15-
// compile-flags:--extern remove_extern_crate --extern core
15+
// compile-flags:--extern remove_extern_crate
1616

1717
#![warn(rust_2018_idioms)]
1818

0 commit comments

Comments
 (0)