Repository: astral-sh/ruff
File: crates/ty_python_semantic/src/types/narrow.rs (Rust)

Code before:
                    Type::Union(union) => {
                        // remove all members of the union that would require the key
                        let filtered: Vec<_> = union
                            .elements(self.db)
                            .iter()
                            .filter(|ty| match ty {
                                Type::TypedDict(td) => !requires_key(td),
                                Type::Intersection(intersection) => {
                                    let intersection_requires_key =
                                        intersection.positive(self.db).iter().any(|ty| match ty {
                                            Type::TypedDict(td) => requires_key(td),
                                            _ => false,
                                        });
                                    !intersection_requires_key
                                }
                                _ => true,
                            })
                            .copied()
                            .collect();
                        UnionType::from_elements(self.db, filtered)
                    }
                    _ => rhs_type,
                };

                let place = self.expect_place(&rhs_place_expr);
                constraints.insert(place, narrowed.into());
            }
        }

        let mut last_rhs_ty: Option<Type> = None;

        for (op, (left, right)) in std::iter::zip(&**ops, comparator_tuples) {
            let lhs_ty = last_rhs_ty.unwrap_or_else(|| inference.expression_type(left));
            let rhs_ty = inference.expression_type(right);
            last_rhs_ty = Some(rhs_ty);

            match left {
                ast::Expr::Name(_)
                | ast::Expr::Attribute(_)
                | ast::Expr::Subscript(_)
                | ast::Expr::Named(_) => {
                    if let Some(left) = place_expr(left)
                        && let Some(ty) =
                            self.evaluate_expr_compare_op(lhs_ty, rhs_ty, *op, is_positive)
                    {
                        let place = self.expect_place(&left);
                        constraints.insert(place, NarrowingConstraint::regular(ty));
                    }
                }
                ast::Expr::Call(ast::ExprCall {
                    range: _,

Review comment (performance):
similar to https://github.com/astral-sh/ruff/pull/22348, I think this would be slightly more efficient if we used a "typeguard constraint" here rather than a "regular constraint". A regular constraint creates an intersection with the pre-existing type, but that's unnecessary here because we know what the intersection of the unfiltered union with the filtered union will simplify to: it will simplify to the filtered union.

We can also avoid adding the constraint if the narrowed type is exactly the same as the original type.

```suggestion
                if narrowed != rhs_type {
	                let place = self.expect_place(&rhs_place_expr);
	                constraints.insert(place, NarrowingConstraint::typeguard(narrowed));
                }
```

Code after:
                        if intersection
                            .positive(self.db)
                            .iter()
                            .copied()
                            .filter_map(Type::as_typed_dict)
                            .any(requires_key)
                        {
                            Type::Never
                        } else {
                            rhs_type
                        }
                    }
                    Type::Union(union) => {
                        // remove all members of the union that would require the key
                        union.filter(self.db, |ty| match ty {
                            Type::TypedDict(td) => !requires_key(*td),
                            Type::Intersection(intersection) => !intersection
                                .positive(self.db)
                                .iter()
                                .copied()
                                .filter_map(Type::as_typed_dict)
                                .any(requires_key),
                            _ => true,
                        })
                    }
                    _ => rhs_type,
                };

                if narrowed != rhs_type {
                    let place = self.expect_place(&rhs_place_expr);
                    constraints.insert(place, NarrowingConstraint::typeguard(narrowed));
                }
            }
        }

        let mut last_rhs_ty: Option<Type> = None;

        for (op, (left, right)) in std::iter::zip(&**ops, comparator_tuples) {
            let lhs_ty = last_rhs_ty.unwrap_or_else(|| inference.expression_type(left));
            let rhs_ty = inference.expression_type(right);
            last_rhs_ty = Some(rhs_ty);

            match left {
                ast::Expr::Name(_)
                | ast::Expr::Attribute(_)
                | ast::Expr::Subscript(_)
                | ast::Expr::Named(_) => {
                    if let Some(left) = place_expr(left)
                        && let Some(ty) =
                            self.evaluate_expr_compare_op(lhs_ty, rhs_ty, *op, is_positive)
                    {