@@ -510,6 +510,53 @@ class ClosureConstraintGenerator
510510 }
511511 }
512512
513+ Optional<SolutionApplicationTarget>
514+ getTargetForPattern (PatternBindingDecl *patternBinding, unsigned index,
515+ Type patternType) {
516+ auto hasPropertyWrapper = [&](Pattern *pattern) -> bool {
517+ if (auto *singleVar = pattern->getSingleVar ())
518+ return singleVar->hasAttachedPropertyWrapper ();
519+ return false ;
520+ };
521+
522+ auto *pattern = patternBinding->getPattern (index);
523+ auto *init = patternBinding->getInit (index);
524+
525+ if (!init && patternBinding->isDefaultInitializable (index) &&
526+ pattern->hasStorage ()) {
527+ init = TypeChecker::buildDefaultInitializer (patternType);
528+ }
529+
530+ if (init) {
531+ return SolutionApplicationTarget::forInitialization (
532+ init, patternBinding->getDeclContext (), patternType, patternBinding,
533+ index,
534+ /* bindPatternVarsOneWay=*/ false );
535+ }
536+
537+ // If there was no initializer, there could be one from a property
538+ // wrapper which has to be pre-checked before use. This is not a
539+ // problem in top-level code because pattern bindings go through
540+ // `typeCheckExpression` which does pre-check automatically and
541+ // result builders do not allow declaring local wrapped variables.
542+ if (hasPropertyWrapper (pattern)) {
543+ auto target = SolutionApplicationTarget::forInitialization (
544+ init, patternBinding->getDeclContext (), patternType, patternBinding,
545+ index,
546+ /* bindPatternVarsOneWay=*/ false );
547+
548+ if (ConstraintSystem::preCheckTarget (
549+ target, /* replaceInvalidRefsWithErrors=*/ true ,
550+ /* LeaveCLosureBodyUnchecked=*/ false ))
551+ return None;
552+
553+ return target;
554+ }
555+
556+ return SolutionApplicationTarget::forUninitializedVar (patternBinding, index,
557+ patternType);
558+ }
559+
513560 void visitPatternBindingElement (PatternBindingDecl *patternBinding) {
514561 assert (locator->isLastElement <LocatorPathElt::PatternBindingElement>());
515562
@@ -527,28 +574,15 @@ class ClosureConstraintGenerator
527574 return ;
528575 }
529576
530- auto *pattern = patternBinding->getPattern (index);
531- auto *init = patternBinding->getInit (index);
532-
533- if (!init && patternBinding->isDefaultInitializable (index) &&
534- pattern->hasStorage ()) {
535- init = TypeChecker::buildDefaultInitializer (patternType);
536- }
537-
538- auto target = init ? SolutionApplicationTarget::forInitialization (
539- init, patternBinding->getDeclContext (),
540- patternType, patternBinding, index,
541- /* bindPatternVarsOneWay=*/ false )
542- : SolutionApplicationTarget::forUninitializedVar (
543- patternBinding, index, patternType);
544-
545- if (cs.generateConstraints (target, FreeTypeVariableBinding::Disallow)) {
577+ auto target = getTargetForPattern (patternBinding, index, patternType);
578+ if (!target ||
579+ cs.generateConstraints (*target, FreeTypeVariableBinding::Disallow)) {
546580 hadError = true ;
547581 return ;
548582 }
549583
550584 // Keep track of this binding entry.
551- cs.setSolutionApplicationTarget ({patternBinding, index}, target);
585+ cs.setSolutionApplicationTarget ({patternBinding, index}, * target);
552586 }
553587
554588 void visitDecl (Decl *decl) {
0 commit comments