Skip to content

Unify wording of resolve error #145399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,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)),
}
}
Expand Down
80 changes: 56 additions & 24 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,9 +788,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 {
Expand All @@ -801,13 +800,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
}
Expand Down Expand Up @@ -1001,10 +998,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 })
}
Expand Down Expand Up @@ -2283,13 +2287,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module: Option<ModuleOrUniformRoot<'ra>>,
failed_segment_idx: usize,
ident: Ident,
) -> (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);
Expand All @@ -2307,6 +2323,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))],
Expand All @@ -2316,6 +2333,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())],
Expand All @@ -2324,9 +2342,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![(
Expand All @@ -2335,8 +2358,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!(
Expand All @@ -2348,7 +2372,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;
Expand Down Expand Up @@ -2414,15 +2438,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,
)
Expand Down Expand Up @@ -2476,7 +2501,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 {
Expand Down Expand Up @@ -2508,7 +2534,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
Expand All @@ -2530,7 +2557,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,
)
}
}
}
Expand Down
41 changes: 34 additions & 7 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,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 {
Expand Down Expand Up @@ -1584,16 +1590,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)
},
);
}
Expand Down Expand Up @@ -1711,7 +1725,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)
},
);
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,16 +993,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,
},
);
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4599,14 +4599,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,
},
));
}
Expand Down
17 changes: 12 additions & 5 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,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,
Expand Down Expand Up @@ -331,7 +332,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),
Expand Down Expand Up @@ -476,6 +477,7 @@ enum PathResult<'ra> {
/// The segment name of target
segment_name: Symbol,
error_implied_by_parse_error: bool,
message: String,
},
}

Expand All @@ -486,10 +488,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,
Expand All @@ -498,6 +504,7 @@ impl<'ra> PathResult<'ra> {
is_error_from_last_segment,
module,
error_implied_by_parse_error,
message,
}
}
}
Expand Down
Loading
Loading