diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index eb0a693226c48..2626a2e189c1d 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -512,13 +512,17 @@ impl<'a> CrateLoader<'a> { name: Symbol, span: Span, dep_kind: CrateDepKind, - ) -> CrateNum { + ) -> 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) - }) + 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 + } + } } fn maybe_resolve_crate<'b>( @@ -751,7 +755,7 @@ impl<'a> CrateLoader<'a> { }; info!("panic runtime not found -- loading {}", name); - let cnum = self.resolve_crate(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 @@ -791,7 +795,7 @@ impl<'a> CrateLoader<'a> { ); } - let cnum = self.resolve_crate(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 @@ -991,7 +995,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 +1015,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 +1027,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); + 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, @@ -1043,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 7cba16e0a9ae3..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; +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}; @@ -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 { + 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), @@ -1210,8 +1210,6 @@ impl CrateError { ), }; - err.emit(); - sess.abort_if_errors(); - unreachable!(); + diag.emit(); } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 3cf9d324a38da..c936e08d536a4 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -683,75 +683,13 @@ 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, + item, + local_def_id, + vis, + parent, + ); } ItemKind::Mod(..) => { @@ -889,6 +827,87 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } } + fn build_reduced_graph_for_extern_crate( + &mut self, + orig_name: Option, + item: &Item, + local_def_id: LocalDefId, + 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 (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, + "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) { + Some(self.r.graph_root) + } else { + 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()) + }, + ) + } + .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(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); 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/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..a6560ca78624d --- /dev/null +++ b/src/test/ui/extern/extern-crate-multiple-missing.rs @@ -0,0 +1,10 @@ +// 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() { + // 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/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/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/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`. 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`.