From f67e73ab95a3052353a6761216f53bae22ce2c7a Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 26 Nov 2021 19:18:51 +0000 Subject: [PATCH 1/3] Factor out build reduced graph for extern crate --- .../rustc_resolve/src/build_reduced_graph.rs | 152 ++++++++++-------- 1 file changed, 83 insertions(+), 69 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 3cf9d324a38da..02e540e2091f5 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -683,75 +683,16 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } ItemKind::ExternCrate(orig_name) => { - let module = 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", - "extern crate self as name;".into(), - Applicability::HasPlaceholders, - ) - .emit(); - return; - } else if orig_name == Some(kw::SelfLower) { - self.r.graph_root - } else { - let crate_id = self.r.crate_loader.process_extern_crate( - item, - &self.r.definitions, - local_def_id, - ); - self.r.extern_crate_map.insert(local_def_id, crate_id); - self.r.expect_module(crate_id.as_def_id()) - }; - - let used = self.process_macro_use_imports(item, module); - let binding = - (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas); - 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))), - 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(used), - }); - self.r.potentially_unused_imports.push(import); - let imported_binding = self.r.import(binding, import); - if ptr::eq(parent, self.r.graph_root) { - if let Some(entry) = self.r.extern_prelude.get(&ident.normalize_to_macros_2_0()) - { - if expansion != LocalExpnId::ROOT - && orig_name.is_some() - && entry.extern_crate_item.is_none() - { - let msg = "macro-expanded `extern crate` items cannot \ - shadow names passed with `--extern`"; - self.r.session.span_err(item.span, msg); - } - } - let entry = - self.r.extern_prelude.entry(ident.normalize_to_macros_2_0()).or_insert( - ExternPreludeEntry { - extern_crate_item: None, - introduced_by_item: true, - }, - ); - entry.extern_crate_item = Some(imported_binding); - if orig_name.is_some() { - entry.introduced_by_item = true; - } - } - self.r.define(parent, ident, TypeNS, imported_binding); + self.build_reduced_graph_for_extern_crate( + orig_name, + ident, + item, + local_def_id, + sp, + expansion, + vis, + parent, + ); } ItemKind::Mod(..) => { @@ -889,6 +830,79 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } } + fn build_reduced_graph_for_extern_crate( + &mut self, + orig_name: Option, + ident: Ident, + item: &Item, + local_def_id: LocalDefId, + sp: Span, + expansion: LocalExpnId, + vis: ty::Visibility, + parent: Module<'a>, + ) { + let module = 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", + "extern crate self as name;".into(), + Applicability::HasPlaceholders, + ) + .emit(); + return; + } else if orig_name == Some(kw::SelfLower) { + self.r.graph_root + } else { + let crate_id = + self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id); + self.r.extern_crate_map.insert(local_def_id, crate_id); + self.r.expect_module(crate_id.as_def_id()) + }; + let used = self.process_macro_use_imports(item, module); + let binding = + (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas); + 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))), + 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(used), + }); + self.r.potentially_unused_imports.push(import); + let imported_binding = self.r.import(binding, import); + if ptr::eq(parent, self.r.graph_root) { + if let Some(entry) = self.r.extern_prelude.get(&ident.normalize_to_macros_2_0()) { + if expansion != LocalExpnId::ROOT + && orig_name.is_some() + && entry.extern_crate_item.is_none() + { + let msg = "macro-expanded `extern crate` items cannot \ + shadow names passed with `--extern`"; + self.r.session.span_err(item.span, msg); + } + } + let entry = self.r.extern_prelude.entry(ident.normalize_to_macros_2_0()).or_insert( + ExternPreludeEntry { extern_crate_item: None, introduced_by_item: true }, + ); + entry.extern_crate_item = Some(imported_binding); + if orig_name.is_some() { + entry.introduced_by_item = true; + } + } + self.r.define(parent, ident, TypeNS, imported_binding); + } + /// Constructs the reduced graph for one foreign item. fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) { let local_def_id = self.r.local_def_id(item.id); From 29b4b6cbc84f7ee784461fcb6e39c60a5ab5effc Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 26 Nov 2021 20:37:56 +0000 Subject: [PATCH 2/3] Stop treating extern crate loading failures as fatal errors --- compiler/rustc_metadata/src/creader.rs | 38 +++++++++++------ compiler/rustc_metadata/src/locator.rs | 22 +++++----- .../rustc_resolve/src/build_reduced_graph.rs | 41 ++++++++++++++----- compiler/rustc_resolve/src/imports.rs | 6 ++- src/test/ui/crate-loading/missing-std.rs | 1 + src/test/ui/crate-loading/missing-std.stderr | 6 ++- .../ui/extern-flag/empty-extern-arg.stderr | 6 ++- .../extern/extern-crate-multiple-missing.rs | 8 ++++ .../extern-crate-multiple-missing.stderr | 15 +++++++ src/test/ui/issues/issue-37131.stderr | 4 +- .../issue-49851/compiler-builtins-error.rs | 6 ++- .../compiler-builtins-error.stderr | 12 +++++- 12 files changed, 124 insertions(+), 41 deletions(-) create mode 100644 src/test/ui/extern/extern-crate-multiple-missing.rs create mode 100644 src/test/ui/extern/extern-crate-multiple-missing.stderr diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index eb0a693226c48..f3e7d84c1c530 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -9,6 +9,7 @@ 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; @@ -507,18 +508,31 @@ impl<'a> CrateLoader<'a> { })) } - fn resolve_crate<'b>( + 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, + span: Span, + dep_kind: CrateDepKind, + ) -> Option { self.used_extern_options.insert(name); - self.maybe_resolve_crate(name, dep_kind, None).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) - }) + self.maybe_resolve_crate(name, dep_kind, None).map_or_else( + |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>( @@ -751,7 +765,7 @@ impl<'a> CrateLoader<'a> { }; info!("panic runtime not found -- loading {}", name); - let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit); + let cnum = self.resolve_crate_or_abort(name, DUMMY_SP, CrateDepKind::Implicit); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a panic runtime @@ -791,7 +805,7 @@ impl<'a> CrateLoader<'a> { ); } - let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit); + let cnum = self.resolve_crate_or_abort(name, DUMMY_SP, CrateDepKind::Implicit); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a profiler runtime @@ -991,7 +1005,7 @@ impl<'a> CrateLoader<'a> { item: &ast::Item, definitions: &Definitions, def_id: LocalDefId, - ) -> CrateNum { + ) -> Option { match item.kind { ast::ItemKind::ExternCrate(orig_name) => { debug!( @@ -1011,7 +1025,7 @@ impl<'a> CrateLoader<'a> { CrateDepKind::Explicit }; - let cnum = self.resolve_crate(name, item.span, dep_kind); + let cnum = self.resolve_crate(name, item.span, dep_kind)?; let path_len = definitions.def_path(def_id).data.len(); self.update_extern_crate( @@ -1023,14 +1037,14 @@ impl<'a> CrateLoader<'a> { dependency_of: LOCAL_CRATE, }, ); - cnum + Some(cnum) } _ => bug!(), } } pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum { - let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit); + let cnum = self.resolve_crate_or_abort(name, span, CrateDepKind::Explicit); self.update_extern_crate( cnum, diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 7cba16e0a9ae3..03181012bccb7 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; +use rustc_errors::{struct_span_err, DiagnosticBuilder, FatalError}; use rustc_session::config::{self, CrateType}; use rustc_session::cstore::{CrateSource, MetadataLoader}; use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch}; @@ -814,11 +814,11 @@ pub fn find_plugin_registrar( span: Span, name: Symbol, ) -> PathBuf { - match find_plugin_registrar_impl(sess, metadata_loader, name) { - Ok(res) => res, + find_plugin_registrar_impl(sess, metadata_loader, name).unwrap_or_else(|err| { // `core` is always available if we got as far as loading plugins. - Err(err) => err.report(sess, span, false), - } + err.report(sess, span, false); + FatalError.raise() + }) } fn find_plugin_registrar_impl<'a>( @@ -931,8 +931,8 @@ impl fmt::Display for MetadataError<'_> { } impl CrateError { - crate fn report(self, sess: &Session, span: Span, missing_core: bool) -> ! { - let mut err = match self { + fn build_diag(self, sess: &Session, span: Span, missing_core: bool) -> DiagnosticBuilder<'_> { + 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,10 @@ impl CrateError { "plugin `{}` only found in rlib format, but must be available in dylib format", crate_name, ), - }; + } + } - err.emit(); - sess.abort_if_errors(); - unreachable!(); + crate fn report(self, sess: &Session, span: Span, missing_core: bool) { + self.build_diag(sess, span, missing_core).emit(); } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 02e540e2091f5..aaa946f75421b 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -685,11 +685,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ItemKind::ExternCrate(orig_name) => { self.build_reduced_graph_for_extern_crate( orig_name, - ident, item, local_def_id, - sp, - expansion, vis, parent, ); @@ -833,14 +830,16 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn build_reduced_graph_for_extern_crate( &mut self, orig_name: Option, - ident: Ident, item: &Item, local_def_id: LocalDefId, - sp: Span, - expansion: LocalExpnId, vis: ty::Visibility, parent: Module<'a>, ) { + let ident = item.ident; + let sp = item.span; + let parent_scope = self.parent_scope; + let expansion = parent_scope.expansion; + let module = if orig_name.is_none() && ident.name == kw::SelfLower { self.r .session @@ -856,10 +855,32 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } else if orig_name == Some(kw::SelfLower) { self.r.graph_root } else { - let crate_id = - self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id); - self.r.extern_crate_map.insert(local_def_id, crate_id); - self.r.expect_module(crate_id.as_def_id()) + match self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id) + { + Some(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 = diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index bf4cece8bde8d..d2c64b7e4418d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -600,8 +600,10 @@ impl<'a> Resolver<'a> { // Define a "dummy" resolution containing a Res::Err as a placeholder for a // failed resolution - fn import_dummy_binding(&mut self, import: &'a Import<'a>) { - if let ImportKind::Single { target, .. } = import.kind { + crate fn import_dummy_binding(&mut self, import: &'a Import<'a>) { + if let ImportKind::Single { target, .. } | ImportKind::ExternCrate { 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/src/test/ui/crate-loading/missing-std.rs b/src/test/ui/crate-loading/missing-std.rs index 1a34c21ba5413..400d9f6e0ba12 100644 --- a/src/test/ui/crate-loading/missing-std.rs +++ b/src/test/ui/crate-loading/missing-std.rs @@ -1,6 +1,7 @@ // compile-flags: --target x86_64-unknown-uefi // needs-llvm-components: x86 // rustc-env:CARGO=/usr/bin/cargo +#![feature(no_core)] #![no_core] extern crate core; //~^ ERROR can't find crate for `core` diff --git a/src/test/ui/crate-loading/missing-std.stderr b/src/test/ui/crate-loading/missing-std.stderr index 25808efdfa699..70bcae1e0edd0 100644 --- a/src/test/ui/crate-loading/missing-std.stderr +++ b/src/test/ui/crate-loading/missing-std.stderr @@ -1,5 +1,5 @@ error[E0463]: can't find crate for `core` - --> $DIR/missing-std.rs:5:1 + --> $DIR/missing-std.rs:6:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ can't find crate @@ -8,6 +8,8 @@ LL | extern crate core; = 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 +error: requires `sized` lang_item + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0463`. diff --git a/src/test/ui/extern-flag/empty-extern-arg.stderr b/src/test/ui/extern-flag/empty-extern-arg.stderr index 199c4fb616b53..b0628a4f6dd62 100644 --- a/src/test/ui/extern-flag/empty-extern-arg.stderr +++ b/src/test/ui/extern-flag/empty-extern-arg.stderr @@ -1,4 +1,8 @@ error: extern location for std does not exist: -error: aborting due to previous error +error: language item required, but not found: `eh_personality` + +error: `#[panic_handler]` function required, but not found + +error: aborting due to 3 previous errors diff --git a/src/test/ui/extern/extern-crate-multiple-missing.rs b/src/test/ui/extern/extern-crate-multiple-missing.rs new file mode 100644 index 0000000000000..fa7da83a6dfef --- /dev/null +++ b/src/test/ui/extern/extern-crate-multiple-missing.rs @@ -0,0 +1,8 @@ +// If multiple `extern crate` resolutions fail each of them should produce an error +extern crate bar; //~ ERROR can't find crate for `bar` +extern crate foo; //~ ERROR can't find crate for `foo` + +fn main() { + foo::something(); + bar::something(); +} diff --git a/src/test/ui/extern/extern-crate-multiple-missing.stderr b/src/test/ui/extern/extern-crate-multiple-missing.stderr new file mode 100644 index 0000000000000..893bb4fb26d0d --- /dev/null +++ b/src/test/ui/extern/extern-crate-multiple-missing.stderr @@ -0,0 +1,15 @@ +error[E0463]: can't find crate for `bar` + --> $DIR/extern-crate-multiple-missing.rs:2:1 + | +LL | extern crate bar; + | ^^^^^^^^^^^^^^^^^ can't find crate + +error[E0463]: can't find crate for `foo` + --> $DIR/extern-crate-multiple-missing.rs:3:1 + | +LL | extern crate foo; + | ^^^^^^^^^^^^^^^^^ can't find crate + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0463`. diff --git a/src/test/ui/issues/issue-37131.stderr b/src/test/ui/issues/issue-37131.stderr index b45574f0c49af..9ecae3e7a2b24 100644 --- a/src/test/ui/issues/issue-37131.stderr +++ b/src/test/ui/issues/issue-37131.stderr @@ -4,6 +4,8 @@ error[E0463]: can't find crate for `std` = help: consider downloading the target with `rustup target add thumbv6m-none-eabi` = help: consider building the standard library from source with `cargo build -Zbuild-std` -error: aborting due to previous error +error: requires `sized` lang_item + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0463`. diff --git a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs index ddb070ddf9fae..4e56cca33d6a9 100644 --- a/src/test/ui/issues/issue-49851/compiler-builtins-error.rs +++ b/src/test/ui/issues/issue-49851/compiler-builtins-error.rs @@ -1,4 +1,5 @@ -//~ ERROR 1:1: 1:1: can't find crate for `core` [E0463] +//~ ERROR can't find crate for `core` +//~^ ERROR can't find crate for `compiler_builtins` // compile-flags: --target thumbv7em-none-eabihf // needs-llvm-components: arm @@ -7,3 +8,6 @@ #![no_std] extern crate cortex_m; +//~^ ERROR can't find crate for `cortex_m` + +fn main() {} diff --git a/src/test/ui/issues/issue-49851/compiler-builtins-error.stderr b/src/test/ui/issues/issue-49851/compiler-builtins-error.stderr index d963c07ea9175..fcfa2bf119cff 100644 --- a/src/test/ui/issues/issue-49851/compiler-builtins-error.stderr +++ b/src/test/ui/issues/issue-49851/compiler-builtins-error.stderr @@ -4,6 +4,16 @@ error[E0463]: can't find crate for `core` = help: consider downloading the target with `rustup target add thumbv7em-none-eabihf` = help: consider building the standard library from source with `cargo build -Zbuild-std` -error: aborting due to previous error +error[E0463]: can't find crate for `compiler_builtins` + +error[E0463]: can't find crate for `cortex_m` + --> $DIR/compiler-builtins-error.rs:10:1 + | +LL | extern crate cortex_m; + | ^^^^^^^^^^^^^^^^^^^^^^ can't find crate + +error: requires `sized` lang_item + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0463`. From 2c9d9b4b758a9d6bdae212852c59d71a3edcc5de Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 26 Nov 2021 21:39:44 +0000 Subject: [PATCH 3/3] Improve suggestion for extern crate self error message --- compiler/rustc_metadata/src/creader.rs | 30 ++++-------- compiler/rustc_metadata/src/locator.rs | 12 ++--- .../rustc_resolve/src/build_reduced_graph.rs | 48 +++++++------------ compiler/rustc_resolve/src/imports.rs | 6 +-- compiler/rustc_resolve/src/lib.rs | 4 +- src/test/ui/crate-loading/invalid-rlib.rs | 2 + src/test/ui/crate-loading/invalid-rlib.stderr | 10 +++- .../extern/extern-crate-multiple-missing.rs | 2 + .../extern-crate-self-fail.stderr | 7 ++- .../ui/rust-2018/uniform-paths/deadlock.rs | 3 +- .../rust-2018/uniform-paths/deadlock.stderr | 21 ++++++-- 11 files changed, 75 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index f3e7d84c1c530..2626a2e189c1d 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 { 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 { + 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 { diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 03181012bccb7..e2fd8056f1a7c 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 aaa946f75421b..c936e08d536a4 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 d2c64b7e4418d..bf4cece8bde8d 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 d17e8875a1ec0..1c084086ceb02 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -3288,7 +3288,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 77c29090a3ee0..aea861e3261b5 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 b2c79f742fb30..3c0d23bf7b4cc 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/extern-crate-multiple-missing.rs b/src/test/ui/extern/extern-crate-multiple-missing.rs index fa7da83a6dfef..a6560ca78624d 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 8f369f1b03831..127765727b401 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 83ed70a0459a8..2427bde6d18bc 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 9336e90afb71d..8b9863948bd6c 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`.