1
Fork 0

Erase type params when suggesting fully qualified path

When suggesting the use of a fully qualified path for a method call that
is ambiguous because it has multiple candidates, erase type params in
the resulting code, as they would result in an error when applied. We
replace them with `_` in the output to rely on inference. There might be
cases where this still produces slighlty incomplete suggestions, but it
otherwise produces many more errors in relatively common cases.

Fix #96292
This commit is contained in:
Esteban Küber 2022-04-23 11:22:51 -07:00
parent 1e9aa8a96b
commit acee1f47ef
3 changed files with 74 additions and 0 deletions

View file

@ -736,8 +736,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
&& let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
&& let [path_segment] = path.segments
{
let mut eraser = TypeParamEraser(self.tcx);
let candidate_len = impl_candidates.len();
let suggestions = impl_candidates.iter().map(|candidate| {
let candidate = candidate.super_fold_with(&mut eraser);
format!(
"{}::{}({})",
candidate, segment.ident, path_segment.ident
@ -1037,3 +1039,18 @@ impl<'tcx> TypeFolder<'tcx> for ErrTypeParamEraser<'tcx> {
}
}
}
/// Replace type parameters with `ty::Infer(ty::Var)` to display `_`.
struct TypeParamEraser<'tcx>(TyCtxt<'tcx>);
impl<'tcx> TypeFolder<'tcx> for TypeParamEraser<'tcx> {
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
self.0
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match t.kind() {
ty::Param(_) | ty::Error(_) => self.tcx().mk_ty_var(ty::TyVid::from_u32(0)),
_ => t.super_fold_with(self),
}
}
}