Split ObligationCauseCode::BinOp for unops to UnOp

This commit is contained in:
Esteban Küber 2025-08-31 21:13:12 +00:00
parent 18a36bccf5
commit ea2daa33c8
4 changed files with 27 additions and 28 deletions

View file

@ -962,13 +962,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (opt_rhs_expr, opt_rhs_ty) = opt_rhs.unzip();
let cause = self.cause(
span,
ObligationCauseCode::BinOp {
lhs_hir_id: lhs_expr.hir_id,
rhs_hir_id: opt_rhs_expr.map(|expr| expr.hir_id),
rhs_span: opt_rhs_expr.map(|expr| expr.span),
rhs_is_lit: opt_rhs_expr
.is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
output_ty: expected.only_has_type(self),
match opt_rhs_expr {
Some(rhs) => ObligationCauseCode::BinOp {
lhs_hir_id: lhs_expr.hir_id,
rhs_hir_id: rhs.hir_id,
rhs_span: rhs.span,
rhs_is_lit: matches!(rhs.kind, hir::ExprKind::Lit(_)),
output_ty: expected.only_has_type(self),
},
None => ObligationCauseCode::UnOp { hir_id: lhs_expr.hir_id },
},
);

View file

@ -389,10 +389,14 @@ pub enum ObligationCauseCode<'tcx> {
/// against.
MatchImpl(ObligationCause<'tcx>, DefId),
UnOp {
hir_id: HirId,
},
BinOp {
lhs_hir_id: HirId,
rhs_hir_id: Option<HirId>,
rhs_span: Option<Span>,
rhs_hir_id: HirId,
rhs_span: Span,
rhs_is_lit: bool,
output_ty: Option<Ty<'tcx>>,
},

View file

@ -963,8 +963,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
trait_pred: ty::PolyTraitPredicate<'tcx>,
err: &mut Diag<'_>,
) -> bool {
if let ObligationCauseCode::BinOp { lhs_hir_id, .. } = obligation.cause.code()
&& let hir::Node::Expr(expr) = self.tcx.hir_node(*lhs_hir_id)
if let ObligationCauseCode::UnOp { hir_id, .. } = obligation.cause.code()
&& let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id)
&& let hir::ExprKind::Unary(hir::UnOp::Neg, inner) = expr.kind
&& let hir::ExprKind::Lit(lit) = inner.kind
&& let LitKind::Int(_, LitIntType::Unsuffixed) = lit.node
@ -2769,9 +2769,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
suggested: bool,
) {
let body_def_id = obligation.cause.body_id;
let span = if let ObligationCauseCode::BinOp { rhs_span: Some(rhs_span), .. } =
obligation.cause.code()
{
let span = if let ObligationCauseCode::BinOp { rhs_span, .. } = obligation.cause.code() {
*rhs_span
} else {
span

View file

@ -554,7 +554,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
return true;
}
} else if let (
ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id: Some(rhs_hir_id), .. },
ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, .. },
predicate,
) = code.peel_derives_with_predicate()
&& let Some(typeck_results) = &self.typeck_results
@ -2801,6 +2801,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
| ObligationCauseCode::QuestionMark
| ObligationCauseCode::CheckAssociatedTypeBounds { .. }
| ObligationCauseCode::LetElse
| ObligationCauseCode::UnOp { .. }
| ObligationCauseCode::BinOp { .. }
| ObligationCauseCode::AscribeUserTypeProvePredicate(..)
| ObligationCauseCode::AlwaysApplicableImpl
@ -3839,9 +3840,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
trait_pred: ty::PolyTraitPredicate<'tcx>,
) {
let rhs_span = match obligation.cause.code() {
ObligationCauseCode::BinOp { rhs_span: Some(span), rhs_is_lit, .. } if *rhs_is_lit => {
span
}
ObligationCauseCode::BinOp { rhs_span, rhs_is_lit, .. } if *rhs_is_lit => rhs_span,
_ => return,
};
if let ty::Float(_) = trait_pred.skip_binder().self_ty().kind()
@ -5108,16 +5107,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let tcx = self.tcx;
let predicate = predicate.upcast(tcx);
match *cause_code {
ObligationCauseCode::BinOp {
lhs_hir_id,
rhs_hir_id: Some(rhs_hir_id),
rhs_span: Some(rhs_span),
..
} if let Some(typeck_results) = &self.typeck_results
&& let hir::Node::Expr(lhs) = tcx.hir_node(lhs_hir_id)
&& let hir::Node::Expr(rhs) = tcx.hir_node(rhs_hir_id)
&& let Some(lhs_ty) = typeck_results.expr_ty_opt(lhs)
&& let Some(rhs_ty) = typeck_results.expr_ty_opt(rhs) =>
ObligationCauseCode::BinOp { lhs_hir_id, rhs_hir_id, rhs_span, .. }
if let Some(typeck_results) = &self.typeck_results
&& let hir::Node::Expr(lhs) = tcx.hir_node(lhs_hir_id)
&& let hir::Node::Expr(rhs) = tcx.hir_node(rhs_hir_id)
&& let Some(lhs_ty) = typeck_results.expr_ty_opt(lhs)
&& let Some(rhs_ty) = typeck_results.expr_ty_opt(rhs) =>
{
if let Some(pred) = predicate.as_trait_clause()
&& tcx.is_lang_item(pred.def_id(), LangItem::PartialEq)