Skip to content

Commit 0100118

Browse files
committed
Preserve generic args in suggestions for ambiguous associated items
Most notably, this preserves the `(..)` of ambiguous RTN paths.
1 parent ced3388 commit 0100118

15 files changed

+140
-47
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

+29-24
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use rustc_data_structures::sorted_map::SortedMap;
33
use rustc_data_structures::unord::UnordMap;
44
use rustc_errors::codes::*;
55
use rustc_errors::{
6-
Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err,
6+
Applicability, Diag, ErrorGuaranteed, MultiSpan, SuggestionStyle, listify, pluralize,
7+
struct_span_code_err,
78
};
89
use rustc_hir::def::{CtorOf, DefKind, Res};
910
use rustc_hir::def_id::DefId;
@@ -443,7 +444,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
443444
span,
444445
&type_names,
445446
&[path_str],
446-
item_segment.ident.name,
447+
item_segment.ident,
447448
assoc_tag,
448449
)
449450
}
@@ -552,12 +553,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
552553

553554
let traits: Vec<_> = self.probe_traits_that_match_assoc_ty(self_ty, ident);
554555

555-
// Don't print `ty::Error` to the user.
556556
self.report_ambiguous_assoc_item_path(
557557
span,
558558
&[self_ty.to_string()],
559559
&traits,
560-
ident.name,
560+
ident,
561561
assoc_tag,
562562
)
563563
}
@@ -568,7 +568,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
568568
span: Span,
569569
types: &[String],
570570
traits: &[String],
571-
name: Symbol,
571+
ident: Ident,
572572
assoc_tag: ty::AssocTag,
573573
) -> ErrorGuaranteed {
574574
let kind_str = assoc_tag_str(assoc_tag);
@@ -588,83 +588,88 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
588588
Applicability::MachineApplicable,
589589
);
590590
} else {
591+
let sugg_sp = span.until(ident.span);
592+
591593
let mut types = types.to_vec();
592594
types.sort();
593595
let mut traits = traits.to_vec();
594596
traits.sort();
595597
match (&types[..], &traits[..]) {
596598
([], []) => {
597599
err.span_suggestion_verbose(
598-
span,
600+
sugg_sp,
599601
format!(
600602
"if there were a type named `Type` that implements a trait named \
601-
`Trait` with associated {kind_str} `{name}`, you could use the \
603+
`Trait` with associated {kind_str} `{ident}`, you could use the \
602604
fully-qualified path",
603605
),
604-
format!("<Type as Trait>::{name}"),
606+
"<Type as Trait>::",
605607
Applicability::HasPlaceholders,
606608
);
607609
}
608610
([], [trait_str]) => {
609611
err.span_suggestion_verbose(
610-
span,
612+
sugg_sp,
611613
format!(
612614
"if there were a type named `Example` that implemented `{trait_str}`, \
613615
you could use the fully-qualified path",
614616
),
615-
format!("<Example as {trait_str}>::{name}"),
617+
format!("<Example as {trait_str}>::"),
616618
Applicability::HasPlaceholders,
617619
);
618620
}
619621
([], traits) => {
620-
err.span_suggestions(
621-
span,
622+
err.span_suggestions_with_style(
623+
sugg_sp,
622624
format!(
623625
"if there were a type named `Example` that implemented one of the \
624-
traits with associated {kind_str} `{name}`, you could use the \
626+
traits with associated {kind_str} `{ident}`, you could use the \
625627
fully-qualified path",
626628
),
627-
traits.iter().map(|trait_str| format!("<Example as {trait_str}>::{name}")),
629+
traits.iter().map(|trait_str| format!("<Example as {trait_str}>::")),
628630
Applicability::HasPlaceholders,
631+
SuggestionStyle::ShowAlways,
629632
);
630633
}
631634
([type_str], []) => {
632635
err.span_suggestion_verbose(
633-
span,
636+
sugg_sp,
634637
format!(
635-
"if there were a trait named `Example` with associated {kind_str} `{name}` \
638+
"if there were a trait named `Example` with associated {kind_str} `{ident}` \
636639
implemented for `{type_str}`, you could use the fully-qualified path",
637640
),
638-
format!("<{type_str} as Example>::{name}"),
641+
format!("<{type_str} as Example>::"),
639642
Applicability::HasPlaceholders,
640643
);
641644
}
642645
(types, []) => {
643-
err.span_suggestions(
644-
span,
646+
err.span_suggestions_with_style(
647+
sugg_sp,
645648
format!(
646-
"if there were a trait named `Example` with associated {kind_str} `{name}` \
649+
"if there were a trait named `Example` with associated {kind_str} `{ident}` \
647650
implemented for one of the types, you could use the fully-qualified \
648651
path",
649652
),
650653
types
651654
.into_iter()
652-
.map(|type_str| format!("<{type_str} as Example>::{name}")),
655+
.map(|type_str| format!("<{type_str} as Example>::")),
653656
Applicability::HasPlaceholders,
657+
SuggestionStyle::ShowAlways,
654658
);
655659
}
656660
(types, traits) => {
657661
let mut suggestions = vec![];
658662
for type_str in types {
659663
for trait_str in traits {
660-
suggestions.push(format!("<{type_str} as {trait_str}>::{name}"));
664+
suggestions.push(format!("<{type_str} as {trait_str}>::"));
661665
}
662666
}
663-
err.span_suggestions(
664-
span,
667+
err.span_suggestions_with_style(
668+
sugg_sp,
665669
"use fully-qualified syntax",
666670
suggestions,
667671
Applicability::MachineApplicable,
672+
SuggestionStyle::ShowAlways,
668673
);
669674
}
670675
}

tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@ error[E0223]: ambiguous associated type
22
--> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:12
33
|
44
LL | let _: S::<bool>::Pr = ();
5-
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<S<bool> as Tr>::Pr`
5+
| ^^^^^^^^^^^^^
6+
|
7+
help: use fully-qualified syntax
8+
|
9+
LL - let _: S::<bool>::Pr = ();
10+
LL + let _: <S<bool> as Tr>::Pr = ();
11+
|
612

713
error: aborting due to 1 previous error
814

tests/ui/associated-item/ambiguous-associated-type-with-generics.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type
22
--> $DIR/ambiguous-associated-type-with-generics.rs:13:13
33
|
44
LL | let _x: <dyn Trait<i32>>::Ty;
5-
| ^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<dyn Trait<i32> as Assoc>::Ty`
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
help: use fully-qualified syntax
8+
|
9+
LL | let _x: <dyn Trait<i32> as Assoc>::Ty;
10+
| ++++++++
611

712
error: aborting due to 1 previous error
813

tests/ui/associated-item/associated-item-duplicate-names-3.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ error[E0223]: ambiguous associated type
1313
--> $DIR/associated-item-duplicate-names-3.rs:18:12
1414
|
1515
LL | let x: Baz::Bar = 5;
16-
| ^^^^^^^^ help: use fully-qualified syntax: `<Baz as Foo>::Bar`
16+
| ^^^^^^^^
17+
|
18+
help: use fully-qualified syntax
19+
|
20+
LL - let x: Baz::Bar = 5;
21+
LL + let x: <Baz as Foo>::Bar = 5;
22+
|
1723

1824
error: aborting due to 2 previous errors
1925

tests/ui/associated-type-bounds/return-type-notation/path-no-qself.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | Trait::method(..): Send,
77
help: if there were a type named `Example` that implemented `Trait`, you could use the fully-qualified path
88
|
99
LL - Trait::method(..): Send,
10-
LL + <Example as Trait>::method: Send,
10+
LL + <Example as Trait>::method(..): Send,
1111
|
1212

1313
error: aborting due to 1 previous error

tests/ui/associated-type-bounds/return-type-notation/path-non-param-qself.stderr

+4-5
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ LL | <()>::method(..): Send,
66
|
77
help: if there were a trait named `Example` with associated function `method` implemented for `()`, you could use the fully-qualified path
88
|
9-
LL - <()>::method(..): Send,
10-
LL + <() as Example>::method: Send,
11-
|
9+
LL | <() as Example>::method(..): Send,
10+
| ++++++++++
1211

1312
error[E0223]: ambiguous associated function
1413
--> $DIR/path-non-param-qself.rs:13:5
@@ -19,7 +18,7 @@ LL | i32::method(..): Send,
1918
help: if there were a trait named `Example` with associated function `method` implemented for `i32`, you could use the fully-qualified path
2019
|
2120
LL - i32::method(..): Send,
22-
LL + <i32 as Example>::method: Send,
21+
LL + <i32 as Example>::method(..): Send,
2322
|
2423

2524
error[E0223]: ambiguous associated function
@@ -31,7 +30,7 @@ LL | Adt::method(..): Send,
3130
help: if there were a trait named `Example` with associated function `method` implemented for `Adt`, you could use the fully-qualified path
3231
|
3332
LL - Adt::method(..): Send,
34-
LL + <Adt as Example>::method: Send,
33+
LL + <Adt as Example>::method(..): Send,
3534
|
3635

3736
error: aborting due to 3 previous errors

tests/ui/associated-types/associated-types-in-ambiguous-context.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ error[E0223]: ambiguous associated type
1414
--> $DIR/associated-types-in-ambiguous-context.rs:22:17
1515
|
1616
LL | trait Foo where Foo::Assoc: Bar {
17-
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Foo>::Assoc`
17+
| ^^^^^^^^^^
18+
|
19+
help: use fully-qualified syntax
20+
|
21+
LL - trait Foo where Foo::Assoc: Bar {
22+
LL + trait Foo where <Self as Foo>::Assoc: Bar {
23+
|
1824

1925
error[E0223]: ambiguous associated type
2026
--> $DIR/associated-types-in-ambiguous-context.rs:27:10
@@ -42,7 +48,13 @@ error[E0223]: ambiguous associated type
4248
--> $DIR/associated-types-in-ambiguous-context.rs:13:23
4349
|
4450
LL | fn grab(&self) -> Grab::Value;
45-
| ^^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Grab>::Value`
51+
| ^^^^^^^^^^^
52+
|
53+
help: use fully-qualified syntax
54+
|
55+
LL - fn grab(&self) -> Grab::Value;
56+
LL + fn grab(&self) -> <Self as Grab>::Value;
57+
|
4658

4759
error[E0223]: ambiguous associated type
4860
--> $DIR/associated-types-in-ambiguous-context.rs:16:22

tests/ui/error-codes/E0223.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@ error[E0223]: ambiguous associated type
22
--> $DIR/E0223.rs:8:14
33
|
44
LL | let foo: MyTrait::X;
5-
| ^^^^^^^^^^ help: use fully-qualified syntax: `<MyStruct as MyTrait>::X`
5+
| ^^^^^^^^^^
6+
|
7+
help: use fully-qualified syntax
8+
|
9+
LL - let foo: MyTrait::X;
10+
LL + let foo: <MyStruct as MyTrait>::X;
11+
|
612

713
error: aborting due to 1 previous error
814

tests/ui/lint/bare-trait-objects-path.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ error[E0223]: ambiguous associated type
1616
--> $DIR/bare-trait-objects-path.rs:23:12
1717
|
1818
LL | let _: Dyn::Ty;
19-
| ^^^^^^^ help: use fully-qualified syntax: `<dyn Dyn as Assoc>::Ty`
19+
| ^^^^^^^
20+
|
21+
help: use fully-qualified syntax
22+
|
23+
LL - let _: Dyn::Ty;
24+
LL + let _: <dyn Dyn as Assoc>::Ty;
25+
|
2026

2127
warning: trait objects without an explicit `dyn` are deprecated
2228
--> $DIR/bare-trait-objects-path.rs:14:5

tests/ui/qualified/qualified-path-params-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | type A = <S as Tr>::A::f<u8>;
77
help: if there were a trait named `Example` with associated type `f` implemented for `<S as Tr>::A`, you could use the fully-qualified path
88
|
99
LL - type A = <S as Tr>::A::f<u8>;
10-
LL + type A = <<S as Tr>::A as Example>::f;
10+
LL + type A = <<S as Tr>::A as Example>::f<u8>;
1111
|
1212

1313
error: aborting due to 1 previous error

tests/ui/self/self-impl.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ error[E0223]: ambiguous associated type
22
--> $DIR/self-impl.rs:23:16
33
|
44
LL | let _: <Self>::Baz = true;
5-
| ^^^^^^^^^^^ help: use fully-qualified syntax: `<Bar as Foo>::Baz`
5+
| ^^^^^^^^^^^
6+
|
7+
help: use fully-qualified syntax
8+
|
9+
LL - let _: <Self>::Baz = true;
10+
LL + let _: <Bar as Foo>::Baz = true;
11+
|
612

713
error[E0223]: ambiguous associated type
814
--> $DIR/self-impl.rs:25:16
915
|
1016
LL | let _: Self::Baz = true;
11-
| ^^^^^^^^^ help: use fully-qualified syntax: `<Bar as Foo>::Baz`
17+
| ^^^^^^^^^
18+
|
19+
help: use fully-qualified syntax
20+
|
21+
LL - let _: Self::Baz = true;
22+
LL + let _: <Bar as Foo>::Baz = true;
23+
|
1224

1325
error: aborting due to 2 previous errors
1426

tests/ui/structs/struct-path-associated-type.stderr

+21-3
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,37 @@ error[E0223]: ambiguous associated type
4848
--> $DIR/struct-path-associated-type.rs:32:13
4949
|
5050
LL | let s = S::A {};
51-
| ^^^^ help: use fully-qualified syntax: `<S as Tr>::A`
51+
| ^^^^
52+
|
53+
help: use fully-qualified syntax
54+
|
55+
LL - let s = S::A {};
56+
LL + let s = <S as Tr>::A {};
57+
|
5258

5359
error[E0223]: ambiguous associated type
5460
--> $DIR/struct-path-associated-type.rs:33:13
5561
|
5662
LL | let z = S::A::<u8> {};
57-
| ^^^^ help: use fully-qualified syntax: `<S as Tr>::A`
63+
| ^^^^
64+
|
65+
help: use fully-qualified syntax
66+
|
67+
LL - let z = S::A::<u8> {};
68+
LL + let z = <S as Tr>::A::<u8> {};
69+
|
5870

5971
error[E0223]: ambiguous associated type
6072
--> $DIR/struct-path-associated-type.rs:35:9
6173
|
6274
LL | S::A {} => {}
63-
| ^^^^ help: use fully-qualified syntax: `<S as Tr>::A`
75+
| ^^^^
76+
|
77+
help: use fully-qualified syntax
78+
|
79+
LL - S::A {} => {}
80+
LL + <S as Tr>::A {} => {}
81+
|
6482

6583
error: aborting due to 8 previous errors
6684

tests/ui/traits/item-privacy.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,25 @@ error[E0223]: ambiguous associated type
230230
--> $DIR/item-privacy.rs:119:12
231231
|
232232
LL | let _: S::B;
233-
| ^^^^ help: use fully-qualified syntax: `<S as assoc_ty::B>::B`
233+
| ^^^^
234+
|
235+
help: use fully-qualified syntax
236+
|
237+
LL - let _: S::B;
238+
LL + let _: <S as assoc_ty::B>::B;
239+
|
234240

235241
error[E0223]: ambiguous associated type
236242
--> $DIR/item-privacy.rs:120:12
237243
|
238244
LL | let _: S::C;
239-
| ^^^^ help: use fully-qualified syntax: `<S as assoc_ty::C>::C`
245+
| ^^^^
246+
|
247+
help: use fully-qualified syntax
248+
|
249+
LL - let _: S::C;
250+
LL + let _: <S as assoc_ty::C>::C;
251+
|
240252

241253
error[E0624]: associated type `A` is private
242254
--> $DIR/item-privacy.rs:122:12

0 commit comments

Comments
 (0)