Skip to content

Commit b9832e7

Browse files
committed
Auto merge of #116713 - estebank:issue-116703, r=compiler-errors
Properly account for self ty in method disambiguation suggestion Fix #116703.
2 parents 862bba6 + 890e92f commit b9832e7

31 files changed

+588
-98
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10181018
}
10191019
err.span_suggestions(
10201020
span,
1021-
"use the fully-qualified path",
1021+
"use fully-qualified syntax",
10221022
suggestions,
10231023
Applicability::MachineApplicable,
10241024
);
@@ -1190,7 +1190,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11901190
} else {
11911191
err.span_suggestion_verbose(
11921192
span.with_hi(assoc_name.span.lo()),
1193-
"use fully qualified syntax to disambiguate",
1193+
"use fully-qualified syntax to disambiguate",
11941194
format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()),
11951195
Applicability::MaybeIncorrect,
11961196
);

compiler/rustc_hir_typeck/src/method/suggest.rs

+58-44
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12601260
// Dynamic limit to avoid hiding just one candidate, which is silly.
12611261
let limit = if sources.len() == 5 { 5 } else { 4 };
12621262

1263+
let mut suggs = vec![];
12631264
for (idx, source) in sources.iter().take(limit).enumerate() {
12641265
match *source {
12651266
CandidateSource::Impl(impl_did) => {
@@ -1322,7 +1323,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13221323
let path = self.tcx.def_path_str(trait_ref.skip_binder().def_id);
13231324

13241325
let ty = match item.kind {
1325-
ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
1326+
ty::AssocKind::Const | ty::AssocKind::Type => impl_ty,
13261327
ty::AssocKind::Fn => self
13271328
.tcx
13281329
.fn_sig(item.def_id)
@@ -1334,19 +1335,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13341335
.copied()
13351336
.unwrap_or(rcvr_ty),
13361337
};
1337-
print_disambiguation_help(
1338+
if let Some(sugg) = print_disambiguation_help(
13381339
item_name,
13391340
args,
13401341
err,
13411342
path,
13421343
ty,
1344+
Some(impl_ty),
13431345
item.kind,
13441346
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
13451347
sugg_span,
13461348
idx,
13471349
self.tcx.sess.source_map(),
13481350
item.fn_has_self_parameter,
1349-
);
1351+
) {
1352+
suggs.push(sugg);
1353+
}
13501354
}
13511355
}
13521356
CandidateSource::Trait(trait_did) => {
@@ -1370,23 +1374,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13701374
};
13711375
if let Some(sugg_span) = sugg_span {
13721376
let path = self.tcx.def_path_str(trait_did);
1373-
print_disambiguation_help(
1377+
if let Some(sugg) = print_disambiguation_help(
13741378
item_name,
13751379
args,
13761380
err,
13771381
path,
13781382
rcvr_ty,
1383+
None,
13791384
item.kind,
13801385
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
13811386
sugg_span,
13821387
idx,
13831388
self.tcx.sess.source_map(),
13841389
item.fn_has_self_parameter,
1385-
);
1390+
) {
1391+
suggs.push(sugg);
1392+
}
13861393
}
13871394
}
13881395
}
13891396
}
1397+
if !suggs.is_empty() && let Some(span) = sugg_span {
1398+
err.span_suggestions(
1399+
span.with_hi(item_name.span.lo()),
1400+
"use fully-qualified syntax to disambiguate",
1401+
suggs,
1402+
Applicability::MachineApplicable,
1403+
);
1404+
}
13901405
if sources.len() > limit {
13911406
err.note(format!("and {} others", sources.len() - limit));
13921407
}
@@ -3146,52 +3161,51 @@ fn print_disambiguation_help<'tcx>(
31463161
err: &mut Diagnostic,
31473162
trait_name: String,
31483163
rcvr_ty: Ty<'_>,
3164+
impl_self_ty: Option<Ty<'_>>,
31493165
kind: ty::AssocKind,
31503166
def_kind_descr: &'static str,
31513167
span: Span,
31523168
candidate: Option<usize>,
31533169
source_map: &source_map::SourceMap,
31543170
fn_has_self_parameter: bool,
3155-
) {
3156-
let mut applicability = Applicability::MachineApplicable;
3157-
let (span, sugg) = if let (
3158-
ty::AssocKind::Fn,
3159-
Some(MethodCallComponents { receiver, args, .. }),
3160-
) = (kind, args)
3161-
{
3162-
let args = format!(
3163-
"({}{})",
3164-
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
3165-
std::iter::once(receiver)
3166-
.chain(args.iter())
3167-
.map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
3168-
applicability = Applicability::HasPlaceholders;
3169-
"_".to_owned()
3170-
}))
3171-
.collect::<Vec<_>>()
3172-
.join(", "),
3173-
);
3174-
let trait_name = if !fn_has_self_parameter {
3175-
format!("<{rcvr_ty} as {trait_name}>")
3171+
) -> Option<String> {
3172+
Some(
3173+
if let (ty::AssocKind::Fn, Some(MethodCallComponents { receiver, args, .. })) = (kind, args)
3174+
{
3175+
let args = format!(
3176+
"({}{})",
3177+
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
3178+
std::iter::once(receiver)
3179+
.chain(args.iter())
3180+
.map(|arg| source_map
3181+
.span_to_snippet(arg.span)
3182+
.unwrap_or_else(|_| { "_".to_owned() }))
3183+
.collect::<Vec<_>>()
3184+
.join(", "),
3185+
);
3186+
let trait_name = if !fn_has_self_parameter && let Some(impl_self_ty) = impl_self_ty {
3187+
format!("<{impl_self_ty} as {trait_name}>")
31763188
} else {
31773189
trait_name
31783190
};
3179-
(span, format!("{trait_name}::{item_name}{args}"))
3180-
} else {
3181-
(span.with_hi(item_name.span.lo()), format!("<{rcvr_ty} as {trait_name}>::"))
3182-
};
3183-
err.span_suggestion_verbose(
3184-
span,
3185-
format!(
3186-
"disambiguate the {} for {}",
3187-
def_kind_descr,
3188-
if let Some(candidate) = candidate {
3189-
format!("candidate #{candidate}")
3190-
} else {
3191-
"the candidate".to_string()
3192-
},
3193-
),
3194-
sugg,
3195-
applicability,
3196-
);
3191+
err.span_suggestion_verbose(
3192+
span,
3193+
format!(
3194+
"disambiguate the {def_kind_descr} for {}",
3195+
if let Some(candidate) = candidate {
3196+
format!("candidate #{candidate}")
3197+
} else {
3198+
"the candidate".to_string()
3199+
},
3200+
),
3201+
format!("{trait_name}::{item_name}{args}"),
3202+
Applicability::HasPlaceholders,
3203+
);
3204+
return None;
3205+
} else if let Some(impl_self_ty) = impl_self_ty {
3206+
format!("<{impl_self_ty} as {trait_name}>::")
3207+
} else {
3208+
format!("{trait_name}::")
3209+
},
3210+
)
31973211
}

tests/ui/associated-consts/associated-const-ambiguity-report.stderr

+3-5
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@ note: candidate #2 is defined in an impl of the trait `Bar` for the type `i32`
1414
|
1515
LL | const ID: i32 = 3;
1616
| ^^^^^^^^^^^^^
17-
help: disambiguate the associated constant for candidate #1
18-
|
19-
LL | const X: i32 = <i32 as Foo>::ID;
20-
| ~~~~~~~~~~~~~~
21-
help: disambiguate the associated constant for candidate #2
17+
help: use fully-qualified syntax to disambiguate
2218
|
2319
LL | const X: i32 = <i32 as Bar>::ID;
2420
| ~~~~~~~~~~~~~~
21+
LL | const X: i32 = <i32 as Foo>::ID;
22+
| ~~~~~~~~~~~~~~
2523

2624
error: aborting due to previous error
2725

tests/ui/associated-inherent-types/issue-109071.no_gate.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ error[E0223]: ambiguous associated type
3333
--> $DIR/issue-109071.rs:15:22
3434
|
3535
LL | fn T() -> Option<Self::Item> {}
36-
| ^^^^^^^^^^ help: use the fully-qualified path: `<Windows<T> as IntoIterator>::Item`
36+
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Windows<T> as IntoIterator>::Item`
3737

3838
error: aborting due to 4 previous errors
3939

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ 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 the fully-qualified path: `<S<bool> as Tr>::Pr`
5+
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<S<bool> as Tr>::Pr`
66

77
error: aborting due to previous error
88

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ 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 the fully-qualified path: `<dyn Trait<i32> as Assoc>::Ty`
5+
| ^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<dyn Trait<i32> as Assoc>::Ty`
66

77
error: aborting due to previous error
88

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ 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 the fully-qualified path: `<Baz as Foo>::Bar`
16+
| ^^^^^^^^ help: use fully-qualified syntax: `<Baz as Foo>::Bar`
1717

1818
error: aborting due to 2 previous errors
1919

tests/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ LL | type Color;
1010
LL | fn a<C:Vehicle+Box>(_: C::Color) {
1111
| ^^^^^^^^ ambiguous associated type `Color`
1212
|
13-
help: use fully qualified syntax to disambiguate
13+
help: use fully-qualified syntax to disambiguate
1414
|
1515
LL | fn a<C:Vehicle+Box>(_: <C as Box>::Color) {
1616
| ~~~~~~~~~~~~
17-
help: use fully qualified syntax to disambiguate
17+
help: use fully-qualified syntax to disambiguate
1818
|
1919
LL | fn a<C:Vehicle+Box>(_: <C as Vehicle>::Color) {
2020
| ~~~~~~~~~~~~~~~~
@@ -31,11 +31,11 @@ LL | type Color;
3131
LL | fn b<C>(_: C::Color) where C : Vehicle+Box {
3232
| ^^^^^^^^ ambiguous associated type `Color`
3333
|
34-
help: use fully qualified syntax to disambiguate
34+
help: use fully-qualified syntax to disambiguate
3535
|
3636
LL | fn b<C>(_: <C as Box>::Color) where C : Vehicle+Box {
3737
| ~~~~~~~~~~~~
38-
help: use fully qualified syntax to disambiguate
38+
help: use fully-qualified syntax to disambiguate
3939
|
4040
LL | fn b<C>(_: <C as Vehicle>::Color) where C : Vehicle+Box {
4141
| ~~~~~~~~~~~~~~~~
@@ -52,11 +52,11 @@ LL | type Color;
5252
LL | fn c<C>(_: C::Color) where C : Vehicle, C : Box {
5353
| ^^^^^^^^ ambiguous associated type `Color`
5454
|
55-
help: use fully qualified syntax to disambiguate
55+
help: use fully-qualified syntax to disambiguate
5656
|
5757
LL | fn c<C>(_: <C as Box>::Color) where C : Vehicle, C : Box {
5858
| ~~~~~~~~~~~~
59-
help: use fully qualified syntax to disambiguate
59+
help: use fully-qualified syntax to disambiguate
6060
|
6161
LL | fn c<C>(_: <C as Vehicle>::Color) where C : Vehicle, C : Box {
6262
| ~~~~~~~~~~~~~~~~
@@ -73,11 +73,11 @@ LL | type Color;
7373
LL | fn e(&self, _: X::Color) where X : Box;
7474
| ^^^^^^^^ ambiguous associated type `Color`
7575
|
76-
help: use fully qualified syntax to disambiguate
76+
help: use fully-qualified syntax to disambiguate
7777
|
7878
LL | fn e(&self, _: <X as Box>::Color) where X : Box;
7979
| ~~~~~~~~~~~~
80-
help: use fully qualified syntax to disambiguate
80+
help: use fully-qualified syntax to disambiguate
8181
|
8282
LL | fn e(&self, _: <X as Vehicle>::Color) where X : Box;
8383
| ~~~~~~~~~~~~~~~~
@@ -94,11 +94,11 @@ LL | type Color;
9494
LL | fn f(&self, _: X::Color) where X : Box { }
9595
| ^^^^^^^^ ambiguous associated type `Color`
9696
|
97-
help: use fully qualified syntax to disambiguate
97+
help: use fully-qualified syntax to disambiguate
9898
|
9999
LL | fn f(&self, _: <X as Box>::Color) where X : Box { }
100100
| ~~~~~~~~~~~~
101-
help: use fully qualified syntax to disambiguate
101+
help: use fully-qualified syntax to disambiguate
102102
|
103103
LL | fn f(&self, _: <X as Vehicle>::Color) where X : Box { }
104104
| ~~~~~~~~~~~~~~~~
@@ -115,11 +115,11 @@ LL | type Color;
115115
LL | fn d(&self, _: X::Color) where X : Box { }
116116
| ^^^^^^^^ ambiguous associated type `Color`
117117
|
118-
help: use fully qualified syntax to disambiguate
118+
help: use fully-qualified syntax to disambiguate
119119
|
120120
LL | fn d(&self, _: <X as Box>::Color) where X : Box { }
121121
| ~~~~~~~~~~~~
122-
help: use fully qualified syntax to disambiguate
122+
help: use fully-qualified syntax to disambiguate
123123
|
124124
LL | fn d(&self, _: <X as Vehicle>::Color) where X : Box { }
125125
| ~~~~~~~~~~~~~~~~

tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ LL | type Color;
1818
LL | fn dent<C:BoxCar>(c: C, color: C::Color) {
1919
| ^^^^^^^^ ambiguous associated type `Color`
2020
|
21-
help: use fully qualified syntax to disambiguate
21+
help: use fully-qualified syntax to disambiguate
2222
|
2323
LL | fn dent<C:BoxCar>(c: C, color: <C as Vehicle>::Color) {
2424
| ~~~~~~~~~~~~~~~~
25-
help: use fully qualified syntax to disambiguate
25+
help: use fully-qualified syntax to disambiguate
2626
|
2727
LL | fn dent<C:BoxCar>(c: C, color: <C as Box>::Color) {
2828
| ~~~~~~~~~~~~
@@ -71,11 +71,11 @@ LL | type Color;
7171
LL | fn paint<C:BoxCar>(c: C, d: C::Color) {
7272
| ^^^^^^^^ ambiguous associated type `Color`
7373
|
74-
help: use fully qualified syntax to disambiguate
74+
help: use fully-qualified syntax to disambiguate
7575
|
7676
LL | fn paint<C:BoxCar>(c: C, d: <C as Vehicle>::Color) {
7777
| ~~~~~~~~~~~~~~~~
78-
help: use fully qualified syntax to disambiguate
78+
help: use fully-qualified syntax to disambiguate
7979
|
8080
LL | fn paint<C:BoxCar>(c: C, d: <C as Box>::Color) {
8181
| ~~~~~~~~~~~~

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ error[E0223]: ambiguous associated type
1313
--> $DIR/associated-types-in-ambiguous-context.rs:22:17
1414
|
1515
LL | trait Foo where Foo::Assoc: Bar {
16-
| ^^^^^^^^^^ help: use the fully-qualified path: `<Self as Foo>::Assoc`
16+
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Foo>::Assoc`
1717

1818
error[E0223]: ambiguous associated type
1919
--> $DIR/associated-types-in-ambiguous-context.rs:27:10
2020
|
2121
LL | type X = std::ops::Deref::Target;
2222
| ^^^^^^^^^^^^^^^^^^^^^^^
2323
|
24-
help: use the fully-qualified path
24+
help: use fully-qualified syntax
2525
|
2626
LL | type X = <CString as Deref>::Target;
2727
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -37,7 +37,7 @@ error[E0223]: ambiguous associated type
3737
--> $DIR/associated-types-in-ambiguous-context.rs:13:23
3838
|
3939
LL | fn grab(&self) -> Grab::Value;
40-
| ^^^^^^^^^^^ help: use the fully-qualified path: `<Self as Grab>::Value`
40+
| ^^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Grab>::Value`
4141

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

tests/ui/associated-types/associated-types-path-1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ LL | type A;
1616
LL | pub fn f2<T: Foo + Bar>(a: T, x: T::A) {}
1717
| ^^^^ ambiguous associated type `A`
1818
|
19-
help: use fully qualified syntax to disambiguate
19+
help: use fully-qualified syntax to disambiguate
2020
|
2121
LL | pub fn f2<T: Foo + Bar>(a: T, x: <T as Bar>::A) {}
2222
| ~~~~~~~~~~~~
23-
help: use fully qualified syntax to disambiguate
23+
help: use fully-qualified syntax to disambiguate
2424
|
2525
LL | pub fn f2<T: Foo + Bar>(a: T, x: <T as Foo>::A) {}
2626
| ~~~~~~~~~~~~

0 commit comments

Comments
 (0)