Skip to content

Commit 2ca9333

Browse files
committed
Improve suggestion for extern crate self error message
1 parent 62f4ce9 commit 2ca9333

File tree

12 files changed

+77
-70
lines changed

12 files changed

+77
-70
lines changed

compiler/rustc_metadata/src/creader.rs

+10-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use rustc_ast::{self as ast, *};
99
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1010
use rustc_data_structures::svh::Svh;
1111
use rustc_data_structures::sync::Lrc;
12-
use rustc_errors::FatalError;
1312
use rustc_expand::base::SyntaxExtension;
1413
use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE};
1514
use rustc_hir::definitions::Definitions;
@@ -508,31 +507,22 @@ impl<'a> CrateLoader<'a> {
508507
}))
509508
}
510509

511-
fn resolve_crate_or_abort<'b>(
512-
&'b mut self,
513-
name: Symbol,
514-
span: Span,
515-
dep_kind: CrateDepKind,
516-
) -> CrateNum {
517-
self.resolve_crate(name, span, dep_kind).unwrap_or_else(|| FatalError.raise())
518-
}
519-
520510
fn resolve_crate<'b>(
521511
&'b mut self,
522512
name: Symbol,
523513
span: Span,
524514
dep_kind: CrateDepKind,
525515
) -> Option<CrateNum> {
526516
self.used_extern_options.insert(name);
527-
self.maybe_resolve_crate(name, dep_kind, None).map_or_else(
528-
|err| {
517+
match self.maybe_resolve_crate(name, dep_kind, None) {
518+
Ok(cnum) => Some(cnum),
519+
Err(err) => {
529520
let missing_core =
530521
self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
531522
err.report(&self.sess, span, missing_core);
532523
None
533-
},
534-
|cnum| Some(cnum),
535-
)
524+
}
525+
}
536526
}
537527

538528
fn maybe_resolve_crate<'b>(
@@ -765,7 +755,7 @@ impl<'a> CrateLoader<'a> {
765755
};
766756
info!("panic runtime not found -- loading {}", name);
767757

768-
let cnum = self.resolve_crate_or_abort(name, DUMMY_SP, CrateDepKind::Implicit);
758+
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
769759
let data = self.cstore.get_crate_data(cnum);
770760

771761
// Sanity check the loaded crate to ensure it is indeed a panic runtime
@@ -805,7 +795,7 @@ impl<'a> CrateLoader<'a> {
805795
);
806796
}
807797

808-
let cnum = self.resolve_crate_or_abort(name, DUMMY_SP, CrateDepKind::Implicit);
798+
let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { return; };
809799
let data = self.cstore.get_crate_data(cnum);
810800

811801
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
@@ -1043,8 +1033,8 @@ impl<'a> CrateLoader<'a> {
10431033
}
10441034
}
10451035

1046-
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum {
1047-
let cnum = self.resolve_crate_or_abort(name, span, CrateDepKind::Explicit);
1036+
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
1037+
let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?;
10481038

10491039
self.update_extern_crate(
10501040
cnum,
@@ -1057,7 +1047,7 @@ impl<'a> CrateLoader<'a> {
10571047
},
10581048
);
10591049

1060-
cnum
1050+
Some(cnum)
10611051
}
10621052

10631053
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {

compiler/rustc_metadata/src/locator.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ use rustc_data_structures::memmap::Mmap;
220220
use rustc_data_structures::owning_ref::OwningRef;
221221
use rustc_data_structures::svh::Svh;
222222
use rustc_data_structures::sync::MetadataRef;
223-
use rustc_errors::{struct_span_err, DiagnosticBuilder, FatalError};
223+
use rustc_errors::{struct_span_err, FatalError};
224224
use rustc_session::config::{self, CrateType};
225225
use rustc_session::cstore::{CrateSource, MetadataLoader};
226226
use rustc_session::filesearch::{FileDoesntMatch, FileMatches, FileSearch};
@@ -931,8 +931,8 @@ impl fmt::Display for MetadataError<'_> {
931931
}
932932

933933
impl CrateError {
934-
fn build_diag(self, sess: &Session, span: Span, missing_core: bool) -> DiagnosticBuilder<'_> {
935-
match self {
934+
crate fn report(self, sess: &Session, span: Span, missing_core: bool) {
935+
let mut diag = match self {
936936
CrateError::NonAsciiName(crate_name) => sess.struct_span_err(
937937
span,
938938
&format!("cannot load a crate with a non-ascii name `{}`", crate_name),
@@ -1208,10 +1208,8 @@ impl CrateError {
12081208
"plugin `{}` only found in rlib format, but must be available in dylib format",
12091209
crate_name,
12101210
),
1211-
}
1212-
}
1211+
};
12131212

1214-
crate fn report(self, sess: &Session, span: Span, missing_core: bool) {
1215-
self.build_diag(sess, span, missing_core).emit();
1213+
diag.emit();
12161214
}
12171215
}

compiler/rustc_resolve/src/build_reduced_graph.rs

+16-32
Original file line numberDiff line numberDiff line change
@@ -840,57 +840,41 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
840840
let parent_scope = self.parent_scope;
841841
let expansion = parent_scope.expansion;
842842

843-
let module = if orig_name.is_none() && ident.name == kw::SelfLower {
843+
let (used, module, binding) = if orig_name.is_none() && ident.name == kw::SelfLower {
844844
self.r
845845
.session
846846
.struct_span_err(item.span, "`extern crate self;` requires renaming")
847847
.span_suggestion(
848848
item.span,
849-
"try",
849+
"rename the `self` crate to be able to import it",
850850
"extern crate self as name;".into(),
851851
Applicability::HasPlaceholders,
852852
)
853853
.emit();
854854
return;
855855
} else if orig_name == Some(kw::SelfLower) {
856-
self.r.graph_root
856+
Some(self.r.graph_root)
857857
} else {
858-
match self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id)
859-
{
860-
Some(crate_id) => {
858+
self.r.crate_loader.process_extern_crate(item, &self.r.definitions, local_def_id).map(
859+
|crate_id| {
861860
self.r.extern_crate_map.insert(local_def_id, crate_id);
862861
self.r.expect_module(crate_id.as_def_id())
863-
}
864-
_ => {
865-
let dummy_import = self.r.arenas.alloc_import(Import {
866-
kind: ImportKind::ExternCrate { source: orig_name, target: ident },
867-
root_id: item.id,
868-
id: item.id,
869-
parent_scope: self.parent_scope,
870-
imported_module: Cell::new(None),
871-
has_attributes: !item.attrs.is_empty(),
872-
use_span_with_attributes: item.span_with_attributes(),
873-
use_span: item.span,
874-
root_span: item.span,
875-
span: item.span,
876-
module_path: Vec::new(),
877-
vis: Cell::new(vis),
878-
used: Cell::new(true),
879-
});
880-
self.r.import_dummy_binding(dummy_import);
881-
return;
882-
}
883-
}
884-
};
885-
let used = self.process_macro_use_imports(item, module);
886-
let binding =
887-
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
862+
},
863+
)
864+
}
865+
.map(|module| {
866+
let used = self.process_macro_use_imports(item, module);
867+
let binding =
868+
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
869+
(used, Some(ModuleOrUniformRoot::Module(module)), binding)
870+
})
871+
.unwrap_or((true, None, self.r.dummy_binding));
888872
let import = self.r.arenas.alloc_import(Import {
889873
kind: ImportKind::ExternCrate { source: orig_name, target: ident },
890874
root_id: item.id,
891875
id: item.id,
892876
parent_scope: self.parent_scope,
893-
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
877+
imported_module: Cell::new(module),
894878
has_attributes: !item.attrs.is_empty(),
895879
use_span_with_attributes: item.span_with_attributes(),
896880
use_span: item.span,

compiler/rustc_resolve/src/imports.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -600,10 +600,8 @@ impl<'a> Resolver<'a> {
600600

601601
// Define a "dummy" resolution containing a Res::Err as a placeholder for a
602602
// failed resolution
603-
crate fn import_dummy_binding(&mut self, import: &'a Import<'a>) {
604-
if let ImportKind::Single { target, .. } | ImportKind::ExternCrate { target, .. } =
605-
import.kind
606-
{
603+
fn import_dummy_binding(&mut self, import: &'a Import<'a>) {
604+
if let ImportKind::Single { target, .. } = import.kind {
607605
let dummy_binding = self.dummy_binding;
608606
let dummy_binding = self.import(dummy_binding, import);
609607
self.per_ns(|this, ns| {

compiler/rustc_resolve/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -3285,7 +3285,9 @@ impl<'a> Resolver<'a> {
32853285
Some(binding)
32863286
} else {
32873287
let crate_id = if !speculative {
3288-
self.crate_loader.process_path_extern(ident.name, ident.span)
3288+
let Some(crate_id) =
3289+
self.crate_loader.process_path_extern(ident.name, ident.span) else { return Some(self.dummy_binding); };
3290+
crate_id
32893291
} else {
32903292
self.crate_loader.maybe_process_path_extern(ident.name)?
32913293
};

src/test/ui/crate-loading/invalid-rlib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@
66
#![no_std]
77
use ::foo; //~ ERROR invalid metadata files for crate `foo`
88
//~| NOTE failed to mmap file
9+
//~^^ ERROR invalid metadata files for crate `foo`
10+
//~| NOTE failed to mmap file

src/test/ui/crate-loading/invalid-rlib.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ LL | use ::foo;
66
|
77
= note: failed to mmap file 'auxiliary/libfoo.rlib'
88

9-
error: aborting due to previous error
9+
error[E0786]: found invalid metadata files for crate `foo`
10+
--> $DIR/invalid-rlib.rs:7:7
11+
|
12+
LL | use ::foo;
13+
| ^^^
14+
|
15+
= note: failed to mmap file 'auxiliary/libfoo.rlib'
16+
17+
error: aborting due to 2 previous errors
1018

1119
For more information about this error, try `rustc --explain E0786`.
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// compile-flags: --extern std=
22
// error-pattern: extern location for std does not exist
3+
// needs-unwind since it affects the error output
4+
// ignore-emscripten compiled with panic=abort, personality not required
35

46
fn main() {}

src/test/ui/extern/extern-crate-multiple-missing.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ extern crate bar; //~ ERROR can't find crate for `bar`
33
extern crate foo; //~ ERROR can't find crate for `foo`
44

55
fn main() {
6+
// If the crate name introduced by `extern crate` failed to resolve then subsequent
7+
// derived paths do not emit additional errors
68
foo::something();
79
bar::something();
810
}

src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error: `extern crate self;` requires renaming
22
--> $DIR/extern-crate-self-fail.rs:1:1
33
|
44
LL | extern crate self;
5-
| ^^^^^^^^^^^^^^^^^^ help: try: `extern crate self as name;`
5+
| ^^^^^^^^^^^^^^^^^^
6+
|
7+
help: rename the `self` crate to be able to import it
8+
|
9+
LL | extern crate self as name;
10+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
611

712
error: `#[macro_use]` is not supported on `extern crate self`
813
--> $DIR/extern-crate-self-fail.rs:3:1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// edition:2018
22
// compile-flags:--extern foo --extern bar
33

4+
use bar::foo; //~ ERROR can't find crate for `bar`
45
use foo::bar; //~ ERROR can't find crate for `foo`
5-
use bar::foo;
6+
//~^^ ERROR unresolved imports `bar::foo`, `foo::bar`
67

78
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
1-
error[E0463]: can't find crate for `foo`
1+
error[E0463]: can't find crate for `bar`
22
--> $DIR/deadlock.rs:4:5
33
|
4+
LL | use bar::foo;
5+
| ^^^ can't find crate
6+
7+
error[E0463]: can't find crate for `foo`
8+
--> $DIR/deadlock.rs:5:5
9+
|
410
LL | use foo::bar;
511
| ^^^ can't find crate
612

7-
error: aborting due to previous error
13+
error[E0432]: unresolved imports `bar::foo`, `foo::bar`
14+
--> $DIR/deadlock.rs:4:5
15+
|
16+
LL | use bar::foo;
17+
| ^^^^^^^^
18+
LL | use foo::bar;
19+
| ^^^^^^^^
20+
21+
error: aborting due to 3 previous errors
822

9-
For more information about this error, try `rustc --explain E0463`.
23+
Some errors have detailed explanations: E0432, E0463.
24+
For more information about an error, try `rustc --explain E0432`.

0 commit comments

Comments
 (0)