@@ -481,11 +481,18 @@ static bool findNonMembers(ArrayRef<LookupResultEntry> lookupResults,
481
481
// / returning the resultant expression. Context is the DeclContext used
482
482
// / for the lookup.
483
483
Expr *TypeChecker::resolveDeclRefExpr (UnresolvedDeclRefExpr *UDRE,
484
- DeclContext *DC) {
484
+ DeclContext *DC,
485
+ bool replaceInvalidRefsWithErrors) {
485
486
// Process UnresolvedDeclRefExpr by doing an unqualified lookup.
486
487
DeclNameRef Name = UDRE->getName ();
487
488
SourceLoc Loc = UDRE->getLoc ();
488
489
490
+ auto errorResult = [&]() -> Expr * {
491
+ if (replaceInvalidRefsWithErrors)
492
+ return new (DC->getASTContext ()) ErrorExpr (UDRE->getSourceRange ());
493
+ return UDRE;
494
+ };
495
+
489
496
// Perform standard value name lookup.
490
497
NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
491
498
if (isa<AbstractFunctionDecl>(DC))
@@ -506,7 +513,7 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
506
513
if (diagnoseRangeOperatorMisspell (Context.Diags , UDRE) ||
507
514
diagnoseIncDecOperator (Context.Diags , UDRE) ||
508
515
diagnoseOperatorJuxtaposition (UDRE, DC)) {
509
- return new (Context) ErrorExpr (UDRE-> getSourceRange () );
516
+ return errorResult ( );
510
517
}
511
518
512
519
// Try ignoring access control.
@@ -531,7 +538,7 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
531
538
532
539
// Don't try to recover here; we'll get more access-related diagnostics
533
540
// downstream if the type of the inaccessible decl is also inaccessible.
534
- return new (Context) ErrorExpr (UDRE-> getSourceRange () );
541
+ return errorResult ( );
535
542
}
536
543
537
544
// TODO: Name will be a compound name if it was written explicitly as
@@ -625,7 +632,7 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
625
632
// TODO: consider recovering from here. We may want some way to suppress
626
633
// downstream diagnostics, though.
627
634
628
- return new (Context) ErrorExpr (UDRE-> getSourceRange () );
635
+ return errorResult ( );
629
636
}
630
637
631
638
// FIXME: Need to refactor the way we build an AST node from a lookup result!
@@ -916,6 +923,10 @@ namespace {
916
923
917
924
Expr *ParentExpr;
918
925
926
+ // / Indicates whether pre-check is allowed to insert
927
+ // / implicit `ErrorExpr` in place of invalid references.
928
+ bool UseErrorExprs;
929
+
919
930
// / A stack of expressions being walked, used to determine where to
920
931
// / insert RebindSelfInConstructorExpr nodes.
921
932
llvm::SmallVector<Expr *, 8 > ExprStack;
@@ -1055,8 +1066,10 @@ namespace {
1055
1066
}
1056
1067
1057
1068
public:
1058
- PreCheckExpression (DeclContext *dc, Expr *parent)
1059
- : Ctx(dc->getASTContext ()), DC(dc), ParentExpr(parent) {}
1069
+ PreCheckExpression (DeclContext *dc, Expr *parent,
1070
+ bool replaceInvalidRefsWithErrors)
1071
+ : Ctx(dc->getASTContext ()), DC(dc), ParentExpr(parent),
1072
+ UseErrorExprs(replaceInvalidRefsWithErrors) {}
1060
1073
1061
1074
ASTContext &getASTContext () const { return Ctx; }
1062
1075
@@ -1122,7 +1135,8 @@ namespace {
1122
1135
if (auto unresolved = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
1123
1136
TypeChecker::checkForForbiddenPrefix (
1124
1137
getASTContext (), unresolved->getName ().getBaseName ());
1125
- return finish (true , TypeChecker::resolveDeclRefExpr (unresolved, DC));
1138
+ return finish (true , TypeChecker::resolveDeclRefExpr (unresolved, DC,
1139
+ UseErrorExprs));
1126
1140
}
1127
1141
1128
1142
// Let's try to figure out if `InOutExpr` is out of place early
@@ -1979,8 +1993,9 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
1979
1993
1980
1994
// / Pre-check the expression, validating any types that occur in the
1981
1995
// / expression and folding sequence expressions.
1982
- bool ConstraintSystem::preCheckExpression (Expr *&expr, DeclContext *dc) {
1983
- PreCheckExpression preCheck (dc, expr);
1996
+ bool ConstraintSystem::preCheckExpression (Expr *&expr, DeclContext *dc,
1997
+ bool replaceInvalidRefsWithErrors) {
1998
+ PreCheckExpression preCheck (dc, expr, replaceInvalidRefsWithErrors);
1984
1999
// Perform the pre-check.
1985
2000
if (auto result = expr->walk (preCheck)) {
1986
2001
expr = result;
@@ -2107,7 +2122,8 @@ TypeChecker::typeCheckExpression(
2107
2122
2108
2123
// First, pre-check the expression, validating any types that occur in the
2109
2124
// expression and folding sequence expressions.
2110
- if (ConstraintSystem::preCheckExpression (expr, dc)) {
2125
+ if (ConstraintSystem::preCheckExpression (
2126
+ expr, dc, /* replaceInvalidRefsWithErrors=*/ true )) {
2111
2127
target.setExpr (expr);
2112
2128
return None;
2113
2129
}
@@ -2336,13 +2352,15 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
2336
2352
2337
2353
// Precheck the sequence.
2338
2354
Expr *sequence = stmt->getSequence ();
2339
- if (ConstraintSystem::preCheckExpression (sequence, dc))
2355
+ if (ConstraintSystem::preCheckExpression (
2356
+ sequence, dc, /* replaceInvalidRefsWithErrors=*/ true ))
2340
2357
return failed ();
2341
2358
stmt->setSequence (sequence);
2342
2359
2343
2360
// Precheck the filtering condition.
2344
2361
if (Expr *whereExpr = stmt->getWhere ()) {
2345
- if (ConstraintSystem::preCheckExpression (whereExpr, dc))
2362
+ if (ConstraintSystem::preCheckExpression (
2363
+ whereExpr, dc, /* replaceInvalidRefsWithErrors=*/ true ))
2346
2364
return failed ();
2347
2365
2348
2366
stmt->setWhere (whereExpr);
0 commit comments