1
Fork 0

Propagate Expectation around binop typeck code to construct more precise trait obligations for binops.

This commit is contained in:
Will Crichton 2022-04-26 13:59:08 -07:00
parent 8c1cc82a82
commit e5bb7d80d6
12 changed files with 194 additions and 42 deletions

View file

@ -665,6 +665,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
self.suggest_restricting_param_bound(
&mut err,
trait_predicate,
None,
obligation.cause.body_id,
);
} else if !suggested {

View file

@ -24,7 +24,8 @@ use rustc_middle::hir::map;
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, IsSuggestable,
ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
ProjectionPredicate, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitable,
};
use rustc_middle::ty::{TypeAndMut, TypeckResults};
use rustc_session::Limit;
@ -172,6 +173,7 @@ pub trait InferCtxtExt<'tcx> {
&self,
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
proj_pred: Option<ty::PolyProjectionPredicate<'tcx>>,
body_id: hir::HirId,
);
@ -457,6 +459,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
&self,
mut err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
proj_pred: Option<ty::PolyProjectionPredicate<'tcx>>,
body_id: hir::HirId,
) {
let trait_pred = self.resolve_numeric_literals_with_default(trait_pred);
@ -589,9 +592,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
// Missing generic type parameter bound.
let param_name = self_ty.to_string();
let constraint = with_no_trimmed_paths!(
let mut constraint = with_no_trimmed_paths!(
trait_pred.print_modifiers_and_trait_path().to_string()
);
if let Some(proj_pred) = proj_pred {
let ProjectionPredicate { projection_ty, term } = proj_pred.skip_binder();
let item = self.tcx.associated_item(projection_ty.item_def_id);
constraint.push_str(&format!("<{}={}>", item.name, term.to_string()));
}
if suggest_constraining_type_param(
self.tcx,
generics,
@ -2825,7 +2835,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
trait_ref: &ty::PolyTraitRef<'tcx>,
) {
let rhs_span = match obligation.cause.code() {
ObligationCauseCode::BinOp { rhs_span: Some(span), is_lit } if *is_lit => span,
ObligationCauseCode::BinOp { rhs_span: Some(span), is_lit, .. } if *is_lit => span,
_ => return,
};
match (