Skip to content

Commit dcbcd5f

Browse files
committed
[CSBindings] Coalesce ExpressibleBy{Integer, Float}Literal early
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.
1 parent 715ef50 commit dcbcd5f

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,26 @@ void ConstraintSystem::PotentialBindings::inferDefaultTypes(
418418
continue;
419419
}
420420

421+
// Let's try to coalesce integer and floating point literal protocols
422+
// if they appear together because the only possible default type that
423+
// could satisfy both requirements is `Double`.
424+
{
425+
if (protocol->isSpecificProtocol(
426+
KnownProtocolKind::ExpressibleByIntegerLiteral)) {
427+
auto *floatLiteral = CS.getASTContext().getProtocol(
428+
KnownProtocolKind::ExpressibleByFloatLiteral);
429+
if (literalProtocols.count(floatLiteral))
430+
continue;
431+
}
432+
433+
if (protocol->isSpecificProtocol(
434+
KnownProtocolKind::ExpressibleByFloatLiteral)) {
435+
auto *intLiteral = CS.getASTContext().getProtocol(
436+
KnownProtocolKind::ExpressibleByIntegerLiteral);
437+
literalProtocols.erase(intLiteral);
438+
}
439+
}
440+
421441
literalProtocols.insert(
422442
{protocol, {isDirectRequirement(constraint), false}});
423443
}
@@ -499,19 +519,6 @@ void ConstraintSystem::PotentialBindings::inferDefaultTypes(
499519
if (isUnviableForDefaulting(protocol))
500520
continue;
501521

502-
// Let's try to coalesce integer and floating point literal protocols
503-
// if they appear together because the only possible default type that
504-
// could satisfy both requirements is `Double`.
505-
if (protocol->isSpecificProtocol(
506-
KnownProtocolKind::ExpressibleByIntegerLiteral)) {
507-
auto *floatLiteral = cs.getASTContext().getProtocol(
508-
KnownProtocolKind::ExpressibleByFloatLiteral);
509-
// If `ExpressibleByFloatLiteral` is a requirement and it isn't
510-
// covered, let's skip `ExpressibleByIntegerLiteral` requirement.
511-
if (!isUnviableForDefaulting(floatLiteral))
512-
continue;
513-
}
514-
515522
auto defaultType = TypeChecker::getDefaultType(protocol, cs.DC);
516523
if (!defaultType)
517524
continue;

0 commit comments

Comments
 (0)