Rollup merge of #82881 - Manishearth:crate-root, r=estebank

diagnostics: Be clear about "crate root" and `::foo` paths in resolve diagnostics

Various changes to make sure the diagnostics are clear about the differences in `::foo` paths across editions:

 - `::foo` will say "crate root" in 2015 and "list of imported crates" in 2018
 - `crate::` will never reference imported crates in 2018

Fixes https://github.com/rust-lang/rust/issues/82876
This commit is contained in:
Mara Bos 2021-03-08 20:09:06 +01:00 committed by GitHub
commit 3908eec60f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 129 additions and 13 deletions

View File

@ -16,6 +16,7 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::PrimTy;
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition;
use rustc_span::hygiene::MacroKind;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@ -133,7 +134,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _));
// Make the base error.
let expected = source.descr_expected();
let mut expected = source.descr_expected();
let path_str = Segment::names_to_string(path);
let item_str = path.last().unwrap().ident;
let (base_msg, fallback_label, base_span, could_be_expr) = if let Some(res) = res {
@ -166,6 +167,15 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
let (mod_prefix, mod_str) = if path.len() == 1 {
(String::new(), "this scope".to_string())
} else if path.len() == 2 && path[0].ident.name == kw::PathRoot {
if self.r.session.edition() > Edition::Edition2015 {
// In edition 2018 onwards, the `::foo` syntax may only pull from the extern prelude
// which overrides all other expectations of item type
expected = "crate";
(String::new(), "the list of imported crates".to_string())
} else {
(String::new(), "the crate root".to_string())
}
} else if path.len() == 2 && path[0].ident.name == kw::Crate {
(String::new(), "the crate root".to_string())
} else {
let mod_path = &path[..path.len() - 1];

View File

@ -2433,8 +2433,10 @@ impl<'a> Resolver<'a> {
Applicability::MaybeIncorrect,
)),
)
} else {
} else if self.session.edition() == Edition::Edition2015 {
(format!("maybe a missing crate `{}`?", ident), None)
} else {
(format!("could not find `{}` in the crate root", ident), None)
}
} else if i == 0 {
if ident
@ -2450,10 +2452,16 @@ impl<'a> Resolver<'a> {
}
} else {
let parent = path[i - 1].ident.name;
let parent = if parent == kw::PathRoot {
"crate root".to_owned()
} else {
format!("`{}`", parent)
let parent = match parent {
// ::foo is mounted at the crate root for 2015, and is the extern
// prelude for 2018+
kw::PathRoot if self.session.edition() > Edition::Edition2015 => {
"the list of imported crates".to_owned()
}
kw::PathRoot | kw::Crate => "the crate root".to_owned(),
_ => {
format!("`{}`", parent)
}
};
let mut msg = format!("could not find `{}` in {}", ident, parent);

View File

@ -0,0 +1,21 @@
// edition:2015
mod inner {
fn global_inner(_: ::nonexistant::Foo) {
//~^ ERROR failed to resolve: maybe a missing crate `nonexistant`?
}
fn crate_inner(_: crate::nonexistant::Foo) {
//~^ ERROR failed to resolve: maybe a missing crate `nonexistant`?
}
fn bare_global(_: ::nonexistant) {
//~^ ERROR cannot find type `nonexistant` in the crate root
}
fn bare_crate(_: crate::nonexistant) {
//~^ ERROR cannot find type `nonexistant` in the crate root
}
}
fn main() {
}

View File

@ -0,0 +1,28 @@
error[E0433]: failed to resolve: maybe a missing crate `nonexistant`?
--> $DIR/editions-crate-root-2015.rs:4:26
|
LL | fn global_inner(_: ::nonexistant::Foo) {
| ^^^^^^^^^^^ maybe a missing crate `nonexistant`?
error[E0433]: failed to resolve: maybe a missing crate `nonexistant`?
--> $DIR/editions-crate-root-2015.rs:7:30
|
LL | fn crate_inner(_: crate::nonexistant::Foo) {
| ^^^^^^^^^^^ maybe a missing crate `nonexistant`?
error[E0412]: cannot find type `nonexistant` in the crate root
--> $DIR/editions-crate-root-2015.rs:11:25
|
LL | fn bare_global(_: ::nonexistant) {
| ^^^^^^^^^^^ not found in the crate root
error[E0412]: cannot find type `nonexistant` in the crate root
--> $DIR/editions-crate-root-2015.rs:14:29
|
LL | fn bare_crate(_: crate::nonexistant) {
| ^^^^^^^^^^^ not found in the crate root
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0412, E0433.
For more information about an error, try `rustc --explain E0412`.

View File

@ -0,0 +1,21 @@
// edition:2018
mod inner {
fn global_inner(_: ::nonexistant::Foo) {
//~^ ERROR failed to resolve: could not find `nonexistant` in the list of imported crates
}
fn crate_inner(_: crate::nonexistant::Foo) {
//~^ ERROR failed to resolve: could not find `nonexistant` in the crate root
}
fn bare_global(_: ::nonexistant) {
//~^ ERROR cannot find crate `nonexistant` in the list of imported crates
}
fn bare_crate(_: crate::nonexistant) {
//~^ ERROR cannot find type `nonexistant` in the crate root
}
}
fn main() {
}

View File

@ -0,0 +1,28 @@
error[E0433]: failed to resolve: could not find `nonexistant` in the list of imported crates
--> $DIR/editions-crate-root-2018.rs:4:26
|
LL | fn global_inner(_: ::nonexistant::Foo) {
| ^^^^^^^^^^^ could not find `nonexistant` in the list of imported crates
error[E0433]: failed to resolve: could not find `nonexistant` in the crate root
--> $DIR/editions-crate-root-2018.rs:7:30
|
LL | fn crate_inner(_: crate::nonexistant::Foo) {
| ^^^^^^^^^^^ could not find `nonexistant` in the crate root
error[E0412]: cannot find crate `nonexistant` in the list of imported crates
--> $DIR/editions-crate-root-2018.rs:11:25
|
LL | fn bare_global(_: ::nonexistant) {
| ^^^^^^^^^^^ not found in the list of imported crates
error[E0412]: cannot find type `nonexistant` in the crate root
--> $DIR/editions-crate-root-2018.rs:14:29
|
LL | fn bare_crate(_: crate::nonexistant) {
| ^^^^^^^^^^^ not found in the crate root
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0412, E0433.
For more information about an error, try `rustc --explain E0412`.

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `E`
--> $DIR/edition-imports-virtual-2015-gated.rs:8:5
|
LL | gen_gated!();
| ^^^^^^^^^^^^^ could not find `E` in crate root
| ^^^^^^^^^^^^^ could not find `E` in the list of imported crates
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -1,5 +1,5 @@
// Regression test for issue #63882.
type A = crate::r#break; //~ ERROR cannot find type `r#break` in module `crate`
type A = crate::r#break; //~ ERROR cannot find type `r#break` in the crate root
fn main() {}

View File

@ -1,8 +1,8 @@
error[E0412]: cannot find type `r#break` in module `crate`
error[E0412]: cannot find type `r#break` in the crate root
--> $DIR/raw-ident-in-path.rs:3:17
|
LL | type A = crate::r#break;
| ^^^^^^^ not found in `crate`
| ^^^^^^^ not found in the crate root
error: aborting due to previous error

View File

@ -2,5 +2,5 @@
fn main() {
let s = ::xcrate::S;
//~^ ERROR failed to resolve: could not find `xcrate` in crate root
//~^ ERROR failed to resolve: could not find `xcrate` in the list of imported crates
}

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve: could not find `xcrate` in crate root
error[E0433]: failed to resolve: could not find `xcrate` in the list of imported crates
--> $DIR/non-existent-2.rs:4:15
|
LL | let s = ::xcrate::S;
| ^^^^^^ could not find `xcrate` in crate root
| ^^^^^^ could not find `xcrate` in the list of imported crates
error: aborting due to previous error