Skip to content

Commit 9e75730

Browse files
committed
print the appropriate description for the suggestion
1 parent 8788df5 commit 9e75730

File tree

11 files changed

+39
-23
lines changed

11 files changed

+39
-23
lines changed

compiler/rustc_hir/src/def.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::array::IntoIter;
1111
use std::fmt::Debug;
1212

1313
/// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
14-
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
14+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
1515
#[derive(HashStable_Generic)]
1616
pub enum CtorOf {
1717
/// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
@@ -21,7 +21,7 @@ pub enum CtorOf {
2121
}
2222

2323
/// What kind of constructor something is.
24-
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
24+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
2525
#[derive(HashStable_Generic)]
2626
pub enum CtorKind {
2727
/// Constructor function automatically created by a tuple struct/variant.
@@ -33,7 +33,7 @@ pub enum CtorKind {
3333
}
3434

3535
/// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
36-
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
36+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
3737
#[derive(HashStable_Generic)]
3838
pub enum NonMacroAttrKind {
3939
/// Single-segment attribute defined by the language (`#[inline]`)
@@ -50,7 +50,7 @@ pub enum NonMacroAttrKind {
5050
}
5151

5252
/// What kind of definition something is; e.g., `mod` vs `struct`.
53-
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
53+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
5454
#[derive(HashStable_Generic)]
5555
pub enum DefKind {
5656
// Type namespace
@@ -297,7 +297,7 @@ impl DefKind {
297297
/// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]
298298
/// pointing to the definition of `str_to_string` in the current crate.
299299
//
300-
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
300+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
301301
#[derive(HashStable_Generic)]
302302
pub enum Res<Id = hir::HirId> {
303303
/// Definition having a unique ID (`DefId`), corresponds to something defined in user code.

compiler/rustc_hir/src/hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2400,7 +2400,7 @@ impl<'hir> Ty<'hir> {
24002400
}
24012401

24022402
/// Not represented directly in the AST; referred to by name through a `ty_path`.
2403-
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
2403+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
24042404
#[derive(HashStable_Generic)]
24052405
pub enum PrimTy {
24062406
Int(IntTy),

compiler/rustc_resolve/src/diagnostics.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_ast::ptr::P;
44
use rustc_ast::visit::{self, Visitor};
55
use rustc_ast::{self as ast, Crate, ItemKind, ModKind, NodeId, Path, CRATE_NODE_ID};
66
use rustc_ast_pretty::pprust;
7-
use rustc_data_structures::fx::FxHashSet;
7+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
88
use rustc_errors::struct_span_err;
99
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
1010
use rustc_feature::BUILTIN_ATTRIBUTES;
@@ -48,13 +48,15 @@ pub(crate) type Suggestion = (Vec<(Span, String)>, String, Applicability);
4848
/// similarly named label and whether or not it is reachable.
4949
pub(crate) type LabelSuggestion = (Ident, bool);
5050

51+
#[derive(Clone, PartialEq, Eq)]
5152
pub(crate) enum SuggestionTarget {
5253
/// The target has a similar name as the name used by the programmer (probably a typo)
5354
SimilarlyNamed,
5455
/// The target is the only valid item that can be used in the corresponding context
5556
SingleItem,
5657
}
5758

59+
#[derive(Clone, PartialEq, Eq)]
5860
pub(crate) struct TypoSuggestion {
5961
pub candidate: Symbol,
6062
pub res: Res,
@@ -1829,7 +1831,7 @@ impl<'a> Resolver<'a> {
18291831
&mut self,
18301832
ident: Symbol,
18311833
ribs: Option<&PerNS<Vec<Rib<'a>>>>,
1832-
) -> Option<Symbol> {
1834+
) -> Option<TypoSuggestion> {
18331835
fn is_type_candidate(res: Res) -> bool {
18341836
matches!(
18351837
res,
@@ -1884,14 +1886,20 @@ impl<'a> Resolver<'a> {
18841886
}))
18851887
}
18861888

1887-
let mut names = names.iter().map(|sugg| sugg.candidate).collect::<Vec<Symbol>>();
1888-
names.sort();
1889+
// We sort names here to ensure that the suggestion is deterministic.
1890+
// (Notice that there may be a pair of TypoSuggestions whose Symbols
1891+
// are same but Res are different.)
1892+
names.sort_by_key(|name| (name.candidate, name.res));
18891893
names.dedup();
1894+
let symbols = names.iter().map(|sugg| sugg.candidate).collect::<Vec<Symbol>>();
1895+
let typo_suggestions: FxHashMap<Symbol, TypoSuggestion> =
1896+
names.into_iter().map(|typo_sugg| (typo_sugg.candidate, typo_sugg)).collect();
18901897

1891-
match find_best_match_for_name(&names, ident, None) {
1898+
match find_best_match_for_name(&symbols, ident, None) {
18921899
Some(sugg) if sugg == ident => None,
18931900
sugg => sugg,
18941901
}
1902+
.map(|sugg| typo_suggestions.get(&sugg).unwrap().clone())
18951903
}
18961904

18971905
pub(crate) fn report_path_resolution_error(
@@ -2061,8 +2069,12 @@ impl<'a> Resolver<'a> {
20612069
} else {
20622070
self.find_similarly_named_type(ident.name, ribs).map(|sugg| {
20632071
(
2064-
vec![(ident.span, sugg.to_string())],
2065-
String::from("there is a type with a similar name"),
2072+
vec![(ident.span, sugg.candidate.to_string())],
2073+
format!(
2074+
"there is {} {} with a similar name",
2075+
sugg.res.article(),
2076+
sugg.res.descr(),
2077+
),
20662078
Applicability::MaybeIncorrect,
20672079
)
20682080
})
@@ -2087,8 +2099,12 @@ impl<'a> Resolver<'a> {
20872099
} else {
20882100
self.find_similarly_named_type(ident.name, ribs).map(|sugg| {
20892101
(
2090-
vec![(ident.span, sugg.to_string())],
2091-
String::from("there is a type with a similar name"),
2102+
vec![(ident.span, sugg.candidate.to_string())],
2103+
format!(
2104+
"there is {} {} with a similar name",
2105+
sugg.res.article(),
2106+
sugg.res.descr()
2107+
),
20922108
Applicability::MaybeIncorrect,
20932109
)
20942110
})

compiler/rustc_span/src/hygiene.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ impl ExpnKind {
10731073
}
10741074

10751075
/// The kind of macro invocation or definition.
1076-
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
1076+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
10771077
#[derive(HashStable_Generic)]
10781078
pub enum MacroKind {
10791079
/// A bang macro `foo!()`.

src/test/ui/generic-associated-types/equality-bound.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
3939
| ^
4040
| |
4141
| use of undeclared type `I`
42-
| help: there is a type with a similar name: `J`
42+
| help: there is a type parameter with a similar name: `J`
4343

4444
error: aborting due to 4 previous errors
4545

src/test/ui/macros/builtin-prelude-no-accidents.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ LL | type B = vec::Vec<u8>;
1717
| ^^^
1818
| |
1919
| use of undeclared crate or module `vec`
20-
| help: there is a type with a similar name (notice the capitalization): `Vec`
20+
| help: there is a struct with a similar name (notice the capitalization): `Vec`
2121

2222
error: aborting due to 3 previous errors
2323

src/test/ui/macros/macro_path_as_generic_bound.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | foo!(m::m2::A);
55
| ^
66
| |
77
| use of undeclared crate or module `m`
8-
| help: there is a type with a similar name: `T`
8+
| help: there is a type parameter with a similar name: `T`
99

1010
error: aborting due to previous error
1111

src/test/ui/pattern/pattern-error-continue.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | E::V => {}
55
| ^
66
| |
77
| use of undeclared type `E`
8-
| help: there is a type with a similar name: `Eq`
8+
| help: there is a trait with a similar name: `Eq`
99

1010
error[E0532]: expected tuple struct or tuple variant, found unit variant `A::D`
1111
--> $DIR/pattern-error-continue.rs:18:9

src/test/ui/resolve/suggest-similar-type-name.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | FooTyp::bar()
55
| ^^^^^^
66
| |
77
| use of undeclared type `FooTyp`
8-
| help: there is a type with a similar name: `FooType`
8+
| help: there is a struct with a similar name: `FooType`
99

1010
error: aborting due to previous error
1111

src/test/ui/resolve/suggest-type-to-lowercase-path.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let _ = string::new();
55
| ^^^^^^
66
| |
77
| use of undeclared crate or module `string`
8-
| help: there is a type with a similar name (notice the capitalization): `String`
8+
| help: there is a struct with a similar name (notice the capitalization): `String`
99

1010
error: aborting due to previous error
1111

src/test/ui/suggestions/type-ascription-instead-of-path.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | std:io::stdin();
55
| ^^
66
| |
77
| use of undeclared crate or module `io`
8-
| help: there is a type with a similar name: `i8`
8+
| help: there is a builtin type with a similar name: `i8`
99

1010
error[E0423]: expected value, found crate `std`
1111
--> $DIR/type-ascription-instead-of-path.rs:2:5

0 commit comments

Comments
 (0)