Skip to content

Commit 51db014

Browse files
authored
Merge pull request swiftlang#31081 from slavapestov/fix-property-wrapper-init-diagnostics
Fix property wrapper init diagnostics
2 parents 386b622 + 4d04126 commit 51db014

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
lines changed

lib/Sema/TypeCheckPropertyWrapper.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ static VarDecl *findValueProperty(ASTContext &ctx, NominalTypeDecl *nominal,
101101
/// type.
102102
static ConstructorDecl *
103103
findSuitableWrapperInit(ASTContext &ctx, NominalTypeDecl *nominal,
104-
VarDecl *valueVar, PropertyWrapperInitKind initKind) {
104+
VarDecl *valueVar, PropertyWrapperInitKind initKind,
105+
const SmallVectorImpl<ValueDecl *> &decls) {
105106
enum class NonViableReason {
106107
Failable,
107108
ParameterTypeMismatch,
@@ -111,7 +112,6 @@ findSuitableWrapperInit(ASTContext &ctx, NominalTypeDecl *nominal,
111112
SmallVector<std::tuple<ConstructorDecl *, NonViableReason, Type>, 2>
112113
nonviable;
113114
SmallVector<ConstructorDecl *, 2> viableInitializers;
114-
SmallVector<ValueDecl *, 2> decls;
115115

116116
Identifier argumentLabel;
117117
switch (initKind) {
@@ -125,8 +125,6 @@ findSuitableWrapperInit(ASTContext &ctx, NominalTypeDecl *nominal,
125125
break;
126126
}
127127

128-
nominal->lookupQualified(nominal, DeclNameRef::createConstructor(),
129-
NL_QualifiedDefault, decls);
130128
for (const auto &decl : decls) {
131129
auto init = dyn_cast<ConstructorDecl>(decl);
132130
if (!init || init->getDeclContext() != nominal || init->isGeneric())
@@ -156,6 +154,14 @@ findSuitableWrapperInit(ASTContext &ctx, NominalTypeDecl *nominal,
156154
if (hasExtraneousParam)
157155
continue;
158156

157+
if (initKind != PropertyWrapperInitKind::Default) {
158+
if (!argumentParam)
159+
continue;
160+
161+
if (argumentParam->isInOut() || argumentParam->isVariadic())
162+
continue;
163+
}
164+
159165
// Failable initializers cannot be used.
160166
if (init->isFailable()) {
161167
nonviable.push_back(
@@ -172,12 +178,6 @@ findSuitableWrapperInit(ASTContext &ctx, NominalTypeDecl *nominal,
172178

173179
// Additional checks for initial-value and wrapped-value initializers
174180
if (initKind != PropertyWrapperInitKind::Default) {
175-
if (!argumentParam)
176-
continue;
177-
178-
if (argumentParam->isInOut() || argumentParam->isVariadic())
179-
continue;
180-
181181
auto paramType = argumentParam->getInterfaceType();
182182
if (paramType->is<ErrorType>())
183183
continue;
@@ -345,18 +345,22 @@ PropertyWrapperTypeInfoRequest::evaluate(
345345
if (!valueVar)
346346
return PropertyWrapperTypeInfo();
347347

348-
// FIXME: Remove this one
349-
(void)valueVar->getInterfaceType();
350-
348+
TypeChecker::addImplicitConstructors(nominal);
349+
350+
SmallVector<ValueDecl *, 2> decls;
351+
nominal->lookupQualified(nominal, DeclNameRef::createConstructor(),
352+
NL_QualifiedDefault, decls);
353+
351354
PropertyWrapperTypeInfo result;
352355
result.valueVar = valueVar;
353356
if (auto init = findSuitableWrapperInit(ctx, nominal, valueVar,
354-
PropertyWrapperInitKind::WrappedValue)) {
357+
PropertyWrapperInitKind::WrappedValue, decls)) {
355358
result.wrappedValueInit = PropertyWrapperTypeInfo::HasWrappedValueInit;
356359
result.isWrappedValueInitUsingEscapingAutoClosure =
357360
isEscapingAutoclosureArgument(init, ctx.Id_wrappedValue);
358361
} else if (auto init = findSuitableWrapperInit(
359-
ctx, nominal, valueVar, PropertyWrapperInitKind::InitialValue)) {
362+
ctx, nominal, valueVar, PropertyWrapperInitKind::InitialValue,
363+
decls)) {
360364
result.wrappedValueInit = PropertyWrapperTypeInfo::HasInitialValueInit;
361365
result.isWrappedValueInitUsingEscapingAutoClosure =
362366
isEscapingAutoclosureArgument(init, ctx.Id_initialValue);
@@ -376,7 +380,7 @@ PropertyWrapperTypeInfoRequest::evaluate(
376380
}
377381

378382
if (findSuitableWrapperInit(ctx, nominal, /*valueVar=*/nullptr,
379-
PropertyWrapperInitKind::Default)) {
383+
PropertyWrapperInitKind::Default, decls)) {
380384
result.defaultInit = PropertyWrapperTypeInfo::HasDefaultValueInit;
381385
}
382386

test/SILGen/Inputs/property_wrappers_multifile_other.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ public class MyClass {
77

88
@propertyWrapper
99
public struct PropertyWrapper {
10+
public init() { }
11+
1012
public var projectedValue: PropertyWrapper {
1113
get {
1214
return self

test/SILGen/property_wrappers_final.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public class MyClass {
1717

1818
@propertyWrapper
1919
public struct PropertyWrapper {
20+
public init() { }
21+
2022
public var projectedValue: PropertyWrapper {
2123
get {
2224
return self

test/decl/var/property_wrappers.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,5 +1934,10 @@ struct TestDefaultableIntWrapper {
19341934
}
19351935
}
19361936

1937-
1938-
1937+
@propertyWrapper
1938+
public struct NonVisibleImplicitInit {
1939+
// expected-error@-1 {{internal initializer 'init()' cannot have more restrictive access than its enclosing property wrapper type 'NonVisibleImplicitInit' (which is public)}}
1940+
public var wrappedValue: Bool {
1941+
return false
1942+
}
1943+
}

0 commit comments

Comments
 (0)