Skip to content

Commit 5ff654d

Browse files
authored
Merge pull request #27995 from theblixguy/fix/SR-11684
[PropertyWrappers] Mark the property as invalid when there is a mismatch with wrappedValue type
2 parents 4023199 + d1e61a3 commit 5ff654d

File tree

6 files changed

+47
-5
lines changed

6 files changed

+47
-5
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2980,6 +2980,16 @@ bool ConstraintSystem::repairFailures(
29802980
locator);
29812981
}
29822982

2983+
// Let's not complain about argument type mismatch if we have a synthesized
2984+
// wrappedValue initializer, because we already emit a diagnostic for a
2985+
// type mismatch between the property's type and the wrappedValue type.
2986+
if (auto CE = dyn_cast<CallExpr>(loc->getAnchor())) {
2987+
if (CE->isImplicit() && !CE->getArgumentLabels().empty() &&
2988+
CE->getArgumentLabels().front() == getASTContext().Id_wrappedValue) {
2989+
break;
2990+
}
2991+
}
2992+
29832993
conversionsOrFixes.push_back(
29842994
AllowArgumentMismatch::create(*this, lhs, rhs, loc));
29852995
break;

lib/Sema/TypeCheckPropertyWrapper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ PropertyWrapperBackingPropertyTypeRequest::evaluate(
594594
if (cs.solve(nullptr, solutions) || solutions.size() != 1) {
595595
var->diagnose(diag::property_wrapper_incompatible_property,
596596
propertyType, rawType);
597+
var->setInvalid();
597598
if (auto nominalWrapper = rawType->getAnyNominal()) {
598599
nominalWrapper->diagnose(diag::property_wrapper_declared_here,
599600
nominalWrapper->getFullName());

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,6 +2344,7 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
23442344
!propertyType->isEqual(expectedPropertyType)) {
23452345
var->diagnose(diag::property_wrapper_incompatible_property,
23462346
propertyType, wrapperType);
2347+
var->setInvalid();
23472348
if (auto nominalWrapper = wrapperType->getAnyNominal()) {
23482349
nominalWrapper->diagnose(diag::property_wrapper_declared_here,
23492350
nominalWrapper->getFullName());

test/decl/var/property_wrappers.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,8 @@ struct Initialization {
244244
@WrapperWithInitialValue
245245
var y = true
246246

247-
// FIXME: For some reason this is type-checked twice, second time around solver complains about <<error type>> argument
248247
@WrapperWithInitialValue<Int>
249-
var y2 = true // expected-error{{cannot convert value of type 'Bool' to expected argument type 'Int'}}
250-
// expected-error@-1 {{cannot convert value of type '<<error type>>' to expected argument type 'Int'}}
248+
var y2 = true // expected-error{{Bool' is not convertible to 'Int}}
251249

252250
mutating func checkTypes(s: String) {
253251
x2 = s // expected-error{{cannot assign value of type 'String' to type 'Double'}}
@@ -1584,9 +1582,7 @@ extension SR_11288_P4 where Self: AnyObject { // expected-note 2 {{where 'Self'
15841582
}
15851583

15861584
struct SR_11288_S4: SR_11288_P4 {
1587-
// FIXME: We shouldn't diagnose the arg-to-param mismatch (rdar://problem/56345248)
15881585
@SR_11288_Wrapper4 var answer = 42 // expected-error 2 {{referencing type alias 'SR_11288_Wrapper4' on 'SR_11288_P4' requires that 'SR_11288_S4' be a class type}}
1589-
// expected-error @-1 {{cannot convert value of type '<<error type>>' to expected argument type 'Int'}}
15901586
}
15911587

15921588
class SR_11288_C0: SR_11288_P4 {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: not %target-swift-frontend -typecheck %s
2+
3+
@propertyWrapper struct A {
4+
var wrappedValue: Int
5+
}
6+
7+
@propertyWrapper struct B {
8+
var wrappedValue: Int
9+
}
10+
11+
struct C {
12+
@A @B var foo: Int?
13+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-frontend %s -typecheck -verify
2+
3+
@propertyWrapper
4+
struct Wrapper1 { // expected-note {{property wrapper type 'Wrapper1' declared here}}
5+
var wrappedValue: Int?
6+
}
7+
8+
class Test1 {
9+
@Wrapper1 var user: Int
10+
// expected-error@-1 {{property type 'Int' does not match that of the 'wrappedValue' property of its wrapper type 'Wrapper1'}}
11+
}
12+
13+
@propertyWrapper
14+
struct Wrapper2 { // expected-note {{property wrapper type 'Wrapper2' declared here}}
15+
var wrappedValue: Int??
16+
}
17+
18+
class Test2 {
19+
@Wrapper2 var user: Int?
20+
// expected-error@-1 {{property type 'Int?' does not match that of the 'wrappedValue' property of its wrapper type 'Wrapper2'}}
21+
}

0 commit comments

Comments
 (0)