@@ -1351,20 +1351,41 @@ namespace {
1351
1351
Type visitDeclRefExpr (DeclRefExpr *E) {
1352
1352
auto locator = CS.getConstraintLocator (E);
1353
1353
1354
+ auto invalidateReference = [&]() -> Type {
1355
+ auto *hole = CS.createTypeVariable (locator, TVO_CanBindToHole);
1356
+ (void )CS.recordFix (AllowRefToInvalidDecl::create (CS, locator));
1357
+ CS.setType (E, hole);
1358
+ return hole;
1359
+ };
1360
+
1354
1361
Type knownType;
1355
1362
if (auto *VD = dyn_cast<VarDecl>(E->getDecl ())) {
1356
1363
knownType = CS.getTypeIfAvailable (VD);
1357
1364
if (!knownType)
1358
1365
knownType = CS.getVarType (VD);
1359
1366
1360
1367
if (knownType) {
1368
+ // An out-of-scope type variable(s) could appear the type of
1369
+ // a declaration only in diagnostic mode when invalid variable
1370
+ // declaration is recursively referenced inside of a multi-statement
1371
+ // closure located somewhere within its initializer e.g.:
1372
+ // `let x = [<call>] { ... print(x) }`. It happens because the
1373
+ // variable assumes the result type of its initializer unless
1374
+ // its specified explicitly.
1375
+ if (isa<ClosureExpr>(CurDC) && knownType->hasTypeVariable ()) {
1376
+ if (knownType.findIf ([&](Type type) {
1377
+ auto *typeVar = type->getAs <TypeVariableType>();
1378
+ if (!typeVar || CS.getFixedType (typeVar))
1379
+ return false ;
1380
+
1381
+ return !CS.isActiveTypeVariable (typeVar);
1382
+ }))
1383
+ return invalidateReference ();
1384
+ }
1385
+
1361
1386
// If the known type has an error, bail out.
1362
1387
if (knownType->hasError ()) {
1363
- auto *hole = CS.createTypeVariable (locator, TVO_CanBindToHole);
1364
- (void )CS.recordFix (AllowRefToInvalidDecl::create (CS, locator));
1365
- if (!CS.hasType (E))
1366
- CS.setType (E, hole);
1367
- return hole;
1388
+ return invalidateReference ();
1368
1389
}
1369
1390
1370
1391
if (!knownType->hasPlaceholder ()) {
@@ -1381,10 +1402,7 @@ namespace {
1381
1402
// (in getTypeOfReference) so we can match non-error param types.
1382
1403
if (!knownType && E->getDecl ()->isInvalid () &&
1383
1404
!CS.isForCodeCompletion ()) {
1384
- auto *hole = CS.createTypeVariable (locator, TVO_CanBindToHole);
1385
- (void )CS.recordFix (AllowRefToInvalidDecl::create (CS, locator));
1386
- CS.setType (E, hole);
1387
- return hole;
1405
+ return invalidateReference ();
1388
1406
}
1389
1407
1390
1408
// Create an overload choice referencing this declaration and immediately
0 commit comments