Skip to content

Commit ea293cf

Browse files
authored
Merge pull request #31344 from hborla/property-wrapper-invalid-dynamic-self
[Property Wrappers] Don't allow wrappedValue and projectedValue to have dynamic Self type.
2 parents 771acf4 + a8406a3 commit ea293cf

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
@@ -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
@@ -2895,7 +2895,7 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) {
28952895

28962896
// If the nominal type is a property wrapper type, we can be delegating
28972897
// through a property.
2898-
if (nominal->getPropertyWrapperTypeInfo()) {
2898+
if (nominal->getAttrs().hasAttribute<PropertyWrapperAttr>()) {
28992899
// property wrappers can only be applied to variables
29002900
if (!isa<VarDecl>(D) || isa<ParamDecl>(D)) {
29012901
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)