Skip to content

Commit 66dfea1

Browse files
[doc] Document function representation subtyping rules.
1 parent 5d3984e commit 66dfea1

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,27 +1535,39 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
15351535
return getTypeMatchSuccess();
15361536
}
15371537

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.
15401552
static bool
1541-
isConversionAllowedBetween(FunctionTypeRepresentation rep1,
1542-
FunctionTypeRepresentation rep2) {
1553+
isSubtypeOf(FunctionTypeRepresentation potentialSubRepr,
1554+
FunctionTypeRepresentation potentialSuperRepr) {
15431555
auto isThin = [](FunctionTypeRepresentation rep) {
15441556
return rep == FunctionTypeRepresentation::CFunctionPointer ||
15451557
rep == FunctionTypeRepresentation::Thin;
15461558
};
15471559

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))
15501562
return true;
15511563

1552-
// Allowing all to "thick" (swift, block) conventions
1564+
// Allowing all to "thick" (swift, block) conversions
15531565
// "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)
15561568
return true;
15571569

1558-
return rep1 == rep2;
1570+
return potentialSubRepr == potentialSuperRepr;
15591571
}
15601572

15611573
/// Returns true if `constraint rep1 rep2` is satisfied.
@@ -1575,7 +1587,7 @@ static bool matchFunctionRepresentations(FunctionTypeRepresentation rep1,
15751587
if (!(last && last->is<LocatorPathElt::FunctionArgument>()))
15761588
return true;
15771589

1578-
return isConversionAllowedBetween(rep1, rep2);
1590+
return isSubtypeOf(rep1, rep2);
15791591
}
15801592

15811593
case ConstraintKind::OpaqueUnderlyingType:

0 commit comments

Comments
 (0)