@@ -393,29 +393,28 @@ static bool isMemberChainTail(Expr *expr, Expr *parent, MemberChainKind kind) {
393393}
394394
395395static bool isValidForwardReference (ValueDecl *D, DeclContext *DC,
396- ValueDecl **localDeclAfterUse) {
397- *localDeclAfterUse = nullptr ;
398-
399- // References to variables injected by lldb are always valid.
400- if (isa<VarDecl>(D) && cast<VarDecl>(D)->isDebuggerVar ())
396+ ValueDecl *&localDeclAfterUse) {
397+ // Only VarDecls require declaration before use.
398+ auto *VD = dyn_cast<VarDecl>(D);
399+ if (!VD)
401400 return true ;
402401
403- // If we find something in the current context, it must be a forward
404- // reference, because otherwise if it was in scope, it would have
405- // been returned by the call to ASTScope::lookupLocalDecls() above.
406- if (D->getDeclContext ()->isLocalContext ()) {
407- do {
408- if (D->getDeclContext () == DC) {
409- *localDeclAfterUse = D;
410- return false ;
411- }
402+ // Non-local and variables injected by lldb are always valid.
403+ auto *varDC = VD->getDeclContext ();
404+ if (!varDC->isLocalContext () || VD->isDebuggerVar ())
405+ return true ;
412406
413- // If we're inside of a 'defer' context, walk up to the parent
414- // and check again. We don't want 'defer' bodies to forward
415- // reference bindings in the immediate outer scope.
416- } while (isa<FuncDecl>(DC) &&
417- cast<FuncDecl>(DC)->isDeferBody () &&
418- (DC = DC->getParent ()));
407+ while (true ) {
408+ if (varDC == DC) {
409+ localDeclAfterUse = VD;
410+ return false ;
411+ }
412+ if (isa<AbstractClosureExpr>(DC) ||
413+ (isa<FuncDecl>(DC) && cast<FuncDecl>(DC)->isDeferBody ())) {
414+ DC = DC->getParent ();
415+ continue ;
416+ }
417+ break ;
419418 }
420419 return true ;
421420}
@@ -587,12 +586,11 @@ static Expr *resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *DC,
587586 Lookup = TypeChecker::lookupUnqualified (DC, LookupName, Loc, lookupOptions);
588587
589588 ValueDecl *localDeclAfterUse = nullptr ;
590- AllDeclRefs =
591- findNonMembers (Lookup.innerResults (), UDRE->getRefKind (),
592- /* breakOnMember=*/ true , ResultValues,
593- [&](ValueDecl *D) {
594- return isValidForwardReference (D, DC, &localDeclAfterUse);
595- });
589+ AllDeclRefs = findNonMembers (
590+ Lookup.innerResults (), UDRE->getRefKind (),
591+ /* breakOnMember=*/ true , ResultValues, [&](ValueDecl *D) {
592+ return isValidForwardReference (D, DC, localDeclAfterUse);
593+ });
596594
597595 // If local declaration after use is found, check outer results for
598596 // better matching candidates.
@@ -609,12 +607,11 @@ static Expr *resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *DC,
609607 Lookup.shiftDownResults ();
610608 ResultValues.clear ();
611609 localDeclAfterUse = nullptr ;
612- AllDeclRefs =
613- findNonMembers (Lookup.innerResults (), UDRE->getRefKind (),
614- /* breakOnMember=*/ true , ResultValues,
615- [&](ValueDecl *D) {
616- return isValidForwardReference (D, DC, &localDeclAfterUse);
617- });
610+ AllDeclRefs = findNonMembers (
611+ Lookup.innerResults (), UDRE->getRefKind (),
612+ /* breakOnMember=*/ true , ResultValues, [&](ValueDecl *D) {
613+ return isValidForwardReference (D, DC, localDeclAfterUse);
614+ });
618615 }
619616 }
620617 }
0 commit comments