Skip to content

Commit 95949ce

Browse files
committed
Use ASTScope::lookupUnqualified instead of TypeChecker::resolveDeclRefExpr
1 parent 9e9f7be commit 95949ce

File tree

1 file changed

+18
-25
lines changed

1 file changed

+18
-25
lines changed

lib/Sema/PreCheckExpr.cpp

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,22 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
728728
ValueDecl *Base = nullptr;
729729
DeclContext *BaseDC = nullptr;
730730
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();
732747

733748
// Track the base for member declarations.
734749
if (ThisBase && !isa<ModuleDecl>(ThisBase)) {
@@ -763,28 +778,6 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
763778
} else {
764779
BaseExpr = new (Context) DeclRefExpr(Base, UDRE->getNameLoc(),
765780
/*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-
}
788781
}
789782

790783
auto isInClosureContext = [&](ValueDecl *decl) -> bool {
@@ -878,14 +871,14 @@ namespace {
878871
/// Update a direct callee expression node that has a function reference kind
879872
/// based on seeing a call to this callee.
880873
template<typename E,
881-
typename = decltype(((E*)nullptr)->getFunctionRefKind())>
874+
typename = decltype(((E*)nullptr)->getFunctionRefKind())>
882875
void tryUpdateDirectCalleeImpl(E *callee, int) {
883876
callee->setFunctionRefKind(addingDirectCall(callee->getFunctionRefKind()));
884877
}
885878

886879
/// Version of tryUpdateDirectCalleeImpl for when the callee
887880
/// expression type doesn't carry a reference.
888-
template<typename E>
881+
template<typename E>
889882
void tryUpdateDirectCalleeImpl(E *callee, ...) { }
890883

891884
/// The given expression is the direct callee of a call expression; mark it to

0 commit comments

Comments
 (0)