@@ -728,7 +728,22 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
728
728
ValueDecl *Base = nullptr ;
729
729
DeclContext *BaseDC = nullptr ;
730
730
for (auto Result : Lookup) {
731
- auto ThisBase = Result.getBaseDecl ();
731
+ // Perform an unqualified lookup for the base decl. This handles cases
732
+ // where self was rebound (e.g. `guard let self = self`) earlier in this scope.
733
+ // Only do this in closures, since implicit self isn't allowed to be rebound
734
+ // in other contexts.
735
+ ValueDecl* ThisBase = nullptr ;
736
+ if (DC->getContextKind () == DeclContextKind::AbstractClosureExpr) {
737
+ auto &ctx = DC->getASTContext ();
738
+ auto localDecl = ASTScope::lookupSingleLocalDecl (DC->getParentSourceFile (),
739
+ DeclName (ctx.Id_self ),
740
+ UDRE->getLoc ());
741
+ if (localDecl)
742
+ ThisBase = localDecl;
743
+ }
744
+
745
+ if (!ThisBase)
746
+ ThisBase = Result.getBaseDecl ();
732
747
733
748
// Track the base for member declarations.
734
749
if (ThisBase && !isa<ModuleDecl>(ThisBase)) {
@@ -763,28 +778,6 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
763
778
} else {
764
779
BaseExpr = new (Context) DeclRefExpr (Base, UDRE->getNameLoc (),
765
780
/* 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.
773
- bool isClosureImplicitSelfParameter = false ;
774
- if (DC->getContextKind () == DeclContextKind::AbstractClosureExpr)
775
- if (auto varDecl = dyn_cast<VarDecl>(Base))
776
- if (varDecl->isSelfParameter ())
777
- isClosureImplicitSelfParameter = true ;
778
-
779
- if (isClosureImplicitSelfParameter) {
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;
787
- }
788
781
}
789
782
790
783
auto isInClosureContext = [&](ValueDecl *decl) -> bool {
@@ -878,14 +871,14 @@ namespace {
878
871
// / Update a direct callee expression node that has a function reference kind
879
872
// / based on seeing a call to this callee.
880
873
template <typename E,
881
- typename = decltype (((E*)nullptr )->getFunctionRefKind ())>
874
+ typename = decltype (((E*)nullptr )->getFunctionRefKind ())>
882
875
void tryUpdateDirectCalleeImpl(E *callee, int ) {
883
876
callee->setFunctionRefKind (addingDirectCall (callee->getFunctionRefKind ()));
884
877
}
885
878
886
879
// / Version of tryUpdateDirectCalleeImpl for when the callee
887
880
// / expression type doesn't carry a reference.
888
- template <typename E>
881
+ template <typename E>
889
882
void tryUpdateDirectCalleeImpl (E *callee, ...) { }
890
883
891
884
// / The given expression is the direct callee of a call expression; mark it to
0 commit comments