@@ -1535,27 +1535,39 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
1535
1535
return getTypeMatchSuccess ();
1536
1536
}
1537
1537
1538
- // Determine whether conversion is allowed between two function types
1539
- // based on their representations.
1538
+ // / Check where a representation is a subtype of another.
1539
+ // /
1540
+ // / The subtype relationship is defined as:
1541
+ // / 1. any representation R is a sub-type of itself.
1542
+ // / 2. a thin representation is a subtype of any other representation.
1543
+ // / 3. a thick representation is a subtype of any other thick representation.
1544
+ // /
1545
+ // / For example, since `@convention(c)` is a thin representation, and
1546
+ // / `@convention(swift)` is a thick representation,
1547
+ // / `@convention(c) (A) -> B` is a sub-type of `(A) -> B`.
1548
+ // /
1549
+ // / NOTE: Unlike typical subtyping relationships, this is not anti-symmetric.
1550
+ // / For example, @convention(c) and @convention(thin) are subtypes of each other
1551
+ // / but not equal.
1540
1552
static bool
1541
- isConversionAllowedBetween (FunctionTypeRepresentation rep1 ,
1542
- FunctionTypeRepresentation rep2 ) {
1553
+ isSubtypeOf (FunctionTypeRepresentation potentialSubRepr ,
1554
+ FunctionTypeRepresentation potentialSuperRepr ) {
1543
1555
auto isThin = [](FunctionTypeRepresentation rep) {
1544
1556
return rep == FunctionTypeRepresentation::CFunctionPointer ||
1545
1557
rep == FunctionTypeRepresentation::Thin;
1546
1558
};
1547
1559
1548
- // Allowing "thin" (c, thin) to "thin" conventions
1549
- if (isThin (rep1 ) && isThin (rep2 ))
1560
+ // Allowing "thin" (c, thin) to "thin" conversions
1561
+ if (isThin (potentialSubRepr ) && isThin (potentialSuperRepr ))
1550
1562
return true ;
1551
1563
1552
- // Allowing all to "thick" (swift, block) conventions
1564
+ // Allowing all to "thick" (swift, block) conversions
1553
1565
// "thin" (c, thin) to "thick" or "thick" to "thick"
1554
- if (rep2 == FunctionTypeRepresentation::Swift ||
1555
- rep2 == FunctionTypeRepresentation::Block)
1566
+ if (potentialSuperRepr == FunctionTypeRepresentation::Swift ||
1567
+ potentialSuperRepr == FunctionTypeRepresentation::Block)
1556
1568
return true ;
1557
1569
1558
- return rep1 == rep2 ;
1570
+ return potentialSubRepr == potentialSuperRepr ;
1559
1571
}
1560
1572
1561
1573
// / Returns true if `constraint rep1 rep2` is satisfied.
@@ -1575,7 +1587,7 @@ static bool matchFunctionRepresentations(FunctionTypeRepresentation rep1,
1575
1587
if (!(last && last->is <LocatorPathElt::FunctionArgument>()))
1576
1588
return true ;
1577
1589
1578
- return isConversionAllowedBetween (rep1, rep2);
1590
+ return isSubtypeOf (rep1, rep2);
1579
1591
}
1580
1592
1581
1593
case ConstraintKind::OpaqueUnderlyingType:
0 commit comments