mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Type checker] Eliminate the 'literalConformanceProto' state on type variables.
The 'literalConformanceProto' field of
TypeVariableType::Implementation didn't take into account equivalence
classes of type variables. Eliminate it, and either look at the actual
expressions (for optimizing constraints during constraint generation)
or the actual constraints on a given type variable (for determining
whether to include optionals in the set of potential type variable
bindings).
(cherry picked from commit 6bdd9cfae5)
This commit is contained in:
@@ -62,14 +62,24 @@ static Optional<Type> checkTypeOfBinding(ConstraintSystem &cs,
|
||||
return None;
|
||||
|
||||
// If the type is a type variable itself, don't permit the binding.
|
||||
// FIXME: This is a hack. We need to be smarter about whether there's enough
|
||||
// structure in the type to produce an interesting binding, or not.
|
||||
if (auto bindingTypeVar = type->getRValueType()->getAs<TypeVariableType>()) {
|
||||
if (isNilLiteral &&
|
||||
bindingTypeVar->getImpl().literalConformanceProto &&
|
||||
bindingTypeVar->getImpl().literalConformanceProto->isSpecificProtocol(
|
||||
KnownProtocolKind::ExpressibleByNilLiteral))
|
||||
*isNilLiteral = true;
|
||||
if (isNilLiteral) {
|
||||
*isNilLiteral = false;
|
||||
|
||||
// Look for a literal-conformance constraint on the type variable.
|
||||
SmallVector<Constraint *, 8> constraints;
|
||||
cs.getConstraintGraph().gatherConstraints(bindingTypeVar, constraints);
|
||||
for (auto constraint : constraints) {
|
||||
if (constraint->getKind() == ConstraintKind::LiteralConformsTo &&
|
||||
constraint->getProtocol()->isSpecificProtocol(
|
||||
KnownProtocolKind::ExpressibleByNilLiteral) &&
|
||||
cs.simplifyType(constraint->getFirstType())
|
||||
->isEqual(bindingTypeVar)) {
|
||||
*isNilLiteral = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
@@ -667,6 +677,7 @@ static bool shouldBindToValueType(Constraint *constraint)
|
||||
case ConstraintKind::Equal:
|
||||
case ConstraintKind::BindParam:
|
||||
case ConstraintKind::ConformsTo:
|
||||
case ConstraintKind::LiteralConformsTo:
|
||||
case ConstraintKind::CheckedCast:
|
||||
case ConstraintKind::SelfObjectOfProtocol:
|
||||
case ConstraintKind::ApplicableFunction:
|
||||
@@ -782,8 +793,19 @@ static PotentialBindings getPotentialBindings(ConstraintSystem &cs,
|
||||
result.InvolvesTypeVariables = true;
|
||||
continue;
|
||||
|
||||
case ConstraintKind::ConformsTo:
|
||||
case ConstraintKind::LiteralConformsTo:
|
||||
// If there is a 'nil' literal constraint, we might need optional
|
||||
// supertype bindings.
|
||||
if (constraint->getProtocol()->isSpecificProtocol(
|
||||
KnownProtocolKind::ExpressibleByNilLiteral))
|
||||
addOptionalSupertypeBindings = true;
|
||||
|
||||
SWIFT_FALLTHROUGH;
|
||||
|
||||
case ConstraintKind::ConformsTo:
|
||||
case ConstraintKind::SelfObjectOfProtocol: {
|
||||
// FIXME: Only for LiteralConformsTo?
|
||||
|
||||
// If there is a default literal type for this protocol, it's a
|
||||
// potential binding.
|
||||
auto defaultType = tc.getDefaultType(constraint->getProtocol(), cs.DC);
|
||||
@@ -908,13 +930,17 @@ static PotentialBindings getPotentialBindings(ConstraintSystem &cs,
|
||||
// Check whether we can perform this binding.
|
||||
// FIXME: this has a super-inefficient extraneous simplifyType() in it.
|
||||
bool isNilLiteral = false;
|
||||
if (auto boundType = checkTypeOfBinding(cs, typeVar, type, &isNilLiteral)) {
|
||||
bool *isNilLiteralPtr = nullptr;
|
||||
if (!addOptionalSupertypeBindings && kind == AllowedBindingKind::Supertypes)
|
||||
isNilLiteralPtr = &isNilLiteral;
|
||||
if (auto boundType = checkTypeOfBinding(cs, typeVar, type,
|
||||
isNilLiteralPtr)) {
|
||||
type = *boundType;
|
||||
if (type->hasTypeVariable())
|
||||
result.InvolvesTypeVariables = true;
|
||||
} else {
|
||||
// If the bound is a 'nil' literal type, add optional supertype bindings.
|
||||
if (isNilLiteral && kind == AllowedBindingKind::Supertypes) {
|
||||
if (isNilLiteral) {
|
||||
addOptionalSupertypeBindings = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user