Skip to content

Commit 0c51159

Browse files
committed
[CSBindings] Record constraint associated with a subtype relationship
While inferring bindings, let's record not only the fact that current type variable is a subtype of some other type variable but track constraint which establishes this relationship.
1 parent 17f7ad8 commit 0c51159

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4749,7 +4749,7 @@ class ConstraintSystem {
47494749
/// chain of subtypes because binding inference algorithm can't,
47504750
/// at the moment, determine bindings transitively through supertype
47514751
/// type variables.
4752-
llvm::SmallPtrSet<TypeVariableType *, 4> SubtypeOf;
4752+
llvm::SmallDenseMap<TypeVariableType *, Constraint *, 4> SubtypeOf;
47534753

47544754
PotentialBindings(TypeVariableType *typeVar)
47554755
: TypeVar(typeVar), PotentiallyIncomplete(isGenericParameter()) {}
@@ -4794,10 +4794,10 @@ class ConstraintSystem {
47944794
// This is required because algorithm can't currently infer
47954795
// bindings for subtype transitively through superclass ones.
47964796
if (!(x.IsHole && y.IsHole)) {
4797-
if (x.SubtypeOf.count(y.TypeVar))
4797+
if (x.isSubtypeOf(y.TypeVar))
47984798
return false;
47994799

4800-
if (y.SubtypeOf.count(x.TypeVar))
4800+
if (y.isSubtypeOf(x.TypeVar))
48014801
return true;
48024802
}
48034803

@@ -4843,6 +4843,15 @@ class ConstraintSystem {
48434843
return false;
48444844
}
48454845

4846+
bool isSubtypeOf(TypeVariableType *typeVar) const {
4847+
auto result = SubtypeOf.find(typeVar);
4848+
if (result == SubtypeOf.end())
4849+
return false;
4850+
4851+
auto *constraint = result->second;
4852+
return constraint->getKind() == ConstraintKind::Subtype;
4853+
}
4854+
48464855
/// Check if this binding is favored over a disjunction e.g.
48474856
/// if it has only concrete types or would resolve a closure.
48484857
bool favoredOverDisjunction(Constraint *disjunction) const;

lib/Sema/CSBindings.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,28 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
790790
}
791791
}
792792

793-
if (constraint->getKind() == ConstraintKind::Subtype &&
794-
kind == AllowedBindingKind::Subtypes) {
795-
result.SubtypeOf.insert(bindingTypeVar);
793+
switch (constraint->getKind()) {
794+
case ConstraintKind::Subtype:
795+
case ConstraintKind::Conversion:
796+
case ConstraintKind::ArgumentConversion:
797+
case ConstraintKind::OperatorArgumentConversion: {
798+
if (kind == AllowedBindingKind::Subtypes) {
799+
result.SubtypeOf.insert({bindingTypeVar, constraint});
800+
} else {
801+
// TODO: record this type variable as a `supertypeOf`
802+
}
803+
break;
804+
}
805+
806+
case ConstraintKind::Bind:
807+
case ConstraintKind::BindParam:
808+
case ConstraintKind::Equal: {
809+
// TODO: record this type variable as being equal to other type variable.
810+
break;
811+
}
812+
813+
default:
814+
break;
796815
}
797816

798817
return None;

0 commit comments

Comments
 (0)