@@ -5794,25 +5794,71 @@ void ParamDecl::setDefaultArgumentInitContext(Initializer *initContext) {
5794
5794
5795
5795
Expr *swift::findOriginalPropertyWrapperInitialValue (VarDecl *var,
5796
5796
Expr *init) {
5797
- auto attr = var->getAttachedPropertyWrappers ().front ();
5797
+ auto *PBD = var->getParentPatternBinding ();
5798
+ if (!PBD)
5799
+ return nullptr ;
5798
5800
5799
- // Direct initialization implies no original initial value.
5800
- if (attr-> getArg ())
5801
+ // If there is no '=' on the pattern, there was no initial value.
5802
+ if (PBD-> getPatternList ()[ 0 ]. getEqualLoc (). isInvalid ())
5801
5803
return nullptr ;
5802
5804
5803
- // Look through any expressions wrapping the initializer.
5804
- init = init->getSemanticsProvidingExpr ();
5805
- auto initCall = dyn_cast<CallExpr>(init);
5806
- if (!initCall)
5805
+ ASTContext &ctx = var->getASTContext ();
5806
+ auto dc = var->getInnermostDeclContext ();
5807
+ auto innermostAttr = var->getAttachedPropertyWrappers ().back ();
5808
+ auto innermostNominal = evaluateOrDefault (
5809
+ ctx.evaluator , CustomAttrNominalRequest{innermostAttr, dc}, nullptr );
5810
+ if (!innermostNominal)
5807
5811
return nullptr ;
5808
5812
5809
- auto initArg = cast<TupleExpr>(initCall->getArg ())->getElement (0 );
5810
- initArg = initArg->getSemanticsProvidingExpr ();
5811
- if (auto autoclosure = dyn_cast<AutoClosureExpr>(initArg)) {
5812
- initArg =
5813
- autoclosure->getSingleExpressionBody ()->getSemanticsProvidingExpr ();
5814
- }
5813
+ // Walker
5814
+ class Walker : public ASTWalker {
5815
+ public:
5816
+ NominalTypeDecl *innermostNominal;
5817
+ Expr *initArg = nullptr ;
5818
+
5819
+ Walker (NominalTypeDecl *innermostNominal)
5820
+ : innermostNominal(innermostNominal) { }
5821
+
5822
+ virtual std::pair<bool , Expr *> walkToExprPre (Expr *E) override {
5823
+ if (initArg)
5824
+ return { false , E };
5825
+
5826
+ if (auto call = dyn_cast<CallExpr>(E)) {
5827
+ // We're looking for an implicit call.
5828
+ if (!call->isImplicit ())
5829
+ return { true , E };
5830
+
5831
+ // ... producing a value of the same nominal type as the innermost
5832
+ // property wrapper.
5833
+ if (call->getType ()->getAnyNominal () != innermostNominal)
5834
+ return { true , E };
5835
+
5836
+ // Find the implicit initialValue argument.
5837
+ if (auto tuple = dyn_cast<TupleExpr>(call->getArg ())) {
5838
+ ASTContext &ctx = innermostNominal->getASTContext ();
5839
+ for (unsigned i : range (tuple->getNumElements ())) {
5840
+ if (tuple->getElementName (i) == ctx.Id_initialValue &&
5841
+ tuple->getElementNameLoc (i).isInvalid ()) {
5842
+ initArg = tuple->getElement (i);
5843
+ return { false , E };
5844
+ }
5845
+ }
5846
+ }
5847
+ }
5815
5848
5849
+ return { true , E };
5850
+ }
5851
+ } walker (innermostNominal);
5852
+ init->walk (walker);
5853
+
5854
+ Expr *initArg = walker.initArg ;
5855
+ if (initArg) {
5856
+ initArg = initArg->getSemanticsProvidingExpr ();
5857
+ if (auto autoclosure = dyn_cast<AutoClosureExpr>(initArg)) {
5858
+ initArg =
5859
+ autoclosure->getSingleExpressionBody ()->getSemanticsProvidingExpr ();
5860
+ }
5861
+ }
5816
5862
return initArg;
5817
5863
}
5818
5864
0 commit comments