Skip to content

Commit e865b31

Browse files
authored
Merge pull request #25380 from DougGregor/property-wrapper-misc-fixes-5.1
Property wrapper misc fixes 5.1
2 parents d61205b + 20b4434 commit e865b31

File tree

7 files changed

+81
-15
lines changed

7 files changed

+81
-15
lines changed

lib/AST/Decl.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5368,9 +5368,6 @@ PropertyWrapperTypeInfo VarDecl::getAttachedPropertyWrapperTypeInfo() const {
53685368

53695369
Type VarDecl::getAttachedPropertyWrapperType() const {
53705370
auto &ctx = getASTContext();
5371-
if (!ctx.getLazyResolver())
5372-
return nullptr;
5373-
53745371
auto mutableThis = const_cast<VarDecl *>(this);
53755372
return evaluateOrDefault(ctx.evaluator,
53765373
AttachedPropertyWrapperTypeRequest{mutableThis},
@@ -5379,9 +5376,6 @@ Type VarDecl::getAttachedPropertyWrapperType() const {
53795376

53805377
Type VarDecl::getPropertyWrapperBackingPropertyType() const {
53815378
ASTContext &ctx = getASTContext();
5382-
if (!ctx.getLazyResolver())
5383-
return nullptr;
5384-
53855379
auto mutableThis = const_cast<VarDecl *>(this);
53865380
return evaluateOrDefault(
53875381
ctx.evaluator, PropertyWrapperBackingPropertyTypeRequest{mutableThis},
@@ -5391,9 +5385,6 @@ Type VarDecl::getPropertyWrapperBackingPropertyType() const {
53915385
PropertyWrapperBackingPropertyInfo
53925386
VarDecl::getPropertyWrapperBackingPropertyInfo() const {
53935387
auto &ctx = getASTContext();
5394-
if (!ctx.getLazyResolver())
5395-
return PropertyWrapperBackingPropertyInfo();
5396-
53975388
auto mutableThis = const_cast<VarDecl *>(this);
53985389
return evaluateOrDefault(
53995390
ctx.evaluator,

lib/AST/TypeCheckRequests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ void PropertyWrapperBackingPropertyTypeRequest::noteCycleStep(
573573
DiagnosticEngine &diags) const {
574574
std::get<0>(getStorage())->diagnose(diag::circular_reference_through);
575575
}
576+
576577
bool PropertyWrapperBackingPropertyInfoRequest::isCached() const {
577578
auto var = std::get<0>(getStorage());
578579
return !var->getAttrs().isEmpty();

lib/Sema/CodeSynthesis.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,13 +1581,34 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
15811581
auto dc = var->getDeclContext();
15821582
Type storageInterfaceType = wrapperType;
15831583

1584-
Type storageType =
1585-
var->getDeclContext()->mapTypeIntoContext(storageInterfaceType);
1584+
Type storageType = dc->mapTypeIntoContext(storageInterfaceType);
15861585
if (!storageType) {
15871586
storageType = ErrorType::get(ctx);
15881587
isInvalid = true;
15891588
}
15901589

1590+
// Make sure that the property type matches the value of the
1591+
// wrapper type.
1592+
if (!storageType->hasError()) {
1593+
Type expectedPropertyType =
1594+
storageType->getTypeOfMember(
1595+
dc->getParentModule(),
1596+
wrapperInfo.valueVar,
1597+
wrapperInfo.valueVar->getValueInterfaceType());
1598+
Type propertyType =
1599+
dc->mapTypeIntoContext(var->getValueInterfaceType());
1600+
if (!expectedPropertyType->hasError() &&
1601+
!propertyType->hasError() &&
1602+
!propertyType->isEqual(expectedPropertyType)) {
1603+
var->diagnose(diag::property_wrapper_incompatible_property,
1604+
propertyType, wrapperType);
1605+
if (auto nominalWrapper = wrapperType->getAnyNominal()) {
1606+
nominalWrapper->diagnose(diag::property_wrapper_declared_here,
1607+
nominalWrapper->getFullName());
1608+
}
1609+
}
1610+
}
1611+
15911612
// Create the backing storage property and note it in the cache.
15921613
VarDecl *backingVar = new (ctx) VarDecl(/*IsStatic=*/var->isStatic(),
15931614
VarDecl::Specifier::Var,

lib/Sema/TypeCheckPropertyWrapper.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,15 @@ AttachedPropertyWrapperTypeRequest::evaluate(Evaluator &evaluator,
371371
if (!customAttr)
372372
return Type();
373373

374+
ASTContext &ctx = var->getASTContext();
375+
if (!ctx.getLazyResolver())
376+
return nullptr;
377+
374378
auto resolution =
375379
TypeResolution::forContextual(var->getDeclContext());
376380
TypeResolutionOptions options(TypeResolverContext::PatternBindingDecl);
377381
options |= TypeResolutionFlags::AllowUnboundGenerics;
378382

379-
ASTContext &ctx = var->getASTContext();
380383
auto &tc = *static_cast<TypeChecker *>(ctx.getLazyResolver());
381384
if (tc.validateType(customAttr->getTypeLoc(), resolution, options))
382385
return ErrorType::get(ctx);
@@ -409,10 +412,13 @@ PropertyWrapperBackingPropertyTypeRequest::evaluate(
409412
if (!binding)
410413
return Type();
411414

415+
ASTContext &ctx = var->getASTContext();
416+
if (!ctx.getLazyResolver())
417+
return Type();
418+
412419
// If there's an initializer of some sort, checking it will determine the
413420
// property wrapper type.
414421
unsigned index = binding->getPatternEntryIndexForVarDecl(var);
415-
ASTContext &ctx = var->getASTContext();
416422
TypeChecker &tc = *static_cast<TypeChecker *>(ctx.getLazyResolver());
417423
if (binding->isInitialized(index)) {
418424
tc.validateDecl(var);

test/Serialization/Inputs/def_property_wrappers.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,32 @@ public struct SomeWrapper<T> {
1010
public struct HasWrappers {
1111
@SomeWrapper public var x: Int = 17
1212
}
13+
14+
// SR-10844
15+
@_propertyWrapper
16+
class A<T: Equatable> {
17+
18+
private var _value: T
19+
20+
var value: T {
21+
get { _value }
22+
set { _value = newValue }
23+
}
24+
25+
init(initialValue: T) {
26+
_value = initialValue
27+
}
28+
}
29+
30+
@_propertyWrapper
31+
class B: A<Double> {
32+
override var value: Double {
33+
get { super.value }
34+
set { super.value = newValue }
35+
}
36+
}
37+
38+
class Holder {
39+
// @A var b = 10.0 // ok
40+
@B var b = 10.0 // crash in test target
41+
}

test/Serialization/property_wrappers.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_property_wrappers.swift
2+
// RUN: %empty-directory(%t-scratch)
3+
// RUN: %target-swift-frontend -emit-module -o %t-scratch/def_property_wrappers~partial.swiftmodule -primary-file %S/Inputs/def_property_wrappers.swift -module-name def_property_wrappers -enable-testing
4+
// RUN: %target-swift-frontend -merge-modules -emit-module -parse-as-library -sil-merge-partial-modules -disable-diagnostic-passes -disable-sil-perf-optzns -enable-testing %t-scratch/def_property_wrappers~partial.swiftmodule -module-name def_property_wrappers -o %t/def_property_wrappers.swiftmodule
35
// RUN: %target-swift-frontend -typecheck -I%t -verify %s -verify-ignore-unknown
46

5-
import def_property_wrappers
7+
@testable import def_property_wrappers
8+
9+
// SR-10844
10+
func testSR10844() {
11+
let holder = Holder()
12+
holder.b = 100
13+
}
614

715
func useWrappers(hd: HasWrappers) {
816
// Access the original properties

test/decl/var/property_wrappers.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,3 +758,13 @@ struct UsesWrapperRequiringP {
758758
// expected-error@-2{{expected declaration}}
759759
// expected-error@-3{{type annotation missing in pattern}}
760760
}
761+
762+
// SR-10899 / rdar://problem/51588022
763+
@_propertyWrapper
764+
struct SR_10899_Wrapper { // expected-note{{property wrapper type 'SR_10899_Wrapper' declared here}}
765+
var value: String { "hi" }
766+
}
767+
768+
struct SR_10899_Usage {
769+
@SR_10899_Wrapper var thing: Bool // expected-error{{property type 'Bool' does not match that of the 'value' property of its wrapper type 'SR_10899_Wrapper'}}
770+
}

0 commit comments

Comments
 (0)