@@ -1287,7 +1287,12 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
1287
1287
return ;
1288
1288
}
1289
1289
1290
- // Drill through noop expressions we don't care about.
1290
+ // Stash the type of the original expression for display: the precise
1291
+ // expression we're looking for might have an intermediary, non-user-facing
1292
+ // type, such as an opened archetype.
1293
+ const Type TypeForDiag = E->getType ();
1294
+
1295
+ // Drill through expressions we don't care about.
1291
1296
auto valueE = E;
1292
1297
while (1 ) {
1293
1298
valueE = valueE->getValueProvidingExpr ();
@@ -1298,14 +1303,33 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
1298
1303
valueE = CRCE->getSubExpr ();
1299
1304
else if (auto *EE = dyn_cast<ErasureExpr>(valueE))
1300
1305
valueE = EE->getSubExpr ();
1301
- else
1302
- break ;
1306
+ else if (auto *BOE = dyn_cast<BindOptionalExpr>(valueE))
1307
+ valueE = BOE->getSubExpr ();
1308
+ else {
1309
+ // If we have an OptionalEvaluationExpr at the top level, then someone is
1310
+ // "optional chaining" and ignoring the result. Keep drilling if it
1311
+ // doesn't make sense to ignore it.
1312
+ if (auto *OEE = dyn_cast<OptionalEvaluationExpr>(valueE)) {
1313
+ if (auto *IIO = dyn_cast<InjectIntoOptionalExpr>(OEE->getSubExpr ())) {
1314
+ valueE = IIO->getSubExpr ();
1315
+ } else if (auto *C = dyn_cast<CallExpr>(OEE->getSubExpr ())) {
1316
+ valueE = C;
1317
+ } else if (auto *OE =
1318
+ dyn_cast<OpenExistentialExpr>(OEE->getSubExpr ())) {
1319
+ valueE = OE;
1320
+ } else {
1321
+ break ;
1322
+ }
1323
+ } else {
1324
+ break ;
1325
+ }
1326
+ }
1303
1327
}
1304
-
1328
+
1305
1329
// Complain about functions that aren't called.
1306
1330
// TODO: What about tuples which contain functions by-value that are
1307
1331
// dead?
1308
- if (E ->getType ()->is <AnyFunctionType>()) {
1332
+ if (valueE ->getType ()->is <AnyFunctionType>()) {
1309
1333
bool isDiscardable = false ;
1310
1334
1311
1335
// The called function could be wrapped inside a `dot_syntax_call_expr`
@@ -1322,8 +1346,9 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
1322
1346
// }
1323
1347
//
1324
1348
// So look through the DSCE and get the function being called.
1325
- auto expr =
1326
- isa<DotSyntaxCallExpr>(E) ? cast<DotSyntaxCallExpr>(E)->getFn () : E;
1349
+ auto expr = isa<DotSyntaxCallExpr>(valueE)
1350
+ ? cast<DotSyntaxCallExpr>(valueE)->getFn ()
1351
+ : valueE;
1327
1352
1328
1353
if (auto *Fn = dyn_cast<ApplyExpr>(expr)) {
1329
1354
if (auto *calledValue = Fn->getCalledValue ()) {
@@ -1369,18 +1394,6 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
1369
1394
return ;
1370
1395
}
1371
1396
1372
- // If we have an OptionalEvaluationExpr at the top level, then someone is
1373
- // "optional chaining" and ignoring the result. Produce a diagnostic if it
1374
- // doesn't make sense to ignore it.
1375
- if (auto *OEE = dyn_cast<OptionalEvaluationExpr>(valueE)) {
1376
- if (auto *IIO = dyn_cast<InjectIntoOptionalExpr>(OEE->getSubExpr ()))
1377
- return checkIgnoredExpr (IIO->getSubExpr ());
1378
- if (auto *C = dyn_cast<CallExpr>(OEE->getSubExpr ()))
1379
- return checkIgnoredExpr (C);
1380
- if (auto *OE = dyn_cast<OpenExistentialExpr>(OEE->getSubExpr ()))
1381
- return checkIgnoredExpr (OE);
1382
- }
1383
-
1384
1397
if (auto *LE = dyn_cast<LiteralExpr>(valueE)) {
1385
1398
diagnoseIgnoredLiteral (Context, LE);
1386
1399
return ;
@@ -1459,16 +1472,16 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
1459
1472
.highlight (SR1).highlight (SR2);
1460
1473
} else
1461
1474
DE.diagnose (fn->getLoc (), diag::expression_unused_result_unknown,
1462
- isa<ClosureExpr>(fn), valueE->getType ())
1463
- .highlight (SR1).highlight (SR2);
1475
+ isa<ClosureExpr>(fn), TypeForDiag)
1476
+ .highlight (SR1)
1477
+ .highlight (SR2);
1464
1478
1465
1479
return ;
1466
1480
}
1467
1481
1468
1482
// Produce a generic diagnostic.
1469
- DE.diagnose (valueE->getLoc (), diag::expression_unused_result,
1470
- valueE->getType ())
1471
- .highlight (valueE->getSourceRange ());
1483
+ DE.diagnose (valueE->getLoc (), diag::expression_unused_result, TypeForDiag)
1484
+ .highlight (valueE->getSourceRange ());
1472
1485
}
1473
1486
1474
1487
void StmtChecker::typeCheckASTNode (ASTNode &node) {
0 commit comments