Skip to content

Commit dcafd58

Browse files
committed
Sema: Use ASTScope::lookupSingleLocalDecl() in MissingOptionalUnwrapFailure
1 parent 6b98f8f commit dcafd58

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,12 @@ void MissingOptionalUnwrapFailure::offerForceUnwrapFixIt(
11951195
}
11961196
}
11971197

1198+
// FIXME: This walks a partially-type checked function body, which
1199+
// is not guaranteed to yield consistent results. We should come up
1200+
// with another way of performing this analysis, for example by moving
1201+
// it to a post-type checking pass in MiscDiagnostics.
11981202
class VarDeclMultipleReferencesChecker : public ASTWalker {
1203+
DeclContext *DC;
11991204
VarDecl *varDecl;
12001205
int count;
12011206

@@ -1204,11 +1209,30 @@ class VarDeclMultipleReferencesChecker : public ASTWalker {
12041209
if (DRE->getDecl() == varDecl)
12051210
++count;
12061211
}
1212+
1213+
// FIXME: We can see UnresolvedDeclRefExprs here because we have
1214+
// not yet run preCheckExpression() on the entire function body
1215+
// yet.
1216+
//
1217+
// We could consider pre-checking more eagerly.
1218+
if (auto *UDRE = dyn_cast<UnresolvedDeclRefExpr>(E)) {
1219+
auto name = UDRE->getName();
1220+
auto loc = UDRE->getLoc();
1221+
if (name.isSimpleName(varDecl->getName()) && loc.isValid()) {
1222+
auto *otherDecl =
1223+
ASTScope::lookupSingleLocalDecl(DC->getParentSourceFile(),
1224+
name.getFullName(), loc);
1225+
if (otherDecl == varDecl)
1226+
++count;
1227+
}
1228+
}
1229+
12071230
return { true, E };
12081231
}
12091232

12101233
public:
1211-
VarDeclMultipleReferencesChecker(VarDecl *varDecl) : varDecl(varDecl),count(0) {}
1234+
VarDeclMultipleReferencesChecker(DeclContext *DC, VarDecl *varDecl)
1235+
: DC(DC), varDecl(varDecl),count(0) {}
12121236
int referencesCount() { return count; }
12131237
};
12141238

@@ -1267,12 +1291,10 @@ bool MissingOptionalUnwrapFailure::diagnoseAsError() {
12671291
if (auto varDecl = dyn_cast<VarDecl>(declRef->getDecl())) {
12681292
bool singleUse = false;
12691293
AbstractFunctionDecl *AFD = nullptr;
1270-
if (auto contextDecl = varDecl->getDeclContext()->getAsDecl()) {
1271-
if ((AFD = dyn_cast<AbstractFunctionDecl>(contextDecl))) {
1272-
auto checker = VarDeclMultipleReferencesChecker(varDecl);
1273-
AFD->getBody()->walk(checker);
1274-
singleUse = checker.referencesCount() == 1;
1275-
}
1294+
if ((AFD = dyn_cast<AbstractFunctionDecl>(varDecl->getDeclContext()))) {
1295+
auto checker = VarDeclMultipleReferencesChecker(getDC(), varDecl);
1296+
AFD->getBody()->walk(checker);
1297+
singleUse = checker.referencesCount() == 1;
12761298
}
12771299

12781300
PatternBindingDecl *binding = varDecl->getParentPatternBinding();

0 commit comments

Comments
 (0)