Skip to content

Commit eb625f7

Browse files
committed
[Sema] Allow inference of binding to type var of differing lvalue-ness…
when we have an optional type. This uncovered an error with unresolved member lookup where we allowed an unresolved value member constraint to fail if lookup failed in an optional type wrapping a type variable. This resolves SR-13357.
1 parent 5ac3e7c commit eb625f7

File tree

6 files changed

+35
-8
lines changed

6 files changed

+35
-8
lines changed

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2696,7 +2696,7 @@ namespace {
26962696
// then we're in an ambiguity tolerant mode used for diagnostic
26972697
// generation. Just leave this as an unresolved member reference.
26982698
Type resultTy = simplifyType(cs.getType(expr));
2699-
if (resultTy->getRValueType()->is<UnresolvedType>()) {
2699+
if (resultTy->hasUnresolvedType()) {
27002700
cs.setType(expr, resultTy);
27012701
return expr;
27022702
}

lib/Sema/CSBindings.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -715,8 +715,7 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
715715

716716
// Make sure we aren't trying to equate type variables with different
717717
// lvalue-binding rules.
718-
if (auto otherTypeVar =
719-
type->lookThroughAllOptionalTypes()->getAs<TypeVariableType>()) {
718+
if (auto otherTypeVar = type->getAs<TypeVariableType>()) {
720719
if (typeVar->getImpl().canBindToLValue() !=
721720
otherTypeVar->getImpl().canBindToLValue())
722721
return None;

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6590,6 +6590,14 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
65906590
baseObjTy->is<AnyMetatypeType>() &&
65916591
constraintKind == ConstraintKind::UnresolvedValueMember) {
65926592
if (auto objectType = instanceTy->getOptionalObjectType()) {
6593+
// If we don't have a wrapped type yet, we can't look through the optional
6594+
// type.
6595+
if (objectType->getAs<TypeVariableType>()) {
6596+
MemberLookupResult result;
6597+
result.OverallResult = MemberLookupResult::Unsolved;
6598+
return result;
6599+
}
6600+
65936601
if (objectType->mayHaveMembers()) {
65946602
LookupResult &optionalLookup = lookupMember(objectType, memberName);
65956603
for (auto result : optionalLookup)

test/Constraints/patterns.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,7 @@ switch staticMembers {
296296
// expected-note@-2 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
297297

298298
case .prop: break
299-
// TODO: repeated error message
300-
case .optProp: break // expected-error* {{not unwrapped}}
299+
case .optProp: break
301300

302301
case .method: break // expected-error{{member 'method' expects argument of type 'Int'}}
303302
case .method(0): break
@@ -311,9 +310,6 @@ switch staticMembers {
311310

312311
case .optMethod: break // expected-error{{member 'optMethod' expects argument of type 'Int'}}
313312
case .optMethod(0): break
314-
// expected-error@-1 {{value of optional type 'StaticMembers?' must be unwrapped to a value of type 'StaticMembers'}}
315-
// expected-note@-2 {{coalesce}}
316-
// expected-note@-3 {{force-unwrap}}
317313
}
318314

319315
_ = 0

test/expr/delayed-ident/enum.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,13 @@ e2a = .Second(5)
2525
var e2b: E2 = .Second(5)
2626
e2b = .First
2727
var e2c: E2 = .First // expected-error{{generic parameter 'T' could not be inferred}}
28+
29+
// SR-13357
30+
struct SR13357 {}
31+
extension Optional where Wrapped == SR13357 {
32+
static var sr13357: Self { .none }
33+
}
34+
35+
func f_sr13357<T>(_: T?) { }
36+
37+
f_sr13357(.sr13357)

test/expr/delayed-ident/static_var.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,17 @@ var _: HasClosure = .factoryOpt(3)
5252
// expected-note@-3 {{force-unwrap}}
5353
// FIXME: we should accept this
5454
var _: HasClosure = .factoryOpt!(4) // expected-error {{cannot infer contextual base in reference to member 'factoryOpt'}}
55+
56+
infix operator =%: ComparisonPrecedence
57+
58+
extension Optional {
59+
static func =%(lhs: Self, rhs: Self) -> Bool { return true }
60+
}
61+
62+
struct ImplicitMembers {
63+
static var optional: ImplicitMembers? = ImplicitMembers()
64+
}
65+
66+
func implicit(_ i: inout ImplicitMembers) {
67+
if i =% .optional {}
68+
}

0 commit comments

Comments
 (0)