Unify wording of resolve error

Remove "failed to resolve" and use the same format we use in other resolution errors "cannot find `name`".

```
error[E0433]: cannot find `nonexistent` in `existent`
  --> $DIR/custom_attr_multisegment_error.rs:5:13
   |
LL | #[existent::nonexistent]
   |             ^^^^^^^^^^^ could not find `nonexistent` in `existent`
```
This commit is contained in:
Esteban Küber 2025-08-12 22:27:45 +00:00
parent 3f6250a7bb
commit c73b3d20c6
249 changed files with 778 additions and 666 deletions

View file

@ -469,9 +469,15 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
PathResult::NonModule(partial_res) => {
expected_found_error(partial_res.expect_full_res())
}
PathResult::Failed { span, label, suggestion, .. } => {
Err(VisResolutionError::FailedToResolve(span, label, suggestion))
}
PathResult::Failed {
span, label, suggestion, message, segment_name, ..
} => Err(VisResolutionError::FailedToResolve(
span,
segment_name,
label,
suggestion,
message,
)),
PathResult::Indeterminate => Err(VisResolutionError::Indeterminate(path.span)),
}
}

View file

@ -899,9 +899,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
self.dcx().create_err(errs::SelfImportOnlyInImportListWithNonEmptyPrefix { span })
}
ResolutionError::FailedToResolve { segment, label, suggestion, module } => {
let mut err =
struct_span_code_err!(self.dcx(), span, E0433, "failed to resolve: {label}");
ResolutionError::FailedToResolve { segment, label, suggestion, module, message } => {
let mut err = struct_span_code_err!(self.dcx(), span, E0433, "{message}");
err.span_label(span, label);
if let Some((suggestions, msg, applicability)) = suggestion {
@ -912,13 +911,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
err.multipart_suggestion(msg, suggestions, applicability);
}
if let Some(segment) = segment {
let module = match module {
Some(ModuleOrUniformRoot::Module(m)) if let Some(id) = m.opt_def_id() => id,
_ => CRATE_DEF_ID.to_def_id(),
};
self.find_cfg_stripped(&mut err, &segment, module);
}
let module = match module {
Some(ModuleOrUniformRoot::Module(m)) if let Some(id) = m.opt_def_id() => id,
_ => CRATE_DEF_ID.to_def_id(),
};
self.find_cfg_stripped(&mut err, &segment, module);
err
}
@ -1108,10 +1105,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
VisResolutionError::AncestorOnly(span) => {
self.dcx().create_err(errs::AncestorOnly(span))
}
VisResolutionError::FailedToResolve(span, label, suggestion) => self.into_struct_error(
span,
ResolutionError::FailedToResolve { segment: None, label, suggestion, module: None },
),
VisResolutionError::FailedToResolve(span, segment, label, suggestion, message) => self
.into_struct_error(
span,
ResolutionError::FailedToResolve {
segment,
label,
suggestion,
module: None,
message,
},
),
VisResolutionError::ExpectedFound(span, path_str, res) => {
self.dcx().create_err(errs::ExpectedModuleFound { span, res, path_str })
}
@ -2438,13 +2442,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
failed_segment_idx: usize,
ident: Ident,
diag_metadata: Option<&DiagMetadata<'_>>,
) -> (String, Option<Suggestion>) {
) -> (String, String, Option<Suggestion>) {
let is_last = failed_segment_idx == path.len() - 1;
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
let module_res = match module {
Some(ModuleOrUniformRoot::Module(module)) => module.res(),
_ => None,
};
let scope = match &path[..failed_segment_idx] {
[.., prev] => {
if prev.ident.name == kw::PathRoot {
format!("the crate root")
} else {
format!("`{}`", prev.ident)
}
}
_ => format!("this scope"),
};
let message = format!("cannot find `{ident}` in {scope}");
if module_res == self.graph_root.res() {
let is_mod = |res| matches!(res, Res::Def(DefKind::Mod, _));
let mut candidates = self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod);
@ -2462,6 +2478,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Path { segments, span: Span::default(), tokens: None }
};
(
message,
String::from("unresolved import"),
Some((
vec![(ident.span, pprust::path_to_string(&path))],
@ -2471,6 +2488,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
)
} else if ident.name == sym::core {
(
message,
format!("you might be missing crate `{ident}`"),
Some((
vec![(ident.span, "std".to_string())],
@ -2479,9 +2497,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
)),
)
} else if ident.name == kw::Underscore {
(format!("`_` is not a valid crate or module name"), None)
(
"invalid crate or module name `_`".to_string(),
"`_` is not a valid crate or module name".to_string(),
None,
)
} else if self.tcx.sess.is_rust_2015() {
(
format!("cannot find module or crate `{ident}` in {scope}"),
format!("use of unresolved module or unlinked crate `{ident}`"),
Some((
vec![(
@ -2490,8 +2513,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
)],
if was_invoked_from_cargo() {
format!(
"if you wanted to use a crate named `{ident}`, use `cargo add {ident}` \
to add it to your `Cargo.toml` and import it in your code",
"if you wanted to use a crate named `{ident}`, use `cargo add \
{ident}` to add it to your `Cargo.toml` and import it in your \
code",
)
} else {
format!(
@ -2503,7 +2527,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
)),
)
} else {
(format!("could not find `{ident}` in the crate root"), None)
(message, format!("could not find `{ident}` in the crate root"), None)
}
} else if failed_segment_idx > 0 {
let parent = path[failed_segment_idx - 1].ident.name;
@ -2569,15 +2593,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
);
};
}
(msg, None)
(message, msg, None)
} else if ident.name == kw::SelfUpper {
// As mentioned above, `opt_ns` being `None` indicates a module path in import.
// We can use this to improve a confusing error for, e.g. `use Self::Variant` in an
// impl
if opt_ns.is_none() {
("`Self` cannot be used in imports".to_string(), None)
(message, "`Self` cannot be used in imports".to_string(), None)
} else {
(
message,
"`Self` is only available in impls, traits, and type definitions".to_string(),
None,
)
@ -2632,7 +2657,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
)
});
(format!("use of undeclared type `{ident}`"), suggestion)
let message = format!("cannot find type `{ident}` in {scope}");
(message, format!("use of undeclared type `{ident}`"), suggestion)
} else {
let mut suggestion = None;
if ident.name == sym::alloc {
@ -2663,7 +2689,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ignore_import,
) {
let descr = binding.res().descr();
(format!("{descr} `{ident}` is not a crate or module"), suggestion)
let message = format!("cannot find module or crate `{ident}` in {scope}");
(message, format!("{descr} `{ident}` is not a crate or module"), suggestion)
} else {
let suggestion = if suggestion.is_some() {
suggestion
@ -2685,7 +2712,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Applicability::MaybeIncorrect,
))
};
(format!("use of unresolved module or unlinked crate `{ident}`"), suggestion)
let message = format!("cannot find module or crate `{ident}` in {scope}");
(
message,
format!("use of unresolved module or unlinked crate `{ident}`"),
suggestion,
)
}
}
}

View file

@ -1775,7 +1775,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
finalize.is_some(),
module_had_parse_errors,
module,
|| ("there are too many leading `super` keywords".to_string(), None),
|| {
(
"too many leading `super` keywords".to_string(),
"there are too many leading `super` keywords".to_string(),
None,
)
},
);
}
if segment_idx == 0 {
@ -1823,16 +1829,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module,
|| {
let name_str = if name == kw::PathRoot {
"crate root".to_string()
"the crate root".to_string()
} else {
format!("`{name}`")
};
let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot {
format!("global paths cannot start with {name_str}")
let (message, label) = if segment_idx == 1
&& path[0].ident.name == kw::PathRoot
{
(
format!("global paths cannot start with {name_str}"),
"cannot start with this".to_string(),
)
} else {
format!("{name_str} in paths can only be used in start position")
(
format!("{name_str} in paths can only be used in start position"),
"can only be used in path start position".to_string(),
)
};
(label, None)
(message, label, None)
},
);
}
@ -1948,7 +1962,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
res.article(),
res.descr()
);
(label, None)
let scope = match &path[..segment_idx] {
[.., prev] => {
if prev.ident.name == kw::PathRoot {
format!("the crate root")
} else {
format!("`{}`", prev.ident)
}
}
_ => format!("this scope"),
};
// FIXME: reword, as the reason we expected a module is because of
// the following path segment.
let message = format!("cannot find module `{ident}` in {scope}");
(message, label, None)
},
);
}

View file

@ -1042,16 +1042,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
suggestion,
module,
error_implied_by_parse_error: _,
message,
} => {
if no_ambiguity {
assert!(import.imported_module.get().is_none());
self.report_error(
span,
ResolutionError::FailedToResolve {
segment: Some(segment_name),
segment: segment_name,
label,
suggestion,
module,
message,
},
);
}

View file

@ -4890,14 +4890,16 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
module,
segment_name,
error_implied_by_parse_error: _,
message,
} => {
return Err(respan(
span,
ResolutionError::FailedToResolve {
segment: Some(segment_name),
segment: segment_name,
label,
suggestion,
module,
message,
},
));
}

View file

@ -280,10 +280,11 @@ enum ResolutionError<'ra> {
SelfImportOnlyInImportListWithNonEmptyPrefix,
/// Error E0433: failed to resolve.
FailedToResolve {
segment: Option<Symbol>,
segment: Symbol,
label: String,
suggestion: Option<Suggestion>,
module: Option<ModuleOrUniformRoot<'ra>>,
message: String,
},
/// Error E0434: can't capture dynamic environment in a fn item.
CannotCaptureDynamicEnvironmentInFnItem,
@ -342,7 +343,7 @@ enum ResolutionError<'ra> {
enum VisResolutionError<'a> {
Relative2018(Span, &'a ast::Path),
AncestorOnly(Span),
FailedToResolve(Span, String, Option<Suggestion>),
FailedToResolve(Span, Symbol, String, Option<Suggestion>, String),
ExpectedFound(Span, String, Res),
Indeterminate(Span),
ModuleOnly(Span),
@ -486,6 +487,7 @@ enum PathResult<'ra> {
/// The segment name of target
segment_name: Symbol,
error_implied_by_parse_error: bool,
message: String,
},
}
@ -496,10 +498,14 @@ impl<'ra> PathResult<'ra> {
finalize: bool,
error_implied_by_parse_error: bool,
module: Option<ModuleOrUniformRoot<'ra>>,
label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>),
label_and_suggestion: impl FnOnce() -> (String, String, Option<Suggestion>),
) -> PathResult<'ra> {
let (label, suggestion) =
if finalize { label_and_suggestion() } else { (String::new(), None) };
let (message, label, suggestion) = if finalize {
label_and_suggestion()
} else {
// FIXME: this output isn't actually present in the test suite.
(format!("cannot find `{ident}` in this scope"), String::new(), None)
};
PathResult::Failed {
span: ident.span,
segment_name: ident.name,
@ -508,6 +514,7 @@ impl<'ra> PathResult<'ra> {
is_error_from_last_segment,
module,
error_implied_by_parse_error,
message,
}
}
}

View file

@ -908,10 +908,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
),
path_res @ (PathResult::NonModule(..) | PathResult::Failed { .. }) => {
let mut suggestion = None;
let (span, label, module, segment) =
if let PathResult::Failed { span, label, module, segment_name, .. } =
path_res
{
let (span, message, label, module, segment) = match path_res {
PathResult::Failed {
span, label, module, segment_name, message, ..
} => {
// try to suggest if it's not a macro, maybe a function
if let PathResult::NonModule(partial_res) = self
.cm()
@ -930,26 +930,52 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Applicability::MaybeIncorrect,
));
}
(span, label, module, segment_name)
} else {
(span, message, label, module, segment_name)
}
PathResult::NonModule(partial_res) => {
let found_an = partial_res.base_res().article();
let found_descr = partial_res.base_res().descr();
let scope = match &path[..partial_res.unresolved_segments()] {
[.., prev] => {
format!("{found_descr} `{}`", prev.ident)
}
_ => found_descr.to_string(),
};
let expected_an = kind.article();
let expected_descr = kind.descr();
let expected_name = path[partial_res.unresolved_segments()].ident;
(
path_span,
format!(
"partially resolved path in {} {}",
kind.article(),
kind.descr()
"cannot find {expected_descr} `{expected_name}` in {scope}"
),
match partial_res.base_res() {
Res::Def(
DefKind::Mod | DefKind::Macro(..) | DefKind::ExternCrate,
_,
) => format!(
"partially resolved path in {expected_an} {expected_descr}",
),
_ => format!(
"{expected_an} {expected_descr} can't exist within \
{found_an} {found_descr}"
),
},
None,
path.last().map(|segment| segment.ident.name).unwrap(),
)
};
}
_ => unreachable!(),
};
self.report_error(
span,
ResolutionError::FailedToResolve {
segment: Some(segment),
segment,
label,
suggestion,
module,
message,
},
);
}