Skip to content

Commit 41387e2

Browse files
authored
Merge pull request swiftlang#61074 from xedin/closure-property-wrapper-fixes-5.7
[5.7][CSClosure] Fix some aspects of property wrapper handling in closures
2 parents 86def8f + c68fdc8 commit 41387e2

File tree

3 files changed

+79
-16
lines changed

3 files changed

+79
-16
lines changed

lib/Sema/CSClosure.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class TypeVariableRefFinder : public ASTWalker {
109109
CS.setType(var, computeProjectedValueType(wrappedVar, wrapperType));
110110
} else {
111111
// _<name> is the wrapper var
112-
CS.setType(var, computeWrappedValueType(wrappedVar, wrapperType));
112+
CS.setType(var, wrapperType);
113113
}
114114

115115
return {true, expr};
@@ -498,18 +498,13 @@ class SyntacticElementConstraintGenerator
498498
init = TypeChecker::buildDefaultInitializer(patternType);
499499
}
500500

501-
if (init) {
502-
return SolutionApplicationTarget::forInitialization(
503-
init, patternBinding->getDeclContext(), patternType, patternBinding,
504-
index,
505-
/*bindPatternVarsOneWay=*/false);
506-
}
507-
508-
// If there was no initializer, there could be one from a property
509-
// wrapper which has to be pre-checked before use. This is not a
510-
// problem in top-level code because pattern bindings go through
511-
// `typeCheckExpression` which does pre-check automatically and
512-
// result builders do not allow declaring local wrapped variables.
501+
// A property wrapper initializer (either user-defined
502+
// or a synthesized one) has to be pre-checked before use.
503+
//
504+
// This is not a problem in top-level code because pattern
505+
// bindings go through `typeCheckExpression` which does
506+
// pre-check automatically and result builders do not allow
507+
// declaring local wrapped variables (yet).
513508
if (hasPropertyWrapper(pattern)) {
514509
auto target = SolutionApplicationTarget::forInitialization(
515510
init, patternBinding->getDeclContext(), patternType, patternBinding,
@@ -524,6 +519,13 @@ class SyntacticElementConstraintGenerator
524519
return target;
525520
}
526521

522+
if (init) {
523+
return SolutionApplicationTarget::forInitialization(
524+
init, patternBinding->getDeclContext(), patternType, patternBinding,
525+
index,
526+
/*bindPatternVarsOneWay=*/false);
527+
}
528+
527529
return SolutionApplicationTarget::forUninitializedVar(patternBinding, index,
528530
patternType);
529531
}

test/expr/closure/multi_statement.swift

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,3 +535,63 @@ struct Test {
535535
}
536536
}
537537
}
538+
539+
https://github.com/apple/swift/issues/61017
540+
do {
541+
@propertyWrapper
542+
struct Wrapper {
543+
var wrappedValue: Int
544+
545+
init(wrappedValue: Int) {
546+
self.wrappedValue = wrappedValue
547+
}
548+
}
549+
550+
class Test {
551+
let bar: () -> Void = {
552+
@Wrapper var wrapped = 1
553+
let wrapper: Wrapper = _wrapped // Ok
554+
}
555+
}
556+
}
557+
558+
https://github.com/apple/swift/issues/61024
559+
do {
560+
enum Baz: String {
561+
case someCase
562+
}
563+
564+
@propertyWrapper
565+
struct Wrapper {
566+
var wrappedValue: Int
567+
let argument: String
568+
569+
init(wrappedValue: Int, argument: String) { // expected-note 2 {{'init(wrappedValue:argument:)' declared here}}
570+
self.wrappedValue = wrappedValue
571+
self.argument = argument
572+
}
573+
}
574+
575+
class Foo {
576+
let ok: () -> Void = {
577+
@Wrapper(argument: Baz.someCase.rawValue) var wrapped1 = 1 // Ok
578+
@Wrapper(wrappedValue: 42, argument: Baz.someCase.rawValue) var wrapped2 // Ok
579+
@Wrapper(wrappedValue: 42, argument: Baz.someCase.rawValue) var wrapped3: Int // Ok
580+
}
581+
582+
let bad0: () -> Void = {
583+
@Wrapper var wrapped: Int
584+
// expected-error@-1 {{missing arguments for parameters 'wrappedValue', 'argument' in call}}
585+
}
586+
587+
let bad1: () -> Void = {
588+
@Wrapper var wrapped = 0
589+
// expected-error@-1 {{missing argument for parameter 'argument' in property wrapper initializer; add 'wrappedValue' and 'argument' arguments in '@Wrapper(...)'}}
590+
}
591+
592+
let bad2: () -> Void = {
593+
@Wrapper(wrappedValue: 42, argument: Baz.someCase.rawValue) var wrapped = 0
594+
// expected-error@-1 {{extra argument 'wrappedValue' in call}}
595+
}
596+
}
597+
}

validation-test/Sema/type_checker_crashers_fixed/issue59294.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class Test {
7474
if $value.returnValue() > 0 {
7575
test {
7676
return $value.returnValue() == $0 &&
77-
_value == $0
77+
_value.wrappedValue == $0
7878
}
7979
}
8080
return false
@@ -84,7 +84,7 @@ class Test {
8484
@WrapperValue var value = $0
8585

8686
test {
87-
if _value != $0 { // Ok
87+
if _value.wrappedValue != $0 { // Ok
8888
$value.printValue()
8989
}
9090
}
@@ -99,7 +99,8 @@ class Test {
9999
if true {
100100
@OuterWrapper @WrapperValue var value = $0
101101
if true {
102-
let _: Bool = _value == $0
102+
let _: OuterWrapper<WrapperValue<Bool>> = _value
103+
let _ = _value.wrappedValue.wrappedValue == $0
103104
let _: OuterWrapper<WrapperValue<Bool>> = $value
104105
let _: Bool = value
105106
}

0 commit comments

Comments
 (0)