Skip to content
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

Improve typo suggestions #91579

Closed
Closed
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
19 changes: 19 additions & 0 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,25 @@ impl Diagnostic {
self
}

/// Prints out a message for a suggestion without showing the suggested code if
/// the message is shown inline.
pub fn span_suggestion_hide_inline(
&mut self,
sp: Span,
msg: &str,
suggestion: String,
applicability: Applicability,
) -> &mut Self {
self.span_suggestion_with_style(
sp,
msg,
suggestion,
applicability,
SuggestionStyle::HideCodeInline,
);
self
}

/// Prints out a message for a suggestion without showing the suggested code.
///
/// This is intended to be used for suggestions that are obvious in what the changes need to
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_errors/src/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,21 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::span_suggestion_hide_inline()`].
pub fn span_suggestion_hide_inline(
&mut self,
sp: Span,
msg: &str,
suggestion: String,
applicability: Applicability,
) -> &mut Self {
if !self.0.allow_suggestions {
return self;
}
self.0.diagnostic.span_suggestion_hide_inline(sp, msg, suggestion, applicability);
self
}

/// See [`Diagnostic::span_suggestion_hidden()`].
pub fn span_suggestion_hidden(
&mut self,
Expand Down
60 changes: 37 additions & 23 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::ptr;
use rustc_ast::{self as ast, Path};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, SuggestionStyle};
use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind};
Expand Down Expand Up @@ -211,10 +211,14 @@ impl<'a> Resolver<'a> {
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
let sugg = candidate.to_ident_string();
err.span_suggestion_hide_inline(
method.span,
"there is an associated function with a similar name",
candidate.to_ident_string(),
&format!(
"did you mean `{}`? (a similarly named associated function)",
&sugg
),
sugg,
Applicability::MaybeIncorrect,
);
}
Expand All @@ -231,10 +235,11 @@ impl<'a> Resolver<'a> {
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
let sugg = candidate.to_ident_string();
err.span_suggestion_hide_inline(
type_.span,
"there is an associated type with a similar name",
candidate.to_ident_string(),
&format!("did you mean `{}`? (a similarly named associated type)", &sugg),
sugg,
Applicability::MaybeIncorrect,
);
}
Expand All @@ -251,10 +256,14 @@ impl<'a> Resolver<'a> {
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
let sugg = candidate.to_ident_string();
err.span_suggestion_hide_inline(
const_.span,
"there is an associated constant with a similar name",
candidate.to_ident_string(),
&format!(
"did you mean `{}`? (a similarly named associated constant)",
&sugg
),
sugg,
Applicability::MaybeIncorrect,
);
}
Expand Down Expand Up @@ -339,9 +348,9 @@ impl<'a> Resolver<'a> {
// A reachable label with a similar name exists.
Some((ident, true)) => {
err.span_label(ident.span, "a label with a similar name is reachable");
err.span_suggestion(
err.span_suggestion_hide_inline(
span,
"try using similarly named label",
&format!("did you mean `{}`? (a similarly named label)", ident),
ident.name.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down Expand Up @@ -583,9 +592,9 @@ impl<'a> Resolver<'a> {
// A reachable label with a similar name exists.
Some((ident, true)) => {
err.span_label(ident.span, "a label with a similar name is reachable");
err.span_suggestion(
err.span_suggestion_hide_inline(
span,
"try using similarly named label",
&format!("did you mean `{}`? (a similarly named label)", ident),
ident.name.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down Expand Up @@ -1157,21 +1166,26 @@ impl<'a> Resolver<'a> {
),
);
}
let msg = match suggestion.target {
SuggestionTarget::SimilarlyNamed => format!(
"{} {} with a similar name exists",
suggestion.res.article(),
suggestion.res.descr()
let (msg, style) = match suggestion.target {
SuggestionTarget::SimilarlyNamed => (
format!(
"did you mean `{}`? (a similarly named {})",
suggestion.candidate,
suggestion.res.descr()
),
SuggestionStyle::HideCodeInline,
),
SuggestionTarget::SingleItem => (
format!("maybe you meant this {}", suggestion.res.descr()),
SuggestionStyle::ShowCode,
),
SuggestionTarget::SingleItem => {
format!("maybe you meant this {}", suggestion.res.descr())
}
};
err.span_suggestion(
err.span_suggestion_with_style(
span,
&msg,
suggestion.candidate.to_string(),
Applicability::MaybeIncorrect,
style,
);
true
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,9 +571,12 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
..
})) = source
{
err.span_suggestion(
err.span_suggestion_hide_inline(
span,
"use the similarly named label",
&format!(
"did you mean `{}`? (a similarly named label)",
label_ident
),
label_ident.name.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/astconv/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
find_best_match_for_name(&all_candidate_names, assoc_name.name, None),
assoc_name.span != DUMMY_SP,
) {
err.span_suggestion(
err.span_suggestion_hide_inline(
assoc_name.span,
"there is an associated type with a similar name",
&format!("did you mean `{}`? (a similarly named associated type)", suggested_name),
suggested_name.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1811,9 +1811,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
assoc_ident.name,
None,
) {
err.span_suggestion(
err.span_suggestion_hide_inline(
assoc_ident.span,
"there is a variant with a similar name",
&format!(
"did you mean `{}`? (a similarly named variant)",
suggested_name
),
suggested_name.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1729,9 +1729,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(field_name) =
Self::suggest_field_name(variant, field.ident.name, skip_fields.collect())
{
err.span_suggestion(
err.span_suggestion_hide_inline(
field.ident.span,
"a field with a similar name exists",
&format!("did you mean `{}`? (a similarly named field)", field_name),
field_name.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down Expand Up @@ -2125,9 +2125,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(suggested_field_name) =
Self::suggest_field_name(def.non_enum_variant(), field.name, vec![])
{
err.span_suggestion(
err.span_suggestion_hide_inline(
field.span,
"a field with a similar name exists",
&format!("did you mean `{}`? (a similarly named field)", suggested_field_name),
suggested_field_name.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -981,9 +981,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
item_name.name,
None,
) {
err.span_suggestion(
err.span_suggestion_hide_inline(
span,
"there is a variant with a similar name",
&format!("did you mean `{}`? (a similarly named variant)", suggestion),
suggestion.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down Expand Up @@ -1014,11 +1014,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// that had unsatisfied trait bounds
if unsatisfied_predicates.is_empty() {
let def_kind = lev_candidate.kind.as_def_kind();
err.span_suggestion(
err.span_suggestion_hide_inline(
span,
&format!(
"there is {} {} with a similar name",
def_kind.article(),
"did you mean `{}`? (a similarly named {})",
lev_candidate.ident,
def_kind.descr(lev_candidate.def_id),
),
lev_candidate.ident.to_string(),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/check/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1489,9 +1489,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
unmentioned_fields.iter().map(|(_, field)| field.name).collect::<Vec<_>>();
let suggested_name = find_best_match_for_name(&input, ident.name, None);
if let Some(suggested_name) = suggested_name {
err.span_suggestion(
err.span_suggestion_hide_inline(
ident.span,
"a field with a similar name exists",
&format!("did you mean `{}`? (a similarly named field)", suggested_name),
suggested_name.to_string(),
Applicability::MaybeIncorrect,
);
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/associated-item/associated-item-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LL | Enum::mispellable();
| ^^^^^^^^^^^
| |
| variant or associated item not found in `Enum`
| help: there is an associated function with a similar name: `misspellable`
| help: did you mean `misspellable`? (a similarly named associated function)

error[E0599]: no variant or associated item named `mispellable_trait` found for enum `Enum` in the current scope
--> $DIR/associated-item-enum.rs:18:11
Expand All @@ -29,7 +29,7 @@ LL | Enum::MISPELLABLE;
| ^^^^^^^^^^^
| |
| variant or associated item not found in `Enum`
| help: there is an associated constant with a similar name: `MISSPELLABLE`
| help: did you mean `MISSPELLABLE`? (a similarly named associated constant)

error: aborting due to 3 previous errors

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/associated-types/associated-types-eq-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LL | fn foo2<I: Foo>(x: I) {
LL | let _: A = x.boo();
| ^
|
help: a type parameter with a similar name exists
help: did you mean `I`? (a similarly named type parameter)
|
LL | let _: I = x.boo();
| ~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn await_on_struct_similar() {
let x = S { awai: 42 };
x.await;
//~^ ERROR no field `await` on type
//~| HELP a field with a similar name exists
//~| HELP did you mean `awai`?
//~| NOTE to `.await` a `Future`, switch to Rust 2018
//~| HELP set `edition = "2021"` in `Cargo.toml`
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ error[E0609]: no field `await` on type `await_on_struct_similar::S`
--> $DIR/suggest-switching-edition-on-await.rs:22:7
|
LL | x.await;
| ^^^^^ help: a field with a similar name exists: `awai`
| ^^^^^ help: did you mean `awai`? (a similarly named field)
|
= note: to `.await` a `Future`, switch to Rust 2018 or later
= help: set `edition = "2021"` in `Cargo.toml`
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/auto-ref-slice-plus-ref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in th
--> $DIR/auto-ref-slice-plus-ref.rs:7:7
|
LL | a.test_mut();
| ^^^^^^^^ help: there is an associated function with a similar name: `get_mut`
| ^^^^^^^^ help: did you mean `get_mut`? (a similarly named associated function)
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `MyIter` defines an item `test_mut`, perhaps you need to implement it
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/block-result/issue-3563.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no method named `b` found for reference `&Self` in the current sco
--> $DIR/issue-3563.rs:3:17
|
LL | || self.b()
| ^ help: there is an associated function with a similar name: `a`
| ^ help: did you mean `a`? (a similarly named associated function)

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/c-variadic/issue-86053-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize
LL | pub trait Fn<Args>: FnMut<Args> {
| ------------------------------- similarly named trait `Fn` defined here
|
help: a trait with a similar name exists
help: did you mean `Fn`? (a similarly named trait)
|
LL | self , ... , self , self , ... ) where Fn : FnOnce ( & 'a & 'b usize ) {
| ~~
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/closures/issue-78720.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ LL | _func: F,
LL | pub trait Fn<Args>: FnMut<Args> {
| ------------------------------- similarly named trait `Fn` defined here
|
help: a trait with a similar name exists
help: did you mean `Fn`? (a similarly named trait)
|
LL | _func: Fn,
| ~~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | trait Foo {}
LL | impl Foo for A<N> {}
| ^
|
help: a struct with a similar name exists
help: did you mean `A`? (a similarly named struct)
|
LL | impl Foo for A<A> {}
| ~
Expand All @@ -25,7 +25,7 @@ LL | struct A<const N: u8>;
LL | impl<const N: u8> Foo for C<N, T> {}
| ^
|
help: a struct with a similar name exists
help: did you mean `A`? (a similarly named struct)
|
LL | impl<const N: u8> Foo for C<N, A> {}
| ~
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/derived-errors/issue-30580.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0609]: no field `c` on type `&Foo`
--> $DIR/issue-30580.rs:12:11
|
LL | b.c;
| ^ help: a field with a similar name exists: `a`
| ^ help: did you mean `a`? (a similarly named field)

error: aborting due to previous error

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/derives/deriving-meta-unknown-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error: cannot find derive macro `Eqr` in this scope
--> $DIR/deriving-meta-unknown-trait.rs:1:10
|
LL | #[derive(Eqr)]
| ^^^ help: a derive macro with a similar name exists: `Eq`
| ^^^ help: did you mean `Eq`? (a similarly named derive macro)
|
::: $SRC_DIR/core/src/cmp.rs:LL:COL
|
Expand All @@ -13,7 +13,7 @@ error: cannot find derive macro `Eqr` in this scope
--> $DIR/deriving-meta-unknown-trait.rs:1:10
|
LL | #[derive(Eqr)]
| ^^^ help: a derive macro with a similar name exists: `Eq`
| ^^^ help: did you mean `Eq`? (a similarly named derive macro)
|
::: $SRC_DIR/core/src/cmp.rs:LL:COL
|
Expand Down
Loading