Suggest creating unary tuples
This commit is contained in:
parent
1e4f10ba64
commit
5a48fe2c20
11 changed files with 155 additions and 0 deletions
|
@ -466,6 +466,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
self.try_to_add_help_message(
|
||||
&root_obligation,
|
||||
&obligation,
|
||||
leaf_trait_predicate,
|
||||
&mut err,
|
||||
|
@ -2428,6 +2429,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
|
||||
fn try_to_add_help_message(
|
||||
&self,
|
||||
root_obligation: &PredicateObligation<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_predicate: ty::PolyTraitPredicate<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
|
@ -2511,6 +2513,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
impl_candidates.as_slice(),
|
||||
span,
|
||||
);
|
||||
|
||||
self.suggest_tuple_wrapping(err, root_obligation, obligation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4436,6 +4436,41 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// If the type failed selection but the trait is implemented for `(T,)`, suggest that the user
|
||||
/// creates a unary tuple
|
||||
///
|
||||
/// This is a common gotcha when using libraries that emulate variadic functions with traits for tuples.
|
||||
pub(super) fn suggest_tuple_wrapping(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
root_obligation: &PredicateObligation<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) {
|
||||
let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(root_pred) = root_obligation.predicate.as_trait_clause() else { return };
|
||||
|
||||
let trait_ref = root_pred.map_bound(|root_pred| {
|
||||
root_pred
|
||||
.trait_ref
|
||||
.with_self_ty(self.tcx, Ty::new_tup(self.tcx, &[root_pred.trait_ref.self_ty()]))
|
||||
});
|
||||
|
||||
let obligation =
|
||||
Obligation::new(self.tcx, obligation.cause.clone(), obligation.param_env, trait_ref);
|
||||
|
||||
if self.predicate_must_hold_modulo_regions(&obligation) {
|
||||
let arg_span = self.tcx.hir().span(*arg_hir_id);
|
||||
err.multipart_suggestion_verbose(
|
||||
format!("use a unary tuple instead"),
|
||||
vec![(arg_span.shrink_to_lo(), "(".into()), (arg_span.shrink_to_hi(), ",)".into())],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn explain_hrtb_projection(
|
||||
&self,
|
||||
diag: &mut Diag<'_>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue