about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_metadata/src/creader.rs7
-rw-r--r--compiler/rustc_metadata/src/locator.rs37
-rw-r--r--src/test/ui/crate-loading/missing-std.rs11
-rw-r--r--src/test/ui/crate-loading/missing-std.stderr13
4 files changed, 63 insertions, 5 deletions
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 26db3a5f39d..e9ae22f8ced 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -511,8 +511,11 @@ impl<'a> CrateLoader<'a> {
         if dep.is_none() {
             self.used_extern_options.insert(name);
         }
-        self.maybe_resolve_crate(name, dep_kind, dep)
-            .unwrap_or_else(|err| err.report(self.sess, span))
+        self.maybe_resolve_crate(name, dep_kind, dep).unwrap_or_else(|err| {
+            let missing_core =
+                self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
+            err.report(&self.sess, span, missing_core)
+        })
     }
 
     fn maybe_resolve_crate<'b>(
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 7f6311861c1..6e736095090 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -790,7 +790,8 @@ pub fn find_plugin_registrar(
 ) -> (PathBuf, CrateDisambiguator) {
     match find_plugin_registrar_impl(sess, metadata_loader, name) {
         Ok(res) => res,
-        Err(err) => err.report(sess, span),
+        // `core` is always available if we got as far as loading plugins.
+        Err(err) => err.report(sess, span, false),
     }
 }
 
@@ -883,7 +884,7 @@ crate enum CrateError {
 }
 
 impl CrateError {
-    crate fn report(self, sess: &Session, span: Span) -> ! {
+    crate fn report(self, sess: &Session, span: Span, missing_core: bool) -> ! {
         let mut err = match self {
             CrateError::NonAsciiName(crate_name) => sess.struct_span_err(
                 span,
@@ -1068,7 +1069,37 @@ impl CrateError {
                     if (crate_name == sym::std || crate_name == sym::core)
                         && locator.triple != TargetTriple::from_triple(config::host_triple())
                     {
-                        err.note(&format!("the `{}` target may not be installed", locator.triple));
+                        if missing_core {
+                            err.note(&format!(
+                                "the `{}` target may not be installed",
+                                locator.triple
+                            ));
+                        } else {
+                            err.note(&format!(
+                                "the `{}` target may not support the standard library",
+                                locator.triple
+                            ));
+                        }
+                        if missing_core && std::env::var("RUSTUP_HOME").is_ok() {
+                            err.help(&format!(
+                                "consider downloading the target with `rustup target add {}`",
+                                locator.triple
+                            ));
+                        }
+                        // Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
+                        // NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
+                        // If it's not a dummy, that means someone added `extern crate std` explicitly and `#![no_std]` won't help.
+                        if !missing_core && span.is_dummy() {
+                            let current_crate =
+                                sess.opts.crate_name.as_deref().unwrap_or("<unknown>");
+                            err.note(&format!(
+                                "`std` is required by `{}` because it does not declare `#![no_std]`",
+                                current_crate
+                            ));
+                        }
+                        if sess.is_nightly_build() && std::env::var("CARGO").is_ok() {
+                            err.help("consider building the standard library from source with `cargo build -Zbuild-std`");
+                        }
                     } else if crate_name == sym::profiler_builtins {
                         err.note(&"the compiler may have been built without the profiler runtime");
                     }
diff --git a/src/test/ui/crate-loading/missing-std.rs b/src/test/ui/crate-loading/missing-std.rs
new file mode 100644
index 00000000000..442a7c01e5a
--- /dev/null
+++ b/src/test/ui/crate-loading/missing-std.rs
@@ -0,0 +1,11 @@
+// compile-flags: --target x86_64-unknown-uefi
+// rustc-env:CARGO=/usr/bin/cargo
+// rustc-env:RUSTUP_HOME=/home/bors/.rustup
+#![no_core]
+extern crate core;
+//~^ ERROR can't find crate for `core`
+//~| NOTE can't find crate
+//~| NOTE target may not be installed
+//~| HELP consider building the standard library from source with `cargo build -Zbuild-std`
+//~| HELP consider downloading the target with `rustup target add x86_64-unknown-uefi`
+fn main() {}
diff --git a/src/test/ui/crate-loading/missing-std.stderr b/src/test/ui/crate-loading/missing-std.stderr
new file mode 100644
index 00000000000..25808efdfa6
--- /dev/null
+++ b/src/test/ui/crate-loading/missing-std.stderr
@@ -0,0 +1,13 @@
+error[E0463]: can't find crate for `core`
+  --> $DIR/missing-std.rs:5:1
+   |
+LL | extern crate core;
+   | ^^^^^^^^^^^^^^^^^^ can't find crate
+   |
+   = note: the `x86_64-unknown-uefi` target may not be installed
+   = help: consider downloading the target with `rustup target add x86_64-unknown-uefi`
+   = help: consider building the standard library from source with `cargo build -Zbuild-std`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0463`.