@@ -761,26 +761,29 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
761
761
UDRE->getNameLoc (), NTD, BaseDC,
762
762
DC->mapTypeIntoContext (NTD->getInterfaceType ()));
763
763
} else {
764
- // If this is an implicit self reference, we replace the `DeclRefExpr`
765
- // with an `UnresolvedDeclRefExpr` to make the type checker take another
766
- // pass on the expr. This causes `getParentPatternStmt()` to be populated,
767
- // which is required later to validate conditions for permitting
768
- // implicit self for `[weak self]` captures.
764
+ BaseExpr = new (Context) DeclRefExpr (Base, UDRE->getNameLoc (),
765
+ /* Implicit=*/ true );
766
+
767
+ // Implicit self references default to always being `ParamDecl`s
768
+ // that reference the function or closure's `self` param.
769
+ // This isn't necessarily the case though, if `self` has been rebound
770
+ // (e.g. unwrapping a closure's `weak self` capture via `guard let self`).
771
+ // To find the actual `VarDecl` that the base refers to, we resolve the
772
+ // `DeclRefExpr` for `self` and return that instead.
769
773
bool isClosureImplicitSelfParameter = false ;
770
774
if (DC->getContextKind () == DeclContextKind::AbstractClosureExpr)
771
775
if (auto varDecl = dyn_cast<VarDecl>(Base))
772
776
if (varDecl->isSelfParameter ())
773
777
isClosureImplicitSelfParameter = true ;
774
-
778
+
775
779
if (isClosureImplicitSelfParameter) {
776
- auto selfNameRef = new DeclNameRef (Base->getBaseIdentifier ());
777
- BaseExpr = new (Context) UnresolvedDeclRefExpr (*selfNameRef,
778
- DeclRefKind::Ordinary,
779
- UDRE->getNameLoc ());
780
- BaseExpr->setImplicit ();
781
- } else {
782
- BaseExpr = new (Context) DeclRefExpr (Base, UDRE->getNameLoc (),
783
- /* Implicit=*/ true );
780
+ auto &ctx = DC->getASTContext ();
781
+ auto *unresolvedExpr = new (Context) UnresolvedDeclRefExpr (DeclNameRef (ctx.Id_self ),
782
+ DeclRefKind::Ordinary,
783
+ UDRE->getNameLoc ());
784
+ unresolvedExpr->setImplicit ();
785
+ if (auto *resolvedExpr = resolveDeclRefExpr (unresolvedExpr, DC, replaceInvalidRefsWithErrors))
786
+ BaseExpr = resolvedExpr;
784
787
}
785
788
}
786
789
0 commit comments