about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_metadata/creader.rs81
-rw-r--r--src/librustc_resolve/lib.rs51
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/meta.rs17
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr9
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs19
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr21
-rw-r--r--src/test/ui/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs24
-rw-r--r--src/test/ui/rust-2018/remove-extern-crate.fixed2
-rw-r--r--src/test/ui/rust-2018/remove-extern-crate.rs2
9 files changed, 181 insertions, 45 deletions
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index e28bb260820..6eef2397f9c 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -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)
+    }
 }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index f0ff8c419fd..10dddfed6a5 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -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 => {}
+                }
             }
         }
 
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs b/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs
new file mode 100644
index 00000000000..499a322593c
--- /dev/null
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/meta.rs
@@ -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() {}
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr
new file mode 100644
index 00000000000..b8a9b54d26b
--- /dev/null
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/meta.stderr
@@ -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`.
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs
new file mode 100644
index 00000000000..f95961d2a9b
--- /dev/null
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs
@@ -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() {}
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr
new file mode 100644
index 00000000000..0865bd6bea5
--- /dev/null
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr
@@ -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`.
diff --git a/src/test/ui/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs b/src/test/ui/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs
new file mode 100644
index 00000000000..dfd9fbd2774
--- /dev/null
+++ b/src/test/ui/run-pass/rfcs/rfc-2126-extern-absolute-paths/whitelisted.rs
@@ -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();
+    }
+}
diff --git a/src/test/ui/rust-2018/remove-extern-crate.fixed b/src/test/ui/rust-2018/remove-extern-crate.fixed
index 895da74afd7..cdae815b200 100644
--- a/src/test/ui/rust-2018/remove-extern-crate.fixed
+++ b/src/test/ui/rust-2018/remove-extern-crate.fixed
@@ -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)]
 
diff --git a/src/test/ui/rust-2018/remove-extern-crate.rs b/src/test/ui/rust-2018/remove-extern-crate.rs
index c03431a6b88..4984da802c0 100644
--- a/src/test/ui/rust-2018/remove-extern-crate.rs
+++ b/src/test/ui/rust-2018/remove-extern-crate.rs
@@ -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)]