Skip to content

Commit 643d81f

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-rebranch
2 parents 22d1090 + b7d5ea8 commit 643d81f

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,24 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
768768
return None;
769769
}
770770

771+
// If subtyping is allowed and this is a result of an implicit member chain,
772+
// let's delay binding it to an optional until its object type resolved too or
773+
// it has been determined that there is no possibility to resolve it. Otherwise
774+
// we might end up missing solutions since it's allowed to implicitly unwrap
775+
// base type of the chain but it can't be done early - type variable
776+
// representing chain's result type has a different l-valueness comparing
777+
// to generic parameter of the optional.
778+
if (kind == AllowedBindingKind::Subtypes) {
779+
auto *locator = typeVar->getImpl().getLocator();
780+
if (locator &&
781+
locator->isLastElement<LocatorPathElt::UnresolvedMemberChainResult>()) {
782+
auto objectType = type->getOptionalObjectType();
783+
if (objectType && objectType->isTypeVariableOrMember()) {
784+
result.PotentiallyIncomplete = true;
785+
}
786+
}
787+
}
788+
771789
if (type->is<InOutType>() && !typeVar->getImpl().canBindToInOut())
772790
type = LValueType::get(type->getInOutObjectType());
773791
if (type->is<LValueType>() && !typeVar->getImpl().canBindToLValue())

test/expr/delayed-ident/member_chains.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,30 @@ extension CurriedGeneric where T == Int {
344344

345345
let _: CurriedGeneric = .createInt(CurriedGeneric())()
346346
let _: CurriedGeneric = .create(CurriedGeneric())(Int.self)
347+
348+
// rdar://problem/68094328 - failed to compile unresolved member with implicit optional promotion
349+
func rdar68094328() {
350+
struct S {
351+
init(string: String) {}
352+
353+
var value: S {
354+
get { S(string: "") }
355+
}
356+
357+
func baz(str: String) -> S {
358+
S(string: str)
359+
}
360+
}
361+
362+
class C {
363+
func bar(_: S) {}
364+
}
365+
366+
func foo<T>(_: (C) -> (T) -> Void, _: T?) {}
367+
368+
func test(str: String) {
369+
foo(C.bar, .init(string: str)) // Ok
370+
foo(C.bar, .init(string: str).value) // Ok
371+
foo(C.bar, .init(string: str).baz(str: "")) // Ok
372+
}
373+
}

0 commit comments

Comments
 (0)