@@ -1457,27 +1457,56 @@ impl<'db> Type<'db> {
14571457 Type :: NonInferableTypeVar ( rhs_bound_typevar) ,
14581458 ) if lhs_bound_typevar == rhs_bound_typevar => C :: always_satisfiable ( db) ,
14591459
1460- // A fully static typevar is a subtype of its upper bound, and to something similar to
1461- // the union of its constraints. An unbound, unconstrained, fully static typevar has an
1462- // implicit upper bound of `object` (which is handled above).
1463- ( Type :: NonInferableTypeVar ( bound_typevar) , _)
1464- if bound_typevar. typevar ( db) . bound_or_constraints ( db) . is_some ( ) =>
1465- {
1460+ ( Type :: Union ( union) , _) => union. elements ( db) . iter ( ) . when_all ( db, |& elem_ty| {
1461+ elem_ty. has_relation_to_impl ( db, target, relation, visitor)
1462+ } ) ,
1463+
1464+ ( _, Type :: Union ( union) ) => union. elements ( db) . iter ( ) . when_any ( db, |& elem_ty| {
1465+ self . has_relation_to_impl ( db, elem_ty, relation, visitor)
1466+ } ) ,
1467+
1468+ // If both sides are intersections we need to handle the right side first
1469+ // (A & B & C) is a subtype of (A & B) because the left is a subtype of both A and B,
1470+ // but none of A, B, or C is a subtype of (A & B).
1471+ ( _, Type :: Intersection ( intersection) ) => ( intersection. positive ( db) . iter ( ) )
1472+ . when_all ( db, |& pos_ty| {
1473+ self . has_relation_to_impl ( db, pos_ty, relation, visitor)
1474+ } )
1475+ . and ( db, || {
1476+ intersection
1477+ . negative ( db)
1478+ . iter ( )
1479+ . when_all ( db, |& neg_ty| self . when_disjoint_from ( db, neg_ty) )
1480+ } ) ,
1481+ ( Type :: Intersection ( intersection) , _) => {
1482+ intersection. positive ( db) . iter ( ) . when_any ( db, |& elem_ty| {
1483+ elem_ty. has_relation_to_impl ( db, target, relation, visitor)
1484+ } )
1485+ }
1486+
1487+ // A non-inferable typevar must satisfy the relation for every possible specialization.
1488+ ( Type :: NonInferableTypeVar ( bound_typevar) , _) => {
14661489 match bound_typevar. typevar ( db) . bound_or_constraints ( db) {
1467- None => unreachable ! ( ) ,
14681490 // Verify that the upper bound satisfies the relation. (If it does, than any
1469- // subtype of the upper bound will too.) Also add a safety constraint that
1470- // ensures that the typevar specializes to a subtype of the upper bound.
1491+ // subtype of the upper bound will too.)
1492+ None => {
1493+ let bound = Type :: object ( db) ;
1494+ C :: constrain_typevar ( db, bound_typevar, Type :: Never , bound)
1495+ . implies ( db, || {
1496+ bound. has_relation_to_impl ( db, target, relation, visitor)
1497+ } )
1498+ }
14711499 Some ( TypeVarBoundOrConstraints :: UpperBound ( bound) ) => {
14721500 C :: constrain_typevar ( db, bound_typevar, Type :: Never , bound)
14731501 . implies ( db, || {
14741502 bound. has_relation_to_impl ( db, target, relation, visitor)
14751503 } )
14761504 }
1505+ // Verify that each constraint satisfies the relation. (Note that constrained
1506+ // typevars must specialize to _exactly_ one of the constraints, not to a
1507+ // _subtype_ of one.)
14771508 Some ( TypeVarBoundOrConstraints :: Constraints ( constraints) ) => {
14781509 constraints. elements ( db) . iter ( ) . when_all ( db, |constraint| {
1479- // Note that constrained typevars must specialize to _exactly_ one of the
1480- // constraints, not to a _subtype_ of one.
14811510 C :: constrain_typevar ( db, bound_typevar, * constraint, * constraint)
14821511 . implies ( db, || {
14831512 constraint. has_relation_to_impl ( db, target, relation, visitor)
@@ -1487,79 +1516,31 @@ impl<'db> Type<'db> {
14871516 }
14881517 }
14891518
1490- // If the typevar is constrained, there must be multiple constraints, and the typevar
1491- // might be specialized to any one of them. However, the constraints do not have to be
1492- // disjoint, which means an lhs type might be a subtype of all of the constraints.
1493- ( _, Type :: NonInferableTypeVar ( bound_typevar) )
1494- if !bound_typevar
1495- . typevar ( db)
1496- . constraints ( db)
1497- . when_some_and ( db, |constraints| {
1498- constraints. iter ( ) . when_all ( db, |constraint| {
1499- C :: constrain_typevar ( db, bound_typevar, * constraint, * constraint)
1500- . implies ( db, || {
1501- self . has_relation_to_impl ( db, * constraint, relation, visitor)
1502- } )
1503- } )
1504- } )
1505- . is_never_satisfied ( db) =>
1506- {
1507- // TODO: The repetition here isn't great, but we really need the fallthrough logic,
1508- // where this arm only engages if it returns true (or in the world of constraints,
1509- // not false). Once we're using real constraint sets instead of bool, we should be
1510- // able to simplify the typevar logic.
1511- bound_typevar
1512- . typevar ( db)
1513- . constraints ( db)
1514- . when_some_and ( db, |constraints| {
1515- constraints. iter ( ) . when_all ( db, |constraint| {
1519+ ( _, Type :: NonInferableTypeVar ( bound_typevar) ) => {
1520+ match bound_typevar. typevar ( db) . bound_or_constraints ( db) {
1521+ // There is no guarantee which type an unconstrained typevar might specialize
1522+ // to. Never (which is checked above) is the only type that is a subtype of any
1523+ // specialization.
1524+ None | Some ( TypeVarBoundOrConstraints :: UpperBound ( _) ) => C :: unsatisfiable ( db) ,
1525+
1526+ // A constrained typevar, on the other hand, does have a fixed set of types
1527+ // that it can specialize to, so we can check them all exhaustively.
1528+ Some ( TypeVarBoundOrConstraints :: Constraints ( constraints) ) => {
1529+ constraints. elements ( db) . iter ( ) . when_all ( db, |constraint| {
15161530 C :: constrain_typevar ( db, bound_typevar, * constraint, * constraint)
15171531 . implies ( db, || {
15181532 self . has_relation_to_impl ( db, * constraint, relation, visitor)
15191533 } )
15201534 } )
1521- } )
1535+ }
1536+ }
15221537 }
15231538
15241539 // `Never` is the bottom type, the empty set.
15251540 // Other than one unlikely edge case (TypeVars bound to `Never`),
15261541 // no other type is a subtype of or assignable to `Never`.
15271542 ( _, Type :: Never ) => C :: unsatisfiable ( db) ,
15281543
1529- ( Type :: Union ( union) , _) => union. elements ( db) . iter ( ) . when_all ( db, |& elem_ty| {
1530- elem_ty. has_relation_to_impl ( db, target, relation, visitor)
1531- } ) ,
1532-
1533- ( _, Type :: Union ( union) ) => union. elements ( db) . iter ( ) . when_any ( db, |& elem_ty| {
1534- self . has_relation_to_impl ( db, elem_ty, relation, visitor)
1535- } ) ,
1536-
1537- // If both sides are intersections we need to handle the right side first
1538- // (A & B & C) is a subtype of (A & B) because the left is a subtype of both A and B,
1539- // but none of A, B, or C is a subtype of (A & B).
1540- ( _, Type :: Intersection ( intersection) ) => ( intersection. positive ( db) . iter ( ) )
1541- . when_all ( db, |& pos_ty| {
1542- self . has_relation_to_impl ( db, pos_ty, relation, visitor)
1543- } )
1544- . and ( db, || {
1545- intersection
1546- . negative ( db)
1547- . iter ( )
1548- . when_all ( db, |& neg_ty| self . when_disjoint_from ( db, neg_ty) )
1549- } ) ,
1550- ( Type :: Intersection ( intersection) , _) => {
1551- intersection. positive ( db) . iter ( ) . when_any ( db, |& elem_ty| {
1552- elem_ty. has_relation_to_impl ( db, target, relation, visitor)
1553- } )
1554- }
1555-
1556- // Other than the special cases checked above, no other types are a subtype of a
1557- // typevar, since there's no guarantee what type the typevar will be specialized to.
1558- // (If the typevar is bounded, it might be specialized to a smaller type than the
1559- // bound. This is true even if the bound is a final class, since the typevar can still
1560- // be specialized to `Never`.)
1561- ( _, Type :: NonInferableTypeVar ( _) ) => C :: unsatisfiable ( db) ,
1562-
15631544 // TODO: Infer specializations here
15641545 ( Type :: TypeVar ( _) , _) | ( _, Type :: TypeVar ( _) ) => C :: unsatisfiable ( db) ,
15651546
@@ -1822,7 +1803,7 @@ impl<'db> Type<'db> {
18221803
18231804 // Other than the special cases enumerated above, `Instance` types and typevars are
18241805 // never subtypes of any other variants
1825- ( Type :: NominalInstance ( _) | Type :: NonInferableTypeVar ( _ ) , _) => C :: unsatisfiable ( db) ,
1806+ ( Type :: NominalInstance ( _) , _) => C :: unsatisfiable ( db) ,
18261807 }
18271808 }
18281809
0 commit comments