Skip to content

Commit 02a2f02

Browse files
committed
Suggest full trait ref (with placeholders) on unresolved assoc tys
1 parent 3c8b108 commit 02a2f02

File tree

5 files changed

+57
-23
lines changed

5 files changed

+57
-23
lines changed

compiler/rustc_hir_analysis/src/errors.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,20 @@ pub enum AssocItemNotFoundSugg<'a> {
128128
},
129129
#[multipart_suggestion(
130130
hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg,
131-
style = "verbose",
132-
applicability = "maybe-incorrect"
131+
style = "verbose"
133132
)]
134133
SimilarInOtherTraitQPath {
135134
#[suggestion_part(code = "<")]
136135
lo: Span,
137-
#[suggestion_part(code = " as {trait_}>")]
136+
#[suggestion_part(code = " as {trait_ref}>")]
138137
mi: Span,
139138
#[suggestion_part(code = "{suggested_name}")]
140139
hi: Option<Span>,
141-
trait_: &'a str,
140+
trait_ref: String,
142141
suggested_name: Symbol,
143142
identically_named: bool,
143+
#[applicability]
144+
applicability: Applicability,
144145
},
145146
#[suggestion(
146147
hir_analysis_assoc_item_not_found_other_sugg,

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
251251
return self.dcx().emit_err(err);
252252
}
253253

254+
let trait_args = &ty::GenericArgs::identity_for_item(tcx, best_trait)[1..];
255+
let mut trait_ref = trait_name.clone();
256+
let applicability = if let [arg, args @ ..] = trait_args {
257+
use std::fmt::Write;
258+
write!(trait_ref, "</* {arg}").unwrap();
259+
args.iter().try_for_each(|arg| write!(trait_ref, ", {arg}")).unwrap();
260+
trait_ref += " */>";
261+
Applicability::HasPlaceholders
262+
} else {
263+
Applicability::MaybeIncorrect
264+
};
265+
254266
let identically_named = suggested_name == assoc_name.name;
255267

256268
if let DefKind::TyAlias = tcx.def_kind(item_def_id)
@@ -260,22 +272,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
260272
lo: ty_param_span.shrink_to_lo(),
261273
mi: ty_param_span.shrink_to_hi(),
262274
hi: (!identically_named).then_some(assoc_name.span),
263-
// FIXME(fmease): Use a full trait ref here (with placeholders).
264-
trait_: &trait_name,
275+
trait_ref,
265276
identically_named,
266277
suggested_name,
278+
applicability,
267279
});
268280
} else {
269281
let mut err = self.dcx().create_err(err);
270282
if suggest_constraining_type_param(
271-
tcx,
272-
generics,
273-
&mut err,
274-
&qself_str,
275-
// FIXME(fmease): Use a full trait ref here (with placeholders).
276-
&trait_name,
277-
None,
278-
None,
283+
tcx, generics, &mut err, &qself_str, &trait_ref, None, None,
279284
) && !identically_named
280285
{
281286
// We suggested constraining a type parameter, but the associated item on it

tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0220]: associated type `Assoc` not found for `T`
2-
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:11:22
2+
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
33
|
44
LL | type AssocOf<T> = T::Assoc;
55
| ^^^^^ there is an associated type `Assoc` in the trait `Trait`
@@ -10,7 +10,7 @@ LL | type AssocOf<T> = <T as Trait>::Assoc;
1010
| + +++++++++
1111

1212
error[E0220]: associated type `Assok` not found for `T`
13-
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:15:22
13+
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
1414
|
1515
LL | type AssokOf<T> = T::Assok;
1616
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
@@ -20,6 +20,17 @@ help: consider fully qualifying and renaming the associated type
2020
LL | type AssokOf<T> = <T as Trait>::Assoc;
2121
| + +++++++++ ~~~~~
2222

23-
error: aborting due to 2 previous errors
23+
error[E0220]: associated type `Proj` not found for `T`
24+
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
25+
|
26+
LL | type ProjOf<T> = T::Proj;
27+
| ^^^^ there is an associated type `Proj` in the trait `Parametrized`
28+
|
29+
help: consider fully qualifying the associated type
30+
|
31+
LL | type ProjOf<T> = <T as Parametrized</* 'a, T, N */>>::Proj;
32+
| + ++++++++++++++++++++++++++++++++
33+
34+
error: aborting due to 3 previous errors
2435

2536
For more information about this error, try `rustc --explain E0220`.

tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0220]: associated type `Assoc` not found for `T`
2-
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:11:22
2+
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
33
|
44
LL | type AssocOf<T> = T::Assoc;
55
| ^^^^^ there is an associated type `Assoc` in the trait `Trait`
@@ -10,7 +10,7 @@ LL | type AssocOf<T: Trait> = T::Assoc;
1010
| +++++++
1111

1212
error[E0220]: associated type `Assok` not found for `T`
13-
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:15:22
13+
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
1414
|
1515
LL | type AssokOf<T> = T::Assok;
1616
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
@@ -24,6 +24,17 @@ help: ...and changing the associated type name
2424
LL | type AssokOf<T> = T::Assoc;
2525
| ~~~~~
2626

27-
error: aborting due to 2 previous errors
27+
error[E0220]: associated type `Proj` not found for `T`
28+
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
29+
|
30+
LL | type ProjOf<T> = T::Proj;
31+
| ^^^^ there is an associated type `Proj` in the trait `Parametrized`
32+
|
33+
help: consider restricting type parameter `T`
34+
|
35+
LL | type ProjOf<T: Parametrized</* 'a, T, N */>> = T::Proj;
36+
| ++++++++++++++++++++++++++++++
37+
38+
error: aborting due to 3 previous errors
2839

2940
For more information about this error, try `rustc --explain E0220`.

tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
//@ revisions: eager lazy
55
#![cfg_attr(lazy, feature(lazy_type_alias), allow(incomplete_features))]
66

7-
// FIXME(fmease): Suggest a full trait ref (with placeholders) instead of just a trait name.
8-
9-
trait Trait<T> { type Assoc; }
7+
trait Trait { type Assoc; }
108

119
type AssocOf<T> = T::Assoc; //~ ERROR associated type `Assoc` not found for `T`
1210
//[eager]~^ HELP consider fully qualifying the associated type
@@ -17,4 +15,12 @@ type AssokOf<T> = T::Assok; //~ ERROR associated type `Assok` not found for `T`
1715
//[lazy]~| HELP consider restricting type parameter `T`
1816
//[lazy]~| HELP and changing the associated type name
1917

18+
trait Parametrized<'a, T, const N: usize> {
19+
type Proj;
20+
}
21+
22+
type ProjOf<T> = T::Proj; //~ ERROR associated type `Proj` not found for `T`
23+
//[eager]~^ HELP consider fully qualifying the associated type
24+
//[lazy]~| HELP consider restricting type parameter `T`
25+
2026
fn main() {}

0 commit comments

Comments
 (0)