about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael <michael.prantl@hotmail.de>2021-11-26 21:39:44 +0000
committerMichael <michael.prantl@hotmail.de>2021-12-01 21:59:54 +0000
commit2ca933301183b1e913802bc5710c0cb5218ada28 (patch)
treed8245bcf8b925372623abc3f1606a1aaede029a1
parent62f4ce993e8aa788c8269d75aea2db84cafb1f9f (diff)
downloadrust-2ca933301183b1e913802bc5710c0cb5218ada28.tar.gz
rust-2ca933301183b1e913802bc5710c0cb5218ada28.zip
Improve suggestion for extern crate self error message
-rw-r--r--compiler/rustc_metadata/src/creader.rs30
-rw-r--r--compiler/rustc_metadata/src/locator.rs12
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs48
-rw-r--r--compiler/rustc_resolve/src/imports.rs6
-rw-r--r--compiler/rustc_resolve/src/lib.rs4
-rw-r--r--src/test/ui/crate-loading/invalid-rlib.rs2
-rw-r--r--src/test/ui/crate-loading/invalid-rlib.stderr10
-rw-r--r--src/test/ui/extern-flag/empty-extern-arg.rs2
-rw-r--r--src/test/ui/extern/extern-crate-multiple-missing.rs2
-rw-r--r--src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr7
-rw-r--r--src/test/ui/rust-2018/uniform-paths/deadlock.rs3
-rw-r--r--src/test/ui/rust-2018/uniform-paths/deadlock.stderr21
12 files changed, 77 insertions, 70 deletions
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index f3e7d84c1c5..2626a2e189c 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -9,7 +9,6 @@ use rustc_ast::{self as ast, *};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::FatalError;
 use rustc_expand::base::SyntaxExtension;
 use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
@@ -508,15 +507,6 @@ impl<'a> CrateLoader<'a> {
         }))
     }
 
-    fn resolve_crate_or_abort<'b>(
-        &'b mut self,
-        name: Symbol,
-        span: Span,
-        dep_kind: CrateDepKind,
-    ) -> CrateNum {
-        self.resolve_crate(name, span, dep_kind).unwrap_or_else(|| FatalError.raise())
-    }
-
     fn resolve_crate<'b>(
         &'b mut self,
         name: Symbol,
@@ -524,15 +514,15 @@ impl<'a> CrateLoader<'a> {
         dep_kind: CrateDepKind,
     ) -> Option<CrateNum> {
         self.used_extern_options.insert(name);
-        self.maybe_resolve_crate(name, dep_kind, None).map_or_else(
-            |err| {
+        match self.maybe_resolve_crate(name, dep_kind, None) {
+            Ok(cnum) => Some(cnum),
+            Err(err) => {
                 let missing_core =
                     self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
                 err.report(&self.sess, span, missing_core);
                 None
-            },
-            |cnum| Some(cnum),
-        )
+            }
+        }
     }
 
     fn maybe_resolve_crate<'b>(
@@ -765,7 +755,7 @@ impl<'a> CrateLoader<'a> {
         };
         info!("panic runtime not found -- loading {}", name);
 
-        let cnum = self.resolve_crate_or_abort(name, DUMMY_SP, CrateDepKind::Implicit);
+        let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
         let data = self.cstore.get_crate_data(cnum);
 
         // Sanity check the loaded crate to ensure it is indeed a panic runtime
@@ -805,7 +795,7 @@ impl<'a> CrateLoader<'a> {
             );
         }
 
-        let cnum = self.resolve_crate_or_abort(name, DUMMY_SP, CrateDepKind::Implicit);
+        let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
         let data = self.cstore.get_crate_data(cnum);
 
         // Sanity check the loaded crate to ensure it is indeed a profiler runtime
@@ -1043,8 +1033,8 @@ impl<'a> CrateLoader<'a> {
         }
     }
 
-    pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum {
-        let cnum = self.resolve_crate_or_abort(name, span, CrateDepKind::Explicit);
+    pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
+        let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?;
 
         self.update_extern_crate(
             cnum,
@@ -1057,7 +1047,7 @@ impl<'a> CrateLoader<'a> {
             },
         );
 
-        cnum
+        Some(cnum)
     }
 
     pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 03181012bcc..e2fd8056f1a 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -220,7 +220,7 @@ use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::owning_ref::OwningRef;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::MetadataRef;
-use rustc_errors::{struct_span_err, DiagnosticBuilder, FatalError};
+use rustc_errors::{struct_span_err, FatalError};
 use rustc_session::config::{self, CrateType};
 use rustc_session::cstore::{CrateSource, MetadataLoader};
 use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
@@ -931,8 +931,8 @@ impl fmt::Display for MetadataError<'_> {
 }
 
 impl CrateError {
-    fn build_diag(self, sess: &Session, span: Span, missing_core: bool) -> DiagnosticBuilder<'_> {
-        match self {
+    crate fn report(self, sess: &Session, span: Span, missing_core: bool) {
+        let mut diag = match self {
             CrateError::NonAsciiName(crate_name) => sess.struct_span_err(
                 span,
                 &format!("cannot load a crate with a non-ascii name `{}`", crate_name),
@@ -1208,10 +1208,8 @@ impl CrateError {
                 "plugin `{}` only found in rlib format, but must be available in dylib format",
                 crate_name,
             ),
-        }
-    }
+        };
 
-    crate fn report(self, sess: &Session, span: Span, missing_core: bool) {
-        self.build_diag(sess, span, missing_core).emit();
+        diag.emit();
     }
 }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index aaa946f7542..c936e08d536 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -840,57 +840,41 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         let parent_scope = self.parent_scope;
         let expansion = parent_scope.expansion;
 
-        let module = if orig_name.is_none() && ident.name == kw::SelfLower {
+        let (used, module, binding) = if orig_name.is_none() && ident.name == kw::SelfLower {
             self.r
                 .session
                 .struct_span_err(item.span, "`extern crate self;` requires renaming")
                 .span_suggestion(
                     item.span,
-                    "try",
+                    "rename the `self` crate to be able to import it",
                     "extern crate self as name;".into(),
                     Applicability::HasPlaceholders,
                 )
                 .emit();
             return;
         } else if orig_name == Some(kw::SelfLower) {
-            self.r.graph_root
+            Some(self.r.graph_root)
         } else {
-            match self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id)
-            {
-                Some(crate_id) => {
+            self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id).map(
+                |crate_id| {
                     self.r.extern_crate_map.insert(local_def_id, crate_id);
                     self.r.expect_module(crate_id.as_def_id())
-                }
-                _ => {
-                    let dummy_import = self.r.arenas.alloc_import(Import {
-                        kind: ImportKind::ExternCrate { source: orig_name, target: ident },
-                        root_id: item.id,
-                        id: item.id,
-                        parent_scope: self.parent_scope,
-                        imported_module: Cell::new(None),
-                        has_attributes: !item.attrs.is_empty(),
-                        use_span_with_attributes: item.span_with_attributes(),
-                        use_span: item.span,
-                        root_span: item.span,
-                        span: item.span,
-                        module_path: Vec::new(),
-                        vis: Cell::new(vis),
-                        used: Cell::new(true),
-                    });
-                    self.r.import_dummy_binding(dummy_import);
-                    return;
-                }
-            }
-        };
-        let used = self.process_macro_use_imports(item, module);
-        let binding =
-            (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
+                },
+            )
+        }
+        .map(|module| {
+            let used = self.process_macro_use_imports(item, module);
+            let binding =
+                (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
+            (used, Some(ModuleOrUniformRoot::Module(module)), binding)
+        })
+        .unwrap_or((true, None, self.r.dummy_binding));
         let import = self.r.arenas.alloc_import(Import {
             kind: ImportKind::ExternCrate { source: orig_name, target: ident },
             root_id: item.id,
             id: item.id,
             parent_scope: self.parent_scope,
-            imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
+            imported_module: Cell::new(module),
             has_attributes: !item.attrs.is_empty(),
             use_span_with_attributes: item.span_with_attributes(),
             use_span: item.span,
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index d2c64b7e441..bf4cece8bde 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -600,10 +600,8 @@ impl<'a> Resolver<'a> {
 
     // Define a "dummy" resolution containing a Res::Err as a placeholder for a
     // failed resolution
-    crate fn import_dummy_binding(&mut self, import: &'a Import<'a>) {
-        if let ImportKind::Single { target, .. } | ImportKind::ExternCrate { target, .. } =
-            import.kind
-        {
+    fn import_dummy_binding(&mut self, import: &'a Import<'a>) {
+        if let ImportKind::Single { target, .. } = import.kind {
             let dummy_binding = self.dummy_binding;
             let dummy_binding = self.import(dummy_binding, import);
             self.per_ns(|this, ns| {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index a8ae4736c04..df0dc9307d6 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -3285,7 +3285,9 @@ impl<'a> Resolver<'a> {
                 Some(binding)
             } else {
                 let crate_id = if !speculative {
-                    self.crate_loader.process_path_extern(ident.name, ident.span)
+                    let Some(crate_id) =
+                        self.crate_loader.process_path_extern(ident.name, ident.span) else { return Some(self.dummy_binding); };
+                    crate_id
                 } else {
                     self.crate_loader.maybe_process_path_extern(ident.name)?
                 };
diff --git a/src/test/ui/crate-loading/invalid-rlib.rs b/src/test/ui/crate-loading/invalid-rlib.rs
index 77c29090a3e..aea861e3261 100644
--- a/src/test/ui/crate-loading/invalid-rlib.rs
+++ b/src/test/ui/crate-loading/invalid-rlib.rs
@@ -6,3 +6,5 @@
 #![no_std]
 use ::foo; //~ ERROR invalid metadata files for crate `foo`
 //~| NOTE failed to mmap file
+//~^^ ERROR invalid metadata files for crate `foo`
+//~| NOTE failed to mmap file
diff --git a/src/test/ui/crate-loading/invalid-rlib.stderr b/src/test/ui/crate-loading/invalid-rlib.stderr
index b2c79f742fb..3c0d23bf7b4 100644
--- a/src/test/ui/crate-loading/invalid-rlib.stderr
+++ b/src/test/ui/crate-loading/invalid-rlib.stderr
@@ -6,6 +6,14 @@ LL | use ::foo;
    |
    = note: failed to mmap file 'auxiliary/libfoo.rlib'
 
-error: aborting due to previous error
+error[E0786]: found invalid metadata files for crate `foo`
+  --> $DIR/invalid-rlib.rs:7:7
+   |
+LL | use ::foo;
+   |       ^^^
+   |
+   = note: failed to mmap file 'auxiliary/libfoo.rlib'
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0786`.
diff --git a/src/test/ui/extern-flag/empty-extern-arg.rs b/src/test/ui/extern-flag/empty-extern-arg.rs
index d3cb5aaaeba..3170537b0e0 100644
--- a/src/test/ui/extern-flag/empty-extern-arg.rs
+++ b/src/test/ui/extern-flag/empty-extern-arg.rs
@@ -1,4 +1,6 @@
 // compile-flags: --extern std=
 // error-pattern: extern location for std does not exist
+// needs-unwind since it affects the error output
+// ignore-emscripten compiled with panic=abort, personality not required
 
 fn main() {}
diff --git a/src/test/ui/extern/extern-crate-multiple-missing.rs b/src/test/ui/extern/extern-crate-multiple-missing.rs
index fa7da83a6df..a6560ca7862 100644
--- a/src/test/ui/extern/extern-crate-multiple-missing.rs
+++ b/src/test/ui/extern/extern-crate-multiple-missing.rs
@@ -3,6 +3,8 @@ extern crate bar; //~ ERROR can't find crate for `bar`
 extern crate foo; //~ ERROR can't find crate for `foo`
 
 fn main() {
+    // If the crate name introduced by `extern crate` failed to resolve then subsequent
+    // derived paths do not emit additional errors
     foo::something();
     bar::something();
 }
diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr
index 8f369f1b038..127765727b4 100644
--- a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr
+++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr
@@ -2,7 +2,12 @@ error: `extern crate self;` requires renaming
   --> $DIR/extern-crate-self-fail.rs:1:1
    |
 LL | extern crate self;
-   | ^^^^^^^^^^^^^^^^^^ help: try: `extern crate self as name;`
+   | ^^^^^^^^^^^^^^^^^^
+   |
+help: rename the `self` crate to be able to import it
+   |
+LL | extern crate self as name;
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: `#[macro_use]` is not supported on `extern crate self`
   --> $DIR/extern-crate-self-fail.rs:3:1
diff --git a/src/test/ui/rust-2018/uniform-paths/deadlock.rs b/src/test/ui/rust-2018/uniform-paths/deadlock.rs
index 83ed70a0459..2427bde6d18 100644
--- a/src/test/ui/rust-2018/uniform-paths/deadlock.rs
+++ b/src/test/ui/rust-2018/uniform-paths/deadlock.rs
@@ -1,7 +1,8 @@
 // edition:2018
 // compile-flags:--extern foo --extern bar
 
+use bar::foo; //~ ERROR can't find crate for `bar`
 use foo::bar; //~ ERROR can't find crate for `foo`
-use bar::foo;
+//~^^ ERROR unresolved imports `bar::foo`, `foo::bar`
 
 fn main() {}
diff --git a/src/test/ui/rust-2018/uniform-paths/deadlock.stderr b/src/test/ui/rust-2018/uniform-paths/deadlock.stderr
index 9336e90afb7..8b9863948bd 100644
--- a/src/test/ui/rust-2018/uniform-paths/deadlock.stderr
+++ b/src/test/ui/rust-2018/uniform-paths/deadlock.stderr
@@ -1,9 +1,24 @@
-error[E0463]: can't find crate for `foo`
+error[E0463]: can't find crate for `bar`
   --> $DIR/deadlock.rs:4:5
    |
+LL | use bar::foo;
+   |     ^^^ can't find crate
+
+error[E0463]: can't find crate for `foo`
+  --> $DIR/deadlock.rs:5:5
+   |
 LL | use foo::bar;
    |     ^^^ can't find crate
 
-error: aborting due to previous error
+error[E0432]: unresolved imports `bar::foo`, `foo::bar`
+  --> $DIR/deadlock.rs:4:5
+   |
+LL | use bar::foo;
+   |     ^^^^^^^^
+LL | use foo::bar;
+   |     ^^^^^^^^
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0463`.
+Some errors have detailed explanations: E0432, E0463.
+For more information about an error, try `rustc --explain E0432`.