@@ -401,12 +401,25 @@ void ConstraintSystem::PotentialBindings::inferDefaultTypes(
401
401
// Key is a literal protocol requirement, Value indicates whether (first)
402
402
// given protocol is a direct requirement, and (second) whether it has been
403
403
// covered by an existing binding.
404
+ bool canBeNil = false ;
404
405
llvm::SmallMapVector<ProtocolDecl *, std::pair<bool , bool >, 4 >
405
406
literalProtocols;
406
407
for (auto *constraint : Protocols) {
407
- if (constraint->getKind () == ConstraintKind::LiteralConformsTo)
408
- literalProtocols.insert ({constraint->getProtocol (),
409
- {isDirectRequirement (constraint), false }});
408
+ if (constraint->getKind () != ConstraintKind::LiteralConformsTo)
409
+ continue ;
410
+
411
+ auto *protocol = constraint->getProtocol ();
412
+
413
+ // No reason to add `ExpressibleByNilLiteral` into the set
414
+ // because it doesn't have a default type.
415
+ if (protocol->isSpecificProtocol (
416
+ KnownProtocolKind::ExpressibleByNilLiteral)) {
417
+ canBeNil = true ;
418
+ continue ;
419
+ }
420
+
421
+ literalProtocols.insert (
422
+ {protocol, {isDirectRequirement (constraint), false }});
410
423
}
411
424
412
425
for (auto &binding : Bindings) {
@@ -435,17 +448,18 @@ void ConstraintSystem::PotentialBindings::inferDefaultTypes(
435
448
if (isCovered)
436
449
continue ;
437
450
438
- // FIXME: This is a hack and it's incorrect because it depends
439
- // on ordering of the literal procotols e.g. if `ExpressibleByNilLiteral`
440
- // appears before e.g. `ExpressibleByIntegerLiteral` we'd drop
441
- // optionality although that would be incorrect.
442
451
do {
443
452
// If the type conforms to this protocol, we're covered.
444
453
if (TypeChecker::conformsToProtocol (type, protocol, cs.DC )) {
445
454
isCovered = true ;
446
455
break ;
447
456
}
448
457
458
+ // Can't unwrap optionals if there is `ExpressibleByNilLiteral`
459
+ // conformance requirement placed on the type variable.
460
+ if (canBeNil)
461
+ break ;
462
+
449
463
// If this literal protocol is not a direct requirement it
450
464
// would be possible to change optionality while inferring
451
465
// bindings for a supertype, so this hack doesn't apply.
0 commit comments