Skip to content

Commit

Permalink
[CSBindings] Coalesce ExpressibleBy{Integer, Float}Literal early
Browse files Browse the repository at this point in the history
The only possible default which could satisfy both protocols is
`Double`, otherwise it has to be some custom type which conforms
to both protocols. Either way it's best to leave `ExpressibleByFloatLiteral`
in place to get to `Double` faster or make sure that custom type
conforms to it even if it would later fail `ExpressibleByIntegerLiteral`
conformance, at least that wouldn't introduce any unviable bindings.
  • Loading branch information
xedin committed Dec 17, 2020
1 parent 715ef50 commit dcbcd5f
Showing 1 changed file with 20 additions and 13 deletions.
33 changes: 20 additions & 13 deletions lib/Sema/CSBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,26 @@ void ConstraintSystem::PotentialBindings::inferDefaultTypes(
continue;
}

// Let's try to coalesce integer and floating point literal protocols
// if they appear together because the only possible default type that
// could satisfy both requirements is `Double`.
{
if (protocol->isSpecificProtocol(
KnownProtocolKind::ExpressibleByIntegerLiteral)) {
auto *floatLiteral = CS.getASTContext().getProtocol(
KnownProtocolKind::ExpressibleByFloatLiteral);
if (literalProtocols.count(floatLiteral))
continue;
}

if (protocol->isSpecificProtocol(
KnownProtocolKind::ExpressibleByFloatLiteral)) {
auto *intLiteral = CS.getASTContext().getProtocol(
KnownProtocolKind::ExpressibleByIntegerLiteral);
literalProtocols.erase(intLiteral);
}
}

literalProtocols.insert(
{protocol, {isDirectRequirement(constraint), false}});
}
Expand Down Expand Up @@ -499,19 +519,6 @@ void ConstraintSystem::PotentialBindings::inferDefaultTypes(
if (isUnviableForDefaulting(protocol))
continue;

// Let's try to coalesce integer and floating point literal protocols
// if they appear together because the only possible default type that
// could satisfy both requirements is `Double`.
if (protocol->isSpecificProtocol(
KnownProtocolKind::ExpressibleByIntegerLiteral)) {
auto *floatLiteral = cs.getASTContext().getProtocol(
KnownProtocolKind::ExpressibleByFloatLiteral);
// If `ExpressibleByFloatLiteral` is a requirement and it isn't
// covered, let's skip `ExpressibleByIntegerLiteral` requirement.
if (!isUnviableForDefaulting(floatLiteral))
continue;
}

auto defaultType = TypeChecker::getDefaultType(protocol, cs.DC);
if (!defaultType)
continue;
Expand Down

0 comments on commit dcbcd5f

Please sign in to comment.