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

Code before:
    fn implies(self, db: &'db dyn Db, other: Self) -> bool {
        if !self.typevar(db).is_same_typevar_as(db, other.typevar(db)) {
            return false;
        }
        other
            .lower(db)
            .is_constraint_set_assignable_to(db, self.lower(db))
            && self
                .upper(db)
                .is_constraint_set_assignable_to(db, other.upper(db))
    }

    /// Returns the intersection of two range constraints, or `None` if the intersection is empty.
    fn intersect(self, db: &'db dyn Db, other: Self) -> IntersectionResult<'db> {
        // TODO: For now, we treat some upper bounds as unsimplifiable if they become "too big".
        // When intersecting constraints, the upper bounds are also intersected together. If the
        // lhs and rhs upper bounds are unions of intersections (e.g. `(a & b) | (c & d)`), then
        // intersecting them together will require distributing across every pair of union
        // elements. That can quickly balloon in size. We are looking at a better representation
        // that would let us model this case more directly, but for now, we punt.
        const MAX_UPPER_BOUND_SIZE: usize = 4;
        let self_upper = self.upper(db);
        let other_upper = other.upper(db);
        let estimated_upper_bound_size = self_upper.union_size(db)
            * other_upper.union_size(db)
            * (self_upper.intersection_size(db) + other_upper.intersection_size(db));
        if estimated_upper_bound_size >= MAX_UPPER_BOUND_SIZE {
            return IntersectionResult::CannotSimplify;
        }

        // (s₁ ≤ α ≤ t₁) ∧ (s₂ ≤ α ≤ t₂) = (s₁ ∪ s₂) ≤ α ≤ (t₁ ∩ t₂))
        let lower = UnionType::from_elements(db, [self.lower(db), other.lower(db)]);
        let upper = IntersectionType::from_elements(db, [self_upper, other_upper]);

        // If `lower ≰ upper`, then the intersection is empty, since there is no type that is both
        // greater than `lower`, and less than `upper`.
        if !lower.is_constraint_set_assignable_to(db, upper) {
            return IntersectionResult::Disjoint;
        }

        // We do not create lower bounds that are unions, or upper bounds that are intersections,
        // since those can be broken apart into BDDs over simpler constraints.
        if lower.is_union() || upper.is_nontrivial_intersection(db) {
            return IntersectionResult::CannotSimplify;
        }

        IntersectionResult::Simplified(Self::new(db, self.typevar(db), lower, upper))
    }

    pub(crate) fn display(self, db: &'db dyn Db) -> impl Display {
        self.display_inner(db, false)

Review comment (bug):
overflow seems unlikely here unless you have truly massive unions and intersections, but I'd still lean towards doing this just to be safe:


```suggestion
        let estimated_upper_bound_size = self_upper
            .union_size(db)
            .saturating_mul(other_upper.union_size(db))
            .saturating_mul(
                self_upper
                    .intersection_size(db)
                    .saturating_add(other_upper.intersection_size(db)),
            );
```

Code after:
    fn implies(self, db: &'db dyn Db, other: Self) -> bool {
        if !self.typevar(db).is_same_typevar_as(db, other.typevar(db)) {
            return false;
        }
        other
            .lower(db)
            .is_constraint_set_assignable_to(db, self.lower(db))
            && self
                .upper(db)
                .is_constraint_set_assignable_to(db, other.upper(db))
    }

    /// Returns the intersection of two range constraints, or `None` if the intersection is empty.
    fn intersect(self, db: &'db dyn Db, other: Self) -> IntersectionResult<'db> {
        /// TODO: For now, we treat some upper bounds as unsimplifiable if they become "too big".
        /// When intersecting constraints, the upper bounds are also intersected together. If the
        /// lhs and rhs upper bounds are unions of intersections (e.g. `(a & b) | (c & d)`), then
        /// intersecting them together will require distributing across every pair of union
        /// elements. That can quickly balloon in size. We are looking at a better representation
        /// that would let us model this case more directly, but for now, we punt.
        const MAX_UPPER_BOUND_SIZE: usize = 4;

        let self_upper = self.upper(db);
        let other_upper = other.upper(db);
        let estimated_upper_bound_size = self_upper
            .union_size(db)
            .saturating_mul(other_upper.union_size(db))
            .saturating_mul(
                self_upper
                    .intersection_size(db)
                    .saturating_add(other_upper.intersection_size(db)),
            );
        if estimated_upper_bound_size >= MAX_UPPER_BOUND_SIZE {
            return IntersectionResult::CannotSimplify;
        }

        // (s₁ ≤ α ≤ t₁) ∧ (s₂ ≤ α ≤ t₂) = (s₁ ∪ s₂) ≤ α ≤ (t₁ ∩ t₂))
        let lower = UnionType::from_elements(db, [self.lower(db), other.lower(db)]);
        let upper = IntersectionType::from_elements(db, [self_upper, other_upper]);

        // If `lower ≰ upper`, then the intersection is empty, since there is no type that is both
        // greater than `lower`, and less than `upper`.
        if !lower.is_constraint_set_assignable_to(db, upper) {
            return IntersectionResult::Disjoint;
        }

        // We do not create lower bounds that are unions, or upper bounds that are intersections,
        // since those can be broken apart into BDDs over simpler constraints.
        if lower.is_union() || upper.is_nontrivial_intersection(db) {
            return IntersectionResult::CannotSimplify;
        }