Skip to content

Commit a8406a3

Browse files
committed
[Property Wrappers] For now, don't allow wrappedValue and projectedValue
to have dynamic Self type.
1 parent 5cb66a0 commit a8406a3

File tree

4 files changed

+42
-3
lines changed

4 files changed

+42
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4904,6 +4904,9 @@ ERROR(property_wrapper_type_requirement_not_accessible,none,
49044904
ERROR(property_wrapper_ambiguous_enclosing_self_subscript, none,
49054905
"property wrapper type %0 has multiple enclosing-self subscripts %1",
49064906
(Type, DeclName))
4907+
ERROR(property_wrapper_dynamic_self_type, none,
4908+
"property wrapper %select{wrapped value|projected value}0 cannot have "
4909+
"dynamic Self type", (bool))
49074910

49084911
ERROR(property_wrapper_attribute_not_on_property, none,
49094912
"property wrapper attribute %0 can only be applied to a property",

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2862,7 +2862,7 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) {
28622862

28632863
// If the nominal type is a property wrapper type, we can be delegating
28642864
// through a property.
2865-
if (nominal->getPropertyWrapperTypeInfo()) {
2865+
if (nominal->getAttrs().hasAttribute<PropertyWrapperAttr>()) {
28662866
// property wrappers can only be applied to variables
28672867
if (!isa<VarDecl>(D) || isa<ParamDecl>(D)) {
28682868
diagnose(attr->getLocation(),

lib/Sema/TypeCheckPropertyWrapper.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,27 @@ PropertyWrapperTypeInfoRequest::evaluate(
406406
}
407407
}
408408

409+
auto diagnoseInvalidDynamicSelf = [&]() -> bool {
410+
bool invalidDynamicSelf = false;
411+
if (result.projectedValueVar &&
412+
result.projectedValueVar->getValueInterfaceType()->is<DynamicSelfType>()) {
413+
result.projectedValueVar->diagnose(
414+
diag::property_wrapper_dynamic_self_type, /*projectedValue=*/true);
415+
invalidDynamicSelf = true;
416+
}
417+
418+
if (result.valueVar->getValueInterfaceType()->is<DynamicSelfType>()) {
419+
result.valueVar->diagnose(
420+
diag::property_wrapper_dynamic_self_type, /*projectedValue=*/false);
421+
invalidDynamicSelf = true;
422+
}
423+
424+
return invalidDynamicSelf;
425+
};
426+
427+
if (diagnoseInvalidDynamicSelf())
428+
return PropertyWrapperTypeInfo();
429+
409430
return result;
410431
}
411432

test/decl/var/property_wrappers.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,13 +818,28 @@ struct TestProjectionValuePropertyAttr {
818818
@propertyWrapper
819819
struct BrokenLazy { }
820820
// expected-error@-1{{property wrapper type 'BrokenLazy' does not contain a non-static property named 'wrappedValue'}}
821-
// expected-note@-2{{'BrokenLazy' declared here}}
822821

823822
struct S {
824-
@BrokenLazy // expected-error{{struct 'BrokenLazy' cannot be used as an attribute}}
823+
@BrokenLazy
825824
var wrappedValue: Int
826825
}
827826

827+
@propertyWrapper
828+
struct DynamicSelfStruct {
829+
var wrappedValue: Self { self } // okay
830+
var projectedValue: Self { self } // okay
831+
}
832+
833+
@propertyWrapper
834+
class DynamicSelf {
835+
var wrappedValue: Self { self } // expected-error {{property wrapper wrapped value cannot have dynamic Self type}}
836+
var projectedValue: Self { self } // expected-error {{property wrapper projected value cannot have dynamic Self type}}
837+
}
838+
839+
struct UseDynamicSelfWrapper {
840+
@DynamicSelf() var value
841+
}
842+
828843
// ---------------------------------------------------------------------------
829844
// Invalid redeclaration
830845
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)