[ty] narrow the right-hand side of ==, !=, is and is not conditions when the left-hand side is not narrowable (#22511)
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
This commit is contained in:
@@ -1250,6 +1250,29 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
||||
);
|
||||
}
|
||||
}
|
||||
// For symmetric operators (==, !=, is, is not), if left is not a narrowable target,
|
||||
// try to narrow the right operand instead by swapping the operands.
|
||||
// E.g., `None != x` should narrow `x` the same way as `x != None`.
|
||||
_ if matches!(
|
||||
op,
|
||||
ast::CmpOp::Eq | ast::CmpOp::NotEq | ast::CmpOp::Is | ast::CmpOp::IsNot
|
||||
) && matches!(
|
||||
right,
|
||||
ast::Expr::Name(_)
|
||||
| ast::Expr::Attribute(_)
|
||||
| ast::Expr::Subscript(_)
|
||||
| ast::Expr::Named(_)
|
||||
) =>
|
||||
{
|
||||
if let Some(right_place) = place_expr(right)
|
||||
// Swap lhs_ty and rhs_ty since we're narrowing the right operand
|
||||
&& let Some(ty) =
|
||||
self.evaluate_expr_compare_op(rhs_ty, lhs_ty, *op, is_positive)
|
||||
{
|
||||
let place = self.expect_place(&right_place);
|
||||
constraints.insert(place, NarrowingConstraint::regular(ty));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user