Skip to content

Commit

Permalink
Auto merge of rust-lang#116713 - estebank:issue-116703, r=compiler-er…
Browse files Browse the repository at this point in the history
…rors

Properly account for self ty in method disambiguation suggestion

Fix rust-lang#116703.
  • Loading branch information
bors committed Oct 18, 2023
2 parents 862bba6 + 890e92f commit b9832e7
Show file tree
Hide file tree
Showing 31 changed files with 588 additions and 98 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1018,7 +1018,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
err.span_suggestions(
span,
"use the fully-qualified path",
"use fully-qualified syntax",
suggestions,
Applicability::MachineApplicable,
);
Expand Down Expand Up @@ -1190,7 +1190,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} else {
err.span_suggestion_verbose(
span.with_hi(assoc_name.span.lo()),
"use fully qualified syntax to disambiguate",
"use fully-qualified syntax to disambiguate",
format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()),
Applicability::MaybeIncorrect,
);
Expand Down
102 changes: 58 additions & 44 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Dynamic limit to avoid hiding just one candidate, which is silly.
let limit = if sources.len() == 5 { 5 } else { 4 };

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

let ty = match item.kind {
ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
ty::AssocKind::Const | ty::AssocKind::Type => impl_ty,
ty::AssocKind::Fn => self
.tcx
.fn_sig(item.def_id)
Expand All @@ -1334,19 +1335,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.copied()
.unwrap_or(rcvr_ty),
};
print_disambiguation_help(
if let Some(sugg) = print_disambiguation_help(
item_name,
args,
err,
path,
ty,
Some(impl_ty),
item.kind,
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
sugg_span,
idx,
self.tcx.sess.source_map(),
item.fn_has_self_parameter,
);
) {
suggs.push(sugg);
}
}
}
CandidateSource::Trait(trait_did) => {
Expand All @@ -1370,23 +1374,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
if let Some(sugg_span) = sugg_span {
let path = self.tcx.def_path_str(trait_did);
print_disambiguation_help(
if let Some(sugg) = print_disambiguation_help(
item_name,
args,
err,
path,
rcvr_ty,
None,
item.kind,
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
sugg_span,
idx,
self.tcx.sess.source_map(),
item.fn_has_self_parameter,
);
) {
suggs.push(sugg);
}
}
}
}
}
if !suggs.is_empty() && let Some(span) = sugg_span {
err.span_suggestions(
span.with_hi(item_name.span.lo()),
"use fully-qualified syntax to disambiguate",
suggs,
Applicability::MachineApplicable,
);
}
if sources.len() > limit {
err.note(format!("and {} others", sources.len() - limit));
}
Expand Down Expand Up @@ -3146,52 +3161,51 @@ fn print_disambiguation_help<'tcx>(
err: &mut Diagnostic,
trait_name: String,
rcvr_ty: Ty<'_>,
impl_self_ty: Option<Ty<'_>>,
kind: ty::AssocKind,
def_kind_descr: &'static str,
span: Span,
candidate: Option<usize>,
source_map: &source_map::SourceMap,
fn_has_self_parameter: bool,
) {
let mut applicability = Applicability::MachineApplicable;
let (span, sugg) = if let (
ty::AssocKind::Fn,
Some(MethodCallComponents { receiver, args, .. }),
) = (kind, args)
{
let args = format!(
"({}{})",
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
std::iter::once(receiver)
.chain(args.iter())
.map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
applicability = Applicability::HasPlaceholders;
"_".to_owned()
}))
.collect::<Vec<_>>()
.join(", "),
);
let trait_name = if !fn_has_self_parameter {
format!("<{rcvr_ty} as {trait_name}>")
) -> Option<String> {
Some(
if let (ty::AssocKind::Fn, Some(MethodCallComponents { receiver, args, .. })) = (kind, args)
{
let args = format!(
"({}{})",
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
std::iter::once(receiver)
.chain(args.iter())
.map(|arg| source_map
.span_to_snippet(arg.span)
.unwrap_or_else(|_| { "_".to_owned() }))
.collect::<Vec<_>>()
.join(", "),
);
let trait_name = if !fn_has_self_parameter && let Some(impl_self_ty) = impl_self_ty {
format!("<{impl_self_ty} as {trait_name}>")
} else {
trait_name
};
(span, format!("{trait_name}::{item_name}{args}"))
} else {
(span.with_hi(item_name.span.lo()), format!("<{rcvr_ty} as {trait_name}>::"))
};
err.span_suggestion_verbose(
span,
format!(
"disambiguate the {} for {}",
def_kind_descr,
if let Some(candidate) = candidate {
format!("candidate #{candidate}")
} else {
"the candidate".to_string()
},
),
sugg,
applicability,
);
err.span_suggestion_verbose(
span,
format!(
"disambiguate the {def_kind_descr} for {}",
if let Some(candidate) = candidate {
format!("candidate #{candidate}")
} else {
"the candidate".to_string()
},
),
format!("{trait_name}::{item_name}{args}"),
Applicability::HasPlaceholders,
);
return None;
} else if let Some(impl_self_ty) = impl_self_ty {
format!("<{impl_self_ty} as {trait_name}>::")
} else {
format!("{trait_name}::")
},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ note: candidate #2 is defined in an impl of the trait `Bar` for the type `i32`
|
LL | const ID: i32 = 3;
| ^^^^^^^^^^^^^
help: disambiguate the associated constant for candidate #1
|
LL | const X: i32 = <i32 as Foo>::ID;
| ~~~~~~~~~~~~~~
help: disambiguate the associated constant for candidate #2
help: use fully-qualified syntax to disambiguate
|
LL | const X: i32 = <i32 as Bar>::ID;
| ~~~~~~~~~~~~~~
LL | const X: i32 = <i32 as Foo>::ID;
| ~~~~~~~~~~~~~~

error: aborting due to previous error

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

error: aborting due to 4 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0223]: ambiguous associated type
--> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:12
|
LL | let _: S::<bool>::Pr = ();
| ^^^^^^^^^^^^^ help: use the fully-qualified path: `<S<bool> as Tr>::Pr`
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<S<bool> as Tr>::Pr`

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0223]: ambiguous associated type
--> $DIR/ambiguous-associated-type-with-generics.rs:13:13
|
LL | let _x: <dyn Trait<i32>>::Ty;
| ^^^^^^^^^^^^^^^^^^^^ help: use the fully-qualified path: `<dyn Trait<i32> as Assoc>::Ty`
| ^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<dyn Trait<i32> as Assoc>::Ty`

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ error[E0223]: ambiguous associated type
--> $DIR/associated-item-duplicate-names-3.rs:18:12
|
LL | let x: Baz::Bar = 5;
| ^^^^^^^^ help: use the fully-qualified path: `<Baz as Foo>::Bar`
| ^^^^^^^^ help: use fully-qualified syntax: `<Baz as Foo>::Bar`

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ LL | type Color;
LL | fn a<C:Vehicle+Box>(_: C::Color) {
| ^^^^^^^^ ambiguous associated type `Color`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn a<C:Vehicle+Box>(_: <C as Box>::Color) {
| ~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn a<C:Vehicle+Box>(_: <C as Vehicle>::Color) {
| ~~~~~~~~~~~~~~~~
Expand All @@ -31,11 +31,11 @@ LL | type Color;
LL | fn b<C>(_: C::Color) where C : Vehicle+Box {
| ^^^^^^^^ ambiguous associated type `Color`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn b<C>(_: <C as Box>::Color) where C : Vehicle+Box {
| ~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn b<C>(_: <C as Vehicle>::Color) where C : Vehicle+Box {
| ~~~~~~~~~~~~~~~~
Expand All @@ -52,11 +52,11 @@ LL | type Color;
LL | fn c<C>(_: C::Color) where C : Vehicle, C : Box {
| ^^^^^^^^ ambiguous associated type `Color`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn c<C>(_: <C as Box>::Color) where C : Vehicle, C : Box {
| ~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn c<C>(_: <C as Vehicle>::Color) where C : Vehicle, C : Box {
| ~~~~~~~~~~~~~~~~
Expand All @@ -73,11 +73,11 @@ LL | type Color;
LL | fn e(&self, _: X::Color) where X : Box;
| ^^^^^^^^ ambiguous associated type `Color`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn e(&self, _: <X as Box>::Color) where X : Box;
| ~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn e(&self, _: <X as Vehicle>::Color) where X : Box;
| ~~~~~~~~~~~~~~~~
Expand All @@ -94,11 +94,11 @@ LL | type Color;
LL | fn f(&self, _: X::Color) where X : Box { }
| ^^^^^^^^ ambiguous associated type `Color`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn f(&self, _: <X as Box>::Color) where X : Box { }
| ~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn f(&self, _: <X as Vehicle>::Color) where X : Box { }
| ~~~~~~~~~~~~~~~~
Expand All @@ -115,11 +115,11 @@ LL | type Color;
LL | fn d(&self, _: X::Color) where X : Box { }
| ^^^^^^^^ ambiguous associated type `Color`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn d(&self, _: <X as Box>::Color) where X : Box { }
| ~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn d(&self, _: <X as Vehicle>::Color) where X : Box { }
| ~~~~~~~~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ LL | type Color;
LL | fn dent<C:BoxCar>(c: C, color: C::Color) {
| ^^^^^^^^ ambiguous associated type `Color`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn dent<C:BoxCar>(c: C, color: <C as Vehicle>::Color) {
| ~~~~~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn dent<C:BoxCar>(c: C, color: <C as Box>::Color) {
| ~~~~~~~~~~~~
Expand Down Expand Up @@ -71,11 +71,11 @@ LL | type Color;
LL | fn paint<C:BoxCar>(c: C, d: C::Color) {
| ^^^^^^^^ ambiguous associated type `Color`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn paint<C:BoxCar>(c: C, d: <C as Vehicle>::Color) {
| ~~~~~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | fn paint<C:BoxCar>(c: C, d: <C as Box>::Color) {
| ~~~~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ error[E0223]: ambiguous associated type
--> $DIR/associated-types-in-ambiguous-context.rs:22:17
|
LL | trait Foo where Foo::Assoc: Bar {
| ^^^^^^^^^^ help: use the fully-qualified path: `<Self as Foo>::Assoc`
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Foo>::Assoc`

error[E0223]: ambiguous associated type
--> $DIR/associated-types-in-ambiguous-context.rs:27:10
|
LL | type X = std::ops::Deref::Target;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: use the fully-qualified path
help: use fully-qualified syntax
|
LL | type X = <CString as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -37,7 +37,7 @@ error[E0223]: ambiguous associated type
--> $DIR/associated-types-in-ambiguous-context.rs:13:23
|
LL | fn grab(&self) -> Grab::Value;
| ^^^^^^^^^^^ help: use the fully-qualified path: `<Self as Grab>::Value`
| ^^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Grab>::Value`

error[E0223]: ambiguous associated type
--> $DIR/associated-types-in-ambiguous-context.rs:16:22
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/associated-types/associated-types-path-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ LL | type A;
LL | pub fn f2<T: Foo + Bar>(a: T, x: T::A) {}
| ^^^^ ambiguous associated type `A`
|
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | pub fn f2<T: Foo + Bar>(a: T, x: <T as Bar>::A) {}
| ~~~~~~~~~~~~
help: use fully qualified syntax to disambiguate
help: use fully-qualified syntax to disambiguate
|
LL | pub fn f2<T: Foo + Bar>(a: T, x: <T as Foo>::A) {}
| ~~~~~~~~~~~~
Expand Down
Loading

0 comments on commit b9832e7

Please sign in to comment.