Skip to content

Commit cf13e29

Browse files
committed
[CSBindings] Account for literal bindings when checking "subtype of existential" property
It's important to know whether a binding set has all of its bindings as subtypes of some existential type(s), type variables like that should be delayed. Incremental binding inference introduced a bug into computation of this property by checking only directly inferable bindings, but it's also important to check that there are no literal requirements that can produce bindings, because that would mean that type variable can never be just a subtype of existential type(s). Resolves: rdar://77570994
1 parent 5925cb2 commit cf13e29

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

include/swift/Sema/CSBindings.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,13 @@ class BindingSet {
391391
if (Bindings.empty())
392392
return false;
393393

394+
// Literal requirements always result in a subtype/supertype
395+
// relationship to a concrete type.
396+
if (llvm::any_of(Literals, [](const auto &literal) {
397+
return literal.second.viableAsBinding();
398+
}))
399+
return false;
400+
394401
return llvm::all_of(Bindings, [](const PotentialBinding &binding) {
395402
return binding.BindingType->isExistentialType() &&
396403
binding.Kind == AllowedBindingKind::Subtypes;

test/Constraints/protocols.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,3 +492,30 @@ func test_arg_conformance_with_conditional_reqs(i: Int) {
492492
let _: Int?? = simple(overloaded_result())
493493
let _: Int?? = overloaded(overloaded_result())
494494
}
495+
496+
// rdar://77570994 - regression in type unification for literal collections
497+
498+
protocol Elt {
499+
}
500+
501+
extension Int : Elt {}
502+
extension Int64 : Elt {}
503+
extension Dictionary : Elt where Key == String, Value: Elt {}
504+
505+
struct Object {}
506+
507+
extension Object : ExpressibleByDictionaryLiteral {
508+
init(dictionaryLiteral elements: (String, Elt)...) {
509+
}
510+
}
511+
512+
enum E {
513+
case test(cond: Bool, v: Int64)
514+
515+
var test_prop: Object {
516+
switch self {
517+
case let .test(cond, v):
518+
return ["obj": ["a": v, "b": cond ? 0 : 42]] // Ok
519+
}
520+
}
521+
}

0 commit comments

Comments
 (0)