Skip to content

Commit bf72a8e

Browse files
authored
Merge pull request #31427 from hborla/5.3-property-wrapper-invalid-dynamic-self
[5.3][Property Wrappers] For now, don't allow wrappedValue and projectedValue to have dynamic Self type.
2 parents 54b75be + 2880e6d commit bf72a8e

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

include/swift/AST/DiagnosticsSema.def

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

49064909
ERROR(property_wrapper_attribute_not_on_property, none,
49074910
"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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,23 @@ PropertyWrapperTypeInfoRequest::evaluate(
406406
}
407407
}
408408

409+
bool hasInvalidDynamicSelf = false;
410+
if (result.projectedValueVar &&
411+
result.projectedValueVar->getValueInterfaceType()->hasDynamicSelfType()) {
412+
result.projectedValueVar->diagnose(
413+
diag::property_wrapper_dynamic_self_type, /*projectedValue=*/true);
414+
hasInvalidDynamicSelf = true;
415+
}
416+
417+
if (result.valueVar->getValueInterfaceType()->hasDynamicSelfType()) {
418+
result.valueVar->diagnose(
419+
diag::property_wrapper_dynamic_self_type, /*projectedValue=*/false);
420+
hasInvalidDynamicSelf = true;
421+
}
422+
423+
if (hasInvalidDynamicSelf)
424+
return PropertyWrapperTypeInfo();
425+
409426
return result;
410427
}
411428

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)