Skip to content

Commit 9d07e4d

Browse files
committed
fix the build
1 parent 5af2a44 commit 9d07e4d

2 files changed

Lines changed: 62 additions & 14 deletions

File tree

crates/ty_python_semantic/src/types/call/bind.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,8 +734,9 @@ impl<'db> Bindings<'db> {
734734
_ => continue,
735735
};
736736

737-
let result =
738-
constraints.type_implies(db, *ty_a, *ty_b, InferableTypeVars::None);
737+
let result = constraints
738+
.when_type_implies(db, *ty_a, *ty_b, InferableTypeVars::None)
739+
.is_always_satisfied();
739740
overload.set_return_type(Type::BooleanLiteral(result));
740741
}
741742

crates/ty_python_semantic/src/types/constraints.rs

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl<'db> ConstraintSet<'db> {
184184
typevar: BoundTypeVarInstance<'db>,
185185
lower: Type<'db>,
186186
upper: Type<'db>,
187-
relation: TypeRelation<'db>,
187+
relation: TypeRelation,
188188
) -> Self {
189189
let (lower, upper) = match relation {
190190
// TODO: Is this the correct constraint for redundancy?
@@ -196,9 +196,6 @@ impl<'db> ConstraintSet<'db> {
196196
lower.bottom_materialization(db),
197197
upper.top_materialization(db),
198198
),
199-
TypeRelation::ConstraintImplication(_) => {
200-
panic!("cannot constraint a typevar under constraint implication")
201-
}
202199
};
203200

204201
// We have an (arbitrary) ordering for typevars. If the upper and/or lower bounds are
@@ -264,6 +261,52 @@ impl<'db> ConstraintSet<'db> {
264261
self.node.is_always_satisfied()
265262
}
266263

264+
pub(crate) fn when_type_implies(
265+
self,
266+
db: &'db dyn Db,
267+
lhs: Type<'db>,
268+
rhs: Type<'db>,
269+
inferable: InferableTypeVars<'_, 'db>,
270+
) -> Self {
271+
match (lhs, rhs) {
272+
(Type::TypeVar(bound_typevar), _) => {
273+
let constrained_typevar = match rhs {
274+
Type::TypeVar(rhs_bound_typevar) if rhs_bound_typevar > bound_typevar => {
275+
rhs_bound_typevar
276+
}
277+
_ => bound_typevar,
278+
};
279+
let projected = self.project_typevar(db, constrained_typevar.identity(db));
280+
let constraint = ConstraintSet::constrain_typevar(
281+
db,
282+
bound_typevar,
283+
Type::Never,
284+
rhs,
285+
TypeRelation::Subtyping,
286+
);
287+
projected
288+
.and(db, || constraint)
289+
.when_equivalent_to(db, constraint)
290+
}
291+
292+
(_, Type::TypeVar(bound_typevar)) => {
293+
let projected = self.project_typevar(db, bound_typevar.identity(db));
294+
let constraint = ConstraintSet::constrain_typevar(
295+
db,
296+
bound_typevar,
297+
lhs,
298+
Type::object(),
299+
TypeRelation::Subtyping,
300+
);
301+
projected
302+
.and(db, || constraint)
303+
.when_equivalent_to(db, constraint)
304+
}
305+
306+
_ => lhs.when_subtype_of(db, rhs, inferable),
307+
}
308+
}
309+
267310
/// Updates this constraint set to hold the union of itself and another constraint set.
268311
pub(crate) fn union(&mut self, db: &'db dyn Db, other: Self) -> Self {
269312
self.node = self.node.or(db, other.node);
@@ -317,7 +360,7 @@ impl<'db> ConstraintSet<'db> {
317360

318361
pub(crate) fn when_equivalent_to(self, db: &'db dyn Db, other: Self) -> Self {
319362
Self {
320-
node: self.node.iff(db, other.node).simplify(db, self),
363+
node: self.node.iff(db, other.node).simplify(db),
321364
}
322365
}
323366

@@ -423,7 +466,11 @@ impl<'db> ConstrainedTypeVar<'db> {
423466
/// This is used (among other places) to simplify how we display constraint sets, by removing
424467
/// redundant constraints from a clause.
425468
fn implies(self, db: &'db dyn Db, other: Self) -> bool {
426-
other.contains(db, self)
469+
if self.typevar(db) != other.typevar(db) {
470+
return false;
471+
}
472+
other.lower(db).is_subtype_of(db, self.lower(db))
473+
&& self.upper(db).is_subtype_of(db, other.upper(db))
427474
}
428475

429476
/// Returns the intersection of two range constraints, or `None` if the intersection is empty.
@@ -1176,9 +1223,9 @@ impl<'db> InteriorNode<'db> {
11761223

11771224
// Containment: The range of one constraint might completely contain the range of the
11781225
// other. If so, there are several potential simplifications.
1179-
let larger_smaller = if left_constraint.implies(db, right_constraint, constraints) {
1226+
let larger_smaller = if left_constraint.implies(db, right_constraint) {
11801227
Some((right_constraint, left_constraint))
1181-
} else if right_constraint.implies(db, left_constraint, constraints) {
1228+
} else if right_constraint.implies(db, left_constraint) {
11821229
Some((left_constraint, right_constraint))
11831230
} else {
11841231
None
@@ -1700,10 +1747,10 @@ mod tests {
17001747
let u = BoundTypeVarInstance::synthetic(&db, "U", TypeVarVariance::Invariant);
17011748
let bool_type = KnownClass::Bool.to_instance(&db);
17021749
let str_type = KnownClass::Str.to_instance(&db);
1703-
let t_str = ConstraintSet::range(&db, str_type, t.identity(&db), str_type);
1704-
let t_bool = ConstraintSet::range(&db, bool_type, t.identity(&db), bool_type);
1705-
let u_str = ConstraintSet::range(&db, str_type, u.identity(&db), str_type);
1706-
let u_bool = ConstraintSet::range(&db, bool_type, u.identity(&db), bool_type);
1750+
let t_str = ConstraintSet::range(&db, str_type, t, str_type);
1751+
let t_bool = ConstraintSet::range(&db, bool_type, t, bool_type);
1752+
let u_str = ConstraintSet::range(&db, str_type, u, str_type);
1753+
let u_bool = ConstraintSet::range(&db, bool_type, u, bool_type);
17071754
let constraints = (t_str.or(&db, || t_bool)).and(&db, || u_str.or(&db, || u_bool));
17081755
let actual = constraints.node.display_graph(&db, &"").to_string();
17091756
assert_eq!(actual, expected);

0 commit comments

Comments
 (0)