Skip to content

Commit

Permalink
Improve suggestion for extern crate self error message
Browse files Browse the repository at this point in the history
  • Loading branch information
mjptree committed Nov 29, 2021
1 parent 29b4b6c commit 2c9d9b4
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 70 deletions.
30 changes: 10 additions & 20 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -508,31 +507,22 @@ 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,
span: Span,
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>(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -1057,7 +1047,7 @@ impl<'a> CrateLoader<'a> {
},
);

cnum
Some(cnum)
}

pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_metadata/src/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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();
}
}
48 changes: 16 additions & 32 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?
};
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/crate-loading/invalid-rlib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 9 additions & 1 deletion src/test/ui/crate-loading/invalid-rlib.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
2 changes: 2 additions & 0 deletions src/test/ui/extern/extern-crate-multiple-missing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/rust-2018/uniform-paths/deadlock.rs
Original file line number Diff line number Diff line change
@@ -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() {}
21 changes: 18 additions & 3 deletions src/test/ui/rust-2018/uniform-paths/deadlock.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 2c9d9b4

Please sign in to comment.