use structured suggestions for E0432

This commit is contained in:
Andy Russell 2019-01-16 15:30:41 -05:00
parent e1b8898cfb
commit 4bbe8839dd
No known key found for this signature in database
GPG Key ID: BE2221033EDBC374
19 changed files with 310 additions and 152 deletions

View File

@ -137,6 +137,9 @@ impl Ord for BindingError {
}
}
/// A span, message, replacement text, and applicability.
type Suggestion = (Span, String, String, Applicability);
enum ResolutionError<'a> {
/// Error E0401: can't use type or const parameters from outer function.
GenericParamsFromOuterFunction(Def),
@ -166,7 +169,7 @@ enum ResolutionError<'a> {
/// Error E0431: `self` import can only appear in an import list with a non-empty prefix.
SelfImportOnlyInImportListWithNonEmptyPrefix,
/// Error E0433: failed to resolve.
FailedToResolve(&'a str),
FailedToResolve { label: String, suggestion: Option<Suggestion> },
/// Error E0434: can't capture dynamic environment in a fn item.
CannotCaptureDynamicEnvironmentInFnItem,
/// Error E0435: attempt to use a non-constant value in a constant.
@ -380,10 +383,15 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
err.span_label(span, "can only appear in an import list with a non-empty prefix");
err
}
ResolutionError::FailedToResolve(msg) => {
ResolutionError::FailedToResolve { label, suggestion } => {
let mut err = struct_span_err!(resolver.session, span, E0433,
"failed to resolve: {}", msg);
err.span_label(span, msg);
"failed to resolve: {}", &label);
err.span_label(span, label);
if let Some((span, msg, suggestion, applicability)) = suggestion {
err.span_suggestion(span, &msg, suggestion, applicability);
}
err
}
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
@ -1050,7 +1058,12 @@ enum PathResult<'a> {
Module(ModuleOrUniformRoot<'a>),
NonModule(PathResolution),
Indeterminate,
Failed(Span, String, bool /* is the error from the last segment? */),
Failed {
span: Span,
label: String,
suggestion: Option<Suggestion>,
is_error_from_last_segment: bool,
},
}
enum ModuleKind {
@ -1775,13 +1788,18 @@ impl<'a> Resolver<'a> {
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
path_res.base_def(),
PathResult::NonModule(..) => {
let msg = "type-relative paths are not supported in this context";
error_callback(self, span, ResolutionError::FailedToResolve(msg));
error_callback(self, span, ResolutionError::FailedToResolve {
label: String::from("type-relative paths are not supported in this context"),
suggestion: None,
});
Def::Err
}
PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
PathResult::Failed(span, msg, _) => {
error_callback(self, span, ResolutionError::FailedToResolve(&msg));
PathResult::Failed { span, label, suggestion, .. } => {
error_callback(self, span, ResolutionError::FailedToResolve {
label,
suggestion,
});
Def::Err
}
};
@ -3429,7 +3447,7 @@ impl<'a> Resolver<'a> {
// Such behavior is required for backward compatibility.
// The same fallback is used when `a` resolves to nothing.
PathResult::Module(ModuleOrUniformRoot::Module(_)) |
PathResult::Failed(..)
PathResult::Failed { .. }
if (ns == TypeNS || path.len() > 1) &&
self.primitive_type_table.primitive_types
.contains_key(&path[0].ident.name) => {
@ -3438,11 +3456,11 @@ impl<'a> Resolver<'a> {
}
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
PathResolution::new(module.def().unwrap()),
PathResult::Failed(span, msg, false) => {
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
resolve_error(self, span, ResolutionError::FailedToResolve { label, suggestion });
err_path_resolution()
}
PathResult::Module(..) | PathResult::Failed(..) => return None,
PathResult::Module(..) | PathResult::Failed { .. } => return None,
PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"),
};
@ -3550,7 +3568,12 @@ impl<'a> Resolver<'a> {
}
}
let msg = "there are too many initial `super`s.".to_string();
return PathResult::Failed(ident.span, msg, false);
return PathResult::Failed {
span: ident.span,
label: msg,
suggestion: None,
is_error_from_last_segment: false,
};
}
if i == 0 {
if name == keywords::SelfLower.name() {
@ -3587,12 +3610,17 @@ impl<'a> Resolver<'a> {
} else {
format!("`{}`", name)
};
let msg = if i == 1 && path[0].ident.name == keywords::PathRoot.name() {
let label = if i == 1 && path[0].ident.name == keywords::PathRoot.name() {
format!("global paths cannot start with {}", name_str)
} else {
format!("{} in paths can only be used in start position", name_str)
};
return PathResult::Failed(ident.span, msg, false);
return PathResult::Failed {
span: ident.span,
label,
suggestion: None,
is_error_from_last_segment: false,
};
}
let binding = if let Some(module) = module {
@ -3653,9 +3681,12 @@ impl<'a> Resolver<'a> {
def, path.len() - i - 1
));
} else {
return PathResult::Failed(ident.span,
format!("not a module `{}`", ident),
is_last);
return PathResult::Failed {
span: ident.span,
label: format!("not a module `{}`", ident),
suggestion: None,
is_error_from_last_segment: is_last,
};
}
}
Err(Undetermined) => return PathResult::Indeterminate,
@ -3671,7 +3702,7 @@ impl<'a> Resolver<'a> {
Some(ModuleOrUniformRoot::Module(module)) => module.def(),
_ => None,
};
let msg = if module_def == self.graph_root.def() {
let (label, suggestion) = if module_def == self.graph_root.def() {
let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
let mut candidates =
self.lookup_import_candidates(ident, TypeNS, is_mod);
@ -3679,19 +3710,32 @@ impl<'a> Resolver<'a> {
(c.path.segments.len(), c.path.to_string())
});
if let Some(candidate) = candidates.get(0) {
format!("did you mean `{}`?", candidate.path)
(
String::from("unresolved import"),
Some((
ident.span,
String::from("a similar path exists"),
candidate.path.to_string(),
Applicability::MaybeIncorrect,
)),
)
} else if !ident.is_reserved() {
format!("maybe a missing `extern crate {};`?", ident)
(format!("maybe a missing `extern crate {};`?", ident), None)
} else {
// the parser will already have complained about the keyword being used
return PathResult::NonModule(err_path_resolution());
}
} else if i == 0 {
format!("use of undeclared type or module `{}`", ident)
(format!("use of undeclared type or module `{}`", ident), None)
} else {
format!("could not find `{}` in `{}`", ident, path[i - 1].ident)
(format!("could not find `{}` in `{}`", ident, path[i - 1].ident), None)
};
return PathResult::Failed {
span: ident.span,
label,
suggestion,
is_error_from_last_segment: is_last,
};
return PathResult::Failed(ident.span, msg, is_last);
}
}
}

View File

@ -426,9 +426,9 @@ impl<'a> Resolver<'a> {
Ok(path_res.base_def())
}
PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
PathResult::NonModule(..) | PathResult::Indeterminate | PathResult::Failed(..) => {
Err(Determinacy::Determined)
}
PathResult::NonModule(..)
| PathResult::Indeterminate
| PathResult::Failed { .. } => Err(Determinacy::Determined),
PathResult::Module(..) => unreachable!(),
};
@ -990,14 +990,17 @@ impl<'a> Resolver<'a> {
let def = path_res.base_def();
check_consistency(self, &path, path_span, kind, initial_def, def);
}
path_res @ PathResult::NonModule(..) | path_res @ PathResult::Failed(..) => {
let (span, msg) = if let PathResult::Failed(span, msg, ..) = path_res {
(span, msg)
path_res @ PathResult::NonModule(..) | path_res @ PathResult::Failed { .. } => {
let (span, label) = if let PathResult::Failed { span, label, .. } = path_res {
(span, label)
} else {
(path_span, format!("partially resolved path in {} {}",
kind.article(), kind.descr()))
};
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
resolve_error(self, span, ResolutionError::FailedToResolve {
label,
suggestion: None
});
}
PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
}

View File

@ -6,9 +6,11 @@ use crate::Namespace::{self, TypeNS, MacroNS};
use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
use crate::{Resolver, Segment};
use crate::{names_to_string, module_to_string};
use crate::{resolve_error, ResolutionError};
use crate::{resolve_error, ResolutionError, Suggestion};
use crate::macros::ParentScope;
use errors::Applicability;
use rustc_data_structures::ptr_key::PtrKey;
use rustc::ty;
use rustc::lint::builtin::BuiltinLintDiagnostics;
@ -27,7 +29,7 @@ use syntax::util::lev_distance::find_best_match_for_name;
use syntax::{struct_span_err, unwrap_or};
use syntax_pos::{MultiSpan, Span};
use log::debug;
use log::*;
use std::cell::{Cell, RefCell};
use std::{mem, ptr};
@ -623,6 +625,16 @@ impl<'a> Resolver<'a> {
}
}
/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
/// import errors within the same use tree into a single diagnostic.
#[derive(Debug, Clone)]
struct UnresolvedImportError {
span: Span,
label: Option<String>,
note: Option<String>,
suggestion: Option<Suggestion>,
}
pub struct ImportResolver<'a, 'b: 'a> {
pub resolver: &'a mut Resolver<'b>,
}
@ -675,14 +687,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
self.finalize_resolutions_in(module);
}
let mut errors = false;
let mut has_errors = false;
let mut seen_spans = FxHashSet::default();
let mut error_vec = Vec::new();
let mut errors = vec![];
let mut prev_root_id: NodeId = NodeId::from_u32(0);
for i in 0 .. self.determined_imports.len() {
let import = self.determined_imports[i];
if let Some((span, err, note)) = self.finalize_import(import) {
errors = true;
if let Some(err) = self.finalize_import(import) {
has_errors = true;
if let SingleImport { source, ref source_bindings, .. } = import.subclass {
if source.name == "self" {
@ -696,37 +708,36 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
// If the error is a single failed import then create a "fake" import
// resolution for it so that later resolve stages won't complain.
self.import_dummy_binding(import);
if prev_root_id.as_u32() != 0 &&
prev_root_id.as_u32() != import.root_id.as_u32() &&
!error_vec.is_empty(){
// in case of new import line, throw diagnostic message
// for previous line.
let mut empty_vec = vec![];
mem::swap(&mut empty_vec, &mut error_vec);
self.throw_unresolved_import_error(empty_vec, None);
if prev_root_id.as_u32() != 0
&& prev_root_id.as_u32() != import.root_id.as_u32()
&& !errors.is_empty() {
// In the case of a new import line, throw a diagnostic message
// for the previous line.
self.throw_unresolved_import_error(errors, None);
errors = vec![];
}
if !seen_spans.contains(&span) {
if !seen_spans.contains(&err.span) {
let path = import_path_to_string(
&import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
&import.subclass,
span,
err.span,
);
error_vec.push((span, path, err, note));
seen_spans.insert(span);
seen_spans.insert(err.span);
errors.push((path, err));
prev_root_id = import.root_id;
}
}
}
if !error_vec.is_empty() {
self.throw_unresolved_import_error(error_vec.clone(), None);
if !errors.is_empty() {
self.throw_unresolved_import_error(errors.clone(), None);
}
// Report unresolved imports only if no hard error was already reported
// to avoid generating multiple errors on the same import.
if !errors {
if !has_errors {
for import in &self.indeterminate_imports {
self.throw_unresolved_import_error(error_vec, Some(MultiSpan::from(import.span)));
self.throw_unresolved_import_error(errors, Some(MultiSpan::from(import.span)));
break;
}
}
@ -734,44 +745,58 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
fn throw_unresolved_import_error(
&self,
error_vec: Vec<(Span, String, String, Option<String>)>,
errors: Vec<(String, UnresolvedImportError)>,
span: Option<MultiSpan>,
) {
let max_span_label_msg_count = 10; // upper limit on number of span_label message.
let (span, msg, note) = if error_vec.is_empty() {
/// Upper limit on the number of `span_label` messages.
const MAX_LABEL_COUNT: usize = 10;
let (span, msg, note) = if errors.is_empty() {
(span.unwrap(), "unresolved import".to_string(), None)
} else {
let span = MultiSpan::from_spans(
error_vec.clone().into_iter()
.map(|elem: (Span, String, String, Option<String>)| elem.0)
.collect()
errors
.iter()
.map(|(_, err)| err.span)
.collect(),
);
let note: Option<String> = error_vec.clone().into_iter()
.filter_map(|elem: (Span, String, String, Option<String>)| elem.3)
let note = errors
.iter()
.filter_map(|(_, err)| err.note.as_ref())
.last();
let path_vec: Vec<String> = error_vec.clone().into_iter()
.map(|elem: (Span, String, String, Option<String>)| format!("`{}`", elem.1))
.collect();
let path = path_vec.join(", ");
let paths = errors
.iter()
.map(|(path, _)| format!("`{}`", path))
.collect::<Vec<_>>();
let msg = format!(
"unresolved import{} {}",
if path_vec.len() > 1 { "s" } else { "" },
path
if paths.len() > 1 { "s" } else { "" },
paths.join(", "),
);
(span, msg, note)
};
let mut err = struct_span_err!(self.resolver.session, span, E0432, "{}", &msg);
for span_error in error_vec.into_iter().take(max_span_label_msg_count) {
err.span_label(span_error.0, span_error.2);
let mut diag = struct_span_err!(self.resolver.session, span, E0432, "{}", &msg);
if let Some(note) = &note {
diag.note(note);
}
if let Some(note) = note {
err.note(&note);
for (_, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
if let Some(label) = err.label {
diag.span_label(err.span, label);
}
if let Some((span, msg, suggestion, applicability)) = err.suggestion {
diag.span_suggestion(span, &msg, suggestion, applicability);
}
}
err.emit();
diag.emit();
}
/// Attempts to resolve the given import, returning true if its resolution is determined.
@ -802,7 +827,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
match path_res {
PathResult::Module(module) => module,
PathResult::Indeterminate => return false,
PathResult::NonModule(..) | PathResult::Failed(..) => return true,
PathResult::NonModule(..) | PathResult::Failed { .. } => return true,
}
};
@ -866,11 +891,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
!indeterminate
}
// If appropriate, returns an error to report.
/// Performs final import resolution, consistency checks and error reporting.
///
/// Optionally returns an unresolved import error. This error is buffered and used to
/// consolidate multiple unresolved import errors into a single diagnostic.
fn finalize_import(
&mut self,
directive: &'b ImportDirective<'b>
) -> Option<(Span, String, Option<String>)> {
) -> Option<UnresolvedImportError> {
self.current_module = directive.parent_scope.module;
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
@ -896,25 +924,48 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
module
}
PathResult::Failed(span, msg, false) => {
PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
if no_ambiguity {
assert!(directive.imported_module.get().is_none());
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
resolve_error(self, span, ResolutionError::FailedToResolve {
label,
suggestion,
});
}
return None;
}
PathResult::Failed(span, msg, true) => {
PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => {
if no_ambiguity {
assert!(directive.imported_module.get().is_none());
return Some(match self.make_path_suggestion(span, directive.module_path.clone(),
&directive.parent_scope) {
Some((suggestion, note)) => (
span,
format!("did you mean `{}`?", Segment::names_to_string(&suggestion)),
note,
),
None => (span, msg, None),
});
let err = match self.make_path_suggestion(
span,
directive.module_path.clone(),
&directive.parent_scope,
) {
Some((suggestion, note)) => {
UnresolvedImportError {
span,
label: None,
note,
suggestion: Some((
span,
String::from("a similar path exists"),
Segment::names_to_string(&suggestion),
Applicability::MaybeIncorrect,
)),
}
}
None => {
UnresolvedImportError {
span,
label: Some(label),
note: None,
suggestion,
}
}
};
return Some(err);
}
return None;
}
@ -950,11 +1001,12 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
if let ModuleOrUniformRoot::Module(module) = module {
if module.def_id() == directive.parent_scope.module.def_id() {
// Importing a module into itself is not allowed.
return Some((
directive.span,
"Cannot glob-import a module into itself.".to_string(),
None,
));
return Some(UnresolvedImportError {
span: directive.span,
label: Some(String::from("cannot glob-import a module into itself")),
note: None,
suggestion: None,
});
}
}
if !is_prelude &&
@ -1059,31 +1111,42 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
_ => Some(&i.name),
}
});
let lev_suggestion =
match find_best_match_for_name(names, &ident.as_str(), None) {
Some(name) => format!(". Did you mean to use `{}`?", name),
None => String::new(),
};
let msg = match module {
find_best_match_for_name(names, &ident.as_str(), None).map(|suggestion| {
(
ident.span,
String::from("a similar name exists in the module"),
suggestion.to_string(),
Applicability::MaybeIncorrect,
)
});
let label = match module {
ModuleOrUniformRoot::Module(module) => {
let module_str = module_to_string(module);
if let Some(module_str) = module_str {
format!("no `{}` in `{}`{}", ident, module_str, lev_suggestion)
format!("no `{}` in `{}`", ident, module_str)
} else {
format!("no `{}` in the root{}", ident, lev_suggestion)
format!("no `{}` in the root", ident)
}
}
_ => {
if !ident.is_path_segment_keyword() {
format!("no `{}` external crate{}", ident, lev_suggestion)
format!("no `{}` external crate", ident)
} else {
// HACK(eddyb) this shows up for `self` & `super`, which
// should work instead - for now keep the same error message.
format!("no `{}` in the root{}", ident, lev_suggestion)
format!("no `{}` in the root", ident)
}
}
};
Some((directive.span, msg, None))
Some(UnresolvedImportError {
span: directive.span,
label: Some(label),
note: None,
suggestion: lev_suggestion,
})
} else {
// `resolve_ident_in_module` reported a privacy error.
self.import_dummy_binding(directive);

View File

@ -8,7 +8,10 @@ error[E0432]: unresolved import `prelude`
--> $DIR/issue-55897.rs:1:5
|
LL | use prelude::*; //~ ERROR unresolved import `prelude`
| ^^^^^^^ did you mean `std::prelude`?
| ^^^^^^^
| |
| unresolved import
| help: a similar path exists: `std::prelude`
error: cannot determine resolution for the macro `env`
--> $DIR/issue-55897.rs:6:22

View File

@ -1,6 +1,8 @@
use zed::bar;
use zed::baz; //~ ERROR unresolved import `zed::baz` [E0432]
//~^ no `baz` in `zed`. Did you mean to use `bar`?
//~| no `baz` in `zed`
//~| HELP a similar name exists in the module
//~| SUGGESTION bar
mod zed {

View File

@ -2,16 +2,19 @@ error[E0432]: unresolved import `zed::baz`
--> $DIR/import.rs:2:5
|
LL | use zed::baz; //~ ERROR unresolved import `zed::baz` [E0432]
| ^^^^^^^^ no `baz` in `zed`. Did you mean to use `bar`?
| ^^^^^---
| | |
| | help: a similar name exists in the module: `bar`
| no `baz` in `zed`
error[E0432]: unresolved import `foo`
--> $DIR/import.rs:8:9
--> $DIR/import.rs:10:9
|
LL | use foo; //~ ERROR unresolved import `foo` [E0432]
| ^^^ no `foo` in the root
error[E0603]: unresolved item `foo` is private
--> $DIR/import.rs:13:10
--> $DIR/import.rs:15:10
|
LL | zed::foo(); //~ ERROR `foo` is private
| ^^^

View File

@ -2,7 +2,10 @@ error[E0432]: unresolved import `NonExistent`
--> $DIR/issue-55457.rs:1:5
|
LL | use NonExistent; //~ ERROR unresolved import `NonExistent`
| ^^^^^^^^^^^ no `NonExistent` in the root. Did you mean to use `non_existent`?
| ^^^^^^^^^^^
| |
| no `NonExistent` in the root
| help: a similar name exists in the module: `non_existent`
error[E0432]: unresolved import `non_existent`
--> $DIR/issue-55457.rs:2:5

View File

@ -2,13 +2,19 @@ error[E0432]: unresolved import `__test`
--> $DIR/inaccessible-test-modules.rs:5:5
|
LL | use __test as x; //~ ERROR unresolved import `__test`
| ^^^^^^^^^^^ no `__test` in the root. Did you mean to use `test`?
| ------^^^^^
| |
| no `__test` in the root
| help: a similar name exists in the module: `test`
error[E0432]: unresolved import `__test_reexports`
--> $DIR/inaccessible-test-modules.rs:6:5
|
LL | use __test_reexports as y; //~ ERROR unresolved import `__test_reexports`
| ^^^^^^^^^^^^^^^^^^^^^ no `__test_reexports` in the root. Did you mean to use `__test_reexports`?
| ----------------^^^^^
| |
| no `__test_reexports` in the root
| help: a similar name exists in the module: `__test_reexports`
error: aborting due to 2 previous errors

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `self::*`
--> $DIR/issue-31212.rs:5:13
|
LL | pub use self::*; //~ ERROR unresolved
| ^^^^^^^ Cannot glob-import a module into itself.
| ^^^^^^^ cannot glob-import a module into itself
error[E0425]: cannot find function `f` in module `foo`
--> $DIR/issue-31212.rs:9:10

View File

@ -1,14 +1,14 @@
use self::*; //~ ERROR: unresolved import `self::*` [E0432]
//~^ Cannot glob-import a module into itself.
//~^ cannot glob-import a module into itself
mod foo {
use foo::*; //~ ERROR: unresolved import `foo::*` [E0432]
//~^ Cannot glob-import a module into itself.
//~^ cannot glob-import a module into itself
mod bar {
use super::bar::*;
//~^ ERROR: unresolved import `super::bar::*` [E0432]
//~| Cannot glob-import a module into itself.
//~| cannot glob-import a module into itself
}
}

View File

@ -2,19 +2,19 @@ error[E0432]: unresolved import `self::*`
--> $DIR/issue-8208.rs:1:5
|
LL | use self::*; //~ ERROR: unresolved import `self::*` [E0432]
| ^^^^^^^ Cannot glob-import a module into itself.
| ^^^^^^^ cannot glob-import a module into itself
error[E0432]: unresolved import `foo::*`
--> $DIR/issue-8208.rs:5:9
|
LL | use foo::*; //~ ERROR: unresolved import `foo::*` [E0432]
| ^^^^^^ Cannot glob-import a module into itself.
| ^^^^^^ cannot glob-import a module into itself
error[E0432]: unresolved import `super::bar::*`
--> $DIR/issue-8208.rs:9:13
|
LL | use super::bar::*;
| ^^^^^^^^^^^^^ Cannot glob-import a module into itself.
| ^^^^^^^^^^^^^ cannot glob-import a module into itself
error: aborting due to 3 previous errors

View File

@ -5,19 +5,23 @@ mod a {
extern crate alloc;
use alloc::HashMap;
//~^ ERROR unresolved import `alloc` [E0432]
//~| did you mean `self::alloc`?
//~| HELP a similar path exists
//~| SUGGESTION self::alloc
mod b {
use alloc::HashMap;
//~^ ERROR unresolved import `alloc` [E0432]
//~| did you mean `super::alloc`?
//~| HELP a similar path exists
//~| SUGGESTION super::alloc
mod c {
use alloc::HashMap;
//~^ ERROR unresolved import `alloc` [E0432]
//~| did you mean `a::alloc`?
//~| HELP a similar path exists
//~| SUGGESTION a::alloc
mod d {
use alloc::HashMap;
//~^ ERROR unresolved import `alloc` [E0432]
//~| did you mean `a::alloc`?
//~| HELP a similar path exists
//~| SUGGESTION a::alloc
}
}
}

View File

@ -2,25 +2,31 @@ error[E0432]: unresolved import `alloc`
--> $DIR/resolve_self_super_hint.rs:6:9
|
LL | use alloc::HashMap;
| ^^^^^ did you mean `self::alloc`?
| ^^^^^ help: a similar path exists: `self::alloc`
error[E0432]: unresolved import `alloc`
--> $DIR/resolve_self_super_hint.rs:10:13
--> $DIR/resolve_self_super_hint.rs:11:13
|
LL | use alloc::HashMap;
| ^^^^^ did you mean `super::alloc`?
| ^^^^^ help: a similar path exists: `super::alloc`
error[E0432]: unresolved import `alloc`
--> $DIR/resolve_self_super_hint.rs:14:17
--> $DIR/resolve_self_super_hint.rs:16:17
|
LL | use alloc::HashMap;
| ^^^^^ did you mean `a::alloc`?
| ^^^^^
| |
| unresolved import
| help: a similar path exists: `a::alloc`
error[E0432]: unresolved import `alloc`
--> $DIR/resolve_self_super_hint.rs:18:21
--> $DIR/resolve_self_super_hint.rs:21:21
|
LL | use alloc::HashMap;
| ^^^^^ did you mean `a::alloc`?
| ^^^^^
| |
| unresolved import
| help: a similar path exists: `a::alloc`
error: aborting due to 4 previous errors

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `alloc`
--> $DIR/issue-54006.rs:6:5
|
LL | use alloc::vec;
| ^^^^^ did you mean `core::alloc`?
| ^^^^^ help: a similar path exists: `core::alloc`
error: cannot determine resolution for the macro `vec`
--> $DIR/issue-54006.rs:10:18

View File

@ -2,7 +2,10 @@ error[E0432]: unresolved import `foobar`
--> $DIR/local-path-suggestions-2015.rs:24:5
|
LL | use foobar::Baz; //~ ERROR unresolved import `foobar`
| ^^^^^^ did you mean `aux_baz::foobar`?
| ^^^^^^
| |
| unresolved import
| help: a similar path exists: `aux_baz::foobar`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `foo`
--> $DIR/local-path-suggestions-2018.rs:10:9
|
LL | use foo::Bar; //~ ERROR unresolved import `foo`
| ^^^ did you mean `crate::foo`?
| ^^^ help: a similar path exists: `crate::foo`
|
= note: `use` statements changed in Rust 2018; read more at <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html>
@ -10,7 +10,7 @@ error[E0432]: unresolved import `foobar`
--> $DIR/local-path-suggestions-2018.rs:19:5
|
LL | use foobar::Baz; //~ ERROR unresolved import `foobar`
| ^^^^^^ did you mean `baz::foobar`?
| ^^^^^^ help: a similar path exists: `baz::foobar`
error: aborting due to 2 previous errors

View File

@ -1,16 +1,20 @@
// ignore-tidy-linelength
use foo::bar; //~ ERROR unresolved import `foo` [E0432]
//~^ maybe a missing `extern crate foo;`?
use bar::Baz as x; //~ ERROR unresolved import `bar::Baz` [E0432]
//~^ no `Baz` in `bar`. Did you mean to use `Bar`?
//~| no `Baz` in `bar`
//~| HELP a similar name exists in the module
//~| SUGGESTION Bar
use food::baz; //~ ERROR unresolved import `food::baz`
//~^ no `baz` in `food`. Did you mean to use `bag`?
//~| no `baz` in `food`
//~| HELP a similar name exists in the module
//~| SUGGESTION bag
use food::{beens as Foo}; //~ ERROR unresolved import `food::beens` [E0432]
//~^ no `beens` in `food`. Did you mean to use `beans`?
//~| no `beens` in `food`
//~| HELP a similar name exists in the module
//~| SUGGESTION beans
mod bar {
pub struct Bar;
@ -32,7 +36,8 @@ mod m {
}
use MyEnum::*; //~ ERROR unresolved import `MyEnum` [E0432]
//~^ did you mean `self::MyEnum`?
//~| HELP a similar path exists
//~| SUGGESTION self::MyEnum
}
mod items {
@ -41,7 +46,8 @@ mod items {
}
use Enum::*; //~ ERROR unresolved import `Enum` [E0432]
//~^ did you mean `self::Enum`?
//~| HELP a similar path exists
//~| SUGGESTION self::Enum
fn item() {}
}

View File

@ -1,38 +1,47 @@
error[E0432]: unresolved import `foo`
--> $DIR/unresolved-import.rs:3:5
--> $DIR/unresolved-import.rs:1:5
|
LL | use foo::bar; //~ ERROR unresolved import `foo` [E0432]
| ^^^ maybe a missing `extern crate foo;`?
error[E0432]: unresolved import `bar::Baz`
--> $DIR/unresolved-import.rs:6:5
--> $DIR/unresolved-import.rs:4:5
|
LL | use bar::Baz as x; //~ ERROR unresolved import `bar::Baz` [E0432]
| ^^^^^^^^^^^^^ no `Baz` in `bar`. Did you mean to use `Bar`?
| ^^^^^---^^^^^
| | |
| | help: a similar name exists in the module: `Bar`
| no `Baz` in `bar`
error[E0432]: unresolved import `food::baz`
--> $DIR/unresolved-import.rs:9:5
|
LL | use food::baz; //~ ERROR unresolved import `food::baz`
| ^^^^^^^^^ no `baz` in `food`. Did you mean to use `bag`?
| ^^^^^^---
| | |
| | help: a similar name exists in the module: `bag`
| no `baz` in `food`
error[E0432]: unresolved import `food::beens`
--> $DIR/unresolved-import.rs:12:12
--> $DIR/unresolved-import.rs:14:12
|
LL | use food::{beens as Foo}; //~ ERROR unresolved import `food::beens` [E0432]
| ^^^^^^^^^^^^ no `beens` in `food`. Did you mean to use `beans`?
| -----^^^^^^^
| |
| no `beens` in `food`
| help: a similar name exists in the module: `beans`
error[E0432]: unresolved import `MyEnum`
--> $DIR/unresolved-import.rs:34:9
--> $DIR/unresolved-import.rs:38:9
|
LL | use MyEnum::*; //~ ERROR unresolved import `MyEnum` [E0432]
| ^^^^^^ did you mean `self::MyEnum`?
| ^^^^^^ help: a similar path exists: `self::MyEnum`
error[E0432]: unresolved import `Enum`
--> $DIR/unresolved-import.rs:43:9
--> $DIR/unresolved-import.rs:48:9
|
LL | use Enum::*; //~ ERROR unresolved import `Enum` [E0432]
| ^^^^ did you mean `self::Enum`?
| ^^^^ help: a similar path exists: `self::Enum`
error: aborting due to 6 previous errors

View File

@ -2,7 +2,10 @@ error[E0432]: unresolved import `a::b1::C1`
--> $DIR/use-nested-groups-error.rs:9:14
|
LL | use a::{b1::{C1, C2}, B2};
| ^^ no `C1` in `a::b1`. Did you mean to use `C2`?
| ^^
| |
| no `C1` in `a::b1`
| help: a similar name exists in the module: `C2`
error: aborting due to previous error