@@ -1336,30 +1336,46 @@ lookupPrecedenceGroup(const PrecedenceGroupDescriptor &descriptor) {
1336
1336
}
1337
1337
}
1338
1338
1339
+ static PrecedenceGroupDecl *lookupPrecedenceGroupForRelation (
1340
+ DeclContext *dc, PrecedenceGroupDecl::Relation rel,
1341
+ PrecedenceGroupDescriptor::PathDirection direction) {
1342
+ auto &ctx = dc->getASTContext ();
1343
+ PrecedenceGroupDescriptor desc{dc, rel.Name , rel.NameLoc , direction};
1344
+ auto result = ctx.evaluator (ValidatePrecedenceGroupRequest{desc});
1345
+ if (!result) {
1346
+ // Handle a cycle error specially. We don't want to default to an empty
1347
+ // result, as we don't want to emit an error about not finding a precedence
1348
+ // group.
1349
+ using Error = CyclicalRequestError<ValidatePrecedenceGroupRequest>;
1350
+ llvm::handleAllErrors (result.takeError (), [](const Error &E) {});
1351
+ return nullptr ;
1352
+ }
1353
+ if (!result.get ()) {
1354
+ ctx.Diags .diagnose (rel.NameLoc , diag::unknown_precedence_group, rel.Name );
1355
+ }
1356
+ return result.get ();
1357
+ }
1358
+
1339
1359
void swift::validatePrecedenceGroup (PrecedenceGroupDecl *PGD) {
1340
1360
assert (PGD && " Cannot validate a null precedence group!" );
1341
1361
if (PGD->isInvalid ())
1342
1362
return ;
1343
1363
1344
1364
auto &Diags = PGD->getASTContext ().Diags ;
1365
+ auto *dc = PGD->getDeclContext ();
1345
1366
1346
1367
// Validate the higherThan relationships.
1347
1368
bool addedHigherThan = false ;
1348
1369
for (auto &rel : PGD->getMutableHigherThan ()) {
1349
1370
if (rel.Group )
1350
1371
continue ;
1351
1372
1352
- PrecedenceGroupDescriptor desc{PGD->getDeclContext (), rel.Name , rel.NameLoc ,
1353
- PrecedenceGroupDescriptor::HigherThan};
1354
- auto group =
1355
- evaluateOrDefault (PGD->getASTContext ().evaluator ,
1356
- ValidatePrecedenceGroupRequest{desc}, nullptr );
1357
- if (group) {
1358
- rel.Group = group;
1373
+ // TODO: Requestify the lookup of a relation's group.
1374
+ rel.Group = lookupPrecedenceGroupForRelation (
1375
+ dc, rel, PrecedenceGroupDescriptor::HigherThan);
1376
+ if (rel.Group ) {
1359
1377
addedHigherThan = true ;
1360
1378
} else {
1361
- if (!lookupPrecedenceGroup (desc))
1362
- Diags.diagnose (rel.NameLoc , diag::unknown_precedence_group, rel.Name );
1363
1379
PGD->setInvalid ();
1364
1380
}
1365
1381
}
@@ -1369,24 +1385,16 @@ void swift::validatePrecedenceGroup(PrecedenceGroupDecl *PGD) {
1369
1385
if (rel.Group )
1370
1386
continue ;
1371
1387
1372
- auto dc = PGD->getDeclContext ();
1373
- PrecedenceGroupDescriptor desc{PGD->getDeclContext (), rel.Name , rel.NameLoc ,
1374
- PrecedenceGroupDescriptor::LowerThan};
1375
- auto group =
1376
- evaluateOrDefault (PGD->getASTContext ().evaluator ,
1377
- ValidatePrecedenceGroupRequest{desc}, nullptr );
1378
- bool hadError = false ;
1379
- if (group) {
1380
- rel.Group = group;
1381
- } else {
1382
- hadError = true ;
1383
- if (auto *rawGroup = lookupPrecedenceGroup (desc)) {
1384
- // We already know the lowerThan path is errant, try to use the results
1385
- // of a raw lookup to enforce the same-module restriction.
1386
- group = rawGroup;
1387
- } else {
1388
- Diags.diagnose (rel.NameLoc , diag::unknown_precedence_group, rel.Name );
1389
- }
1388
+ auto *group = lookupPrecedenceGroupForRelation (
1389
+ dc, rel, PrecedenceGroupDescriptor::LowerThan);
1390
+ rel.Group = group;
1391
+
1392
+ // If we didn't find anything, try doing a raw lookup for the group before
1393
+ // diagnosing the 'lowerThan' within the same-module restriction. This can
1394
+ // allow us to diagnose even if we have a precedence group cycle.
1395
+ if (!group) {
1396
+ group = lookupPrecedenceGroup (PrecedenceGroupDescriptor{
1397
+ dc, rel.Name , rel.NameLoc , PrecedenceGroupDescriptor::LowerThan});
1390
1398
}
1391
1399
1392
1400
if (group &&
@@ -1396,10 +1404,10 @@ void swift::validatePrecedenceGroup(PrecedenceGroupDecl *PGD) {
1396
1404
Diags.diagnose (group->getNameLoc (), diag::kind_declared_here,
1397
1405
DescriptiveDeclKind::PrecedenceGroup);
1398
1406
}
1399
- hadError = true ;
1407
+ PGD-> setInvalid () ;
1400
1408
}
1401
1409
1402
- if (hadError )
1410
+ if (!rel. Group )
1403
1411
PGD->setInvalid ();
1404
1412
}
1405
1413
@@ -1441,18 +1449,13 @@ static NominalTypeDecl *resolveSingleNominalTypeDecl(
1441
1449
}
1442
1450
1443
1451
bool swift::checkDesignatedTypes (OperatorDecl *OD,
1444
- ArrayRef<Identifier> identifiers,
1445
- ArrayRef<SourceLoc> identifierLocs,
1446
- ASTContext &ctx) {
1447
- assert (identifiers.size () == identifierLocs.size ());
1448
-
1449
- SmallVector<NominalTypeDecl *, 1 > designatedNominalTypes;
1452
+ ArrayRef<Located<Identifier>> identifiers) {
1453
+ auto &ctx = OD->getASTContext ();
1450
1454
auto *DC = OD->getDeclContext ();
1451
1455
1452
- for (auto index : indices (identifiers)) {
1453
- auto *decl = resolveSingleNominalTypeDecl (DC, identifierLocs[index],
1454
- identifiers[index], ctx);
1455
-
1456
+ SmallVector<NominalTypeDecl *, 1 > designatedNominalTypes;
1457
+ for (auto ident : identifiers) {
1458
+ auto *decl = resolveSingleNominalTypeDecl (DC, ident.Loc , ident.Item , ctx);
1456
1459
if (!decl)
1457
1460
return true ;
1458
1461
@@ -1471,63 +1474,55 @@ bool swift::checkDesignatedTypes(OperatorDecl *OD,
1471
1474
PrecedenceGroupDecl *
1472
1475
OperatorPrecedenceGroupRequest::evaluate (Evaluator &evaluator,
1473
1476
InfixOperatorDecl *IOD) const {
1477
+ auto &ctx = IOD->getASTContext ();
1478
+ auto *dc = IOD->getDeclContext ();
1479
+
1474
1480
auto enableOperatorDesignatedTypes =
1475
- IOD-> getASTContext () .TypeCheckerOpts .EnableOperatorDesignatedTypes ;
1481
+ ctx .TypeCheckerOpts .EnableOperatorDesignatedTypes ;
1476
1482
1477
- auto &Diags = IOD-> getASTContext () .Diags ;
1483
+ auto &Diags = ctx .Diags ;
1478
1484
PrecedenceGroupDecl *group = nullptr ;
1479
1485
1480
1486
auto identifiers = IOD->getIdentifiers ();
1481
- auto identifierLocs = IOD->getIdentifierLocs ();
1482
-
1483
1487
if (!identifiers.empty ()) {
1484
- group = TypeChecker::lookupPrecedenceGroup (
1485
- IOD->getDeclContext (), identifiers[0 ], identifierLocs[0 ]);
1488
+ auto name = identifiers[0 ].Item ;
1489
+ auto loc = identifiers[0 ].Loc ;
1490
+
1491
+ group = TypeChecker::lookupPrecedenceGroup (dc, name, loc);
1486
1492
1487
1493
if (group) {
1488
1494
identifiers = identifiers.slice (1 );
1489
- identifierLocs = identifierLocs.slice (1 );
1490
1495
} else {
1491
1496
// If we're either not allowing types, or we are allowing them
1492
1497
// and this identifier is not a type, emit an error as if it's
1493
1498
// a precedence group.
1494
- auto *DC = IOD->getDeclContext ();
1495
1499
if (!(enableOperatorDesignatedTypes &&
1496
- resolveSingleNominalTypeDecl (DC, identifierLocs[0 ], identifiers[0 ],
1497
- IOD->getASTContext (),
1500
+ resolveSingleNominalTypeDecl (dc, loc, name, ctx,
1498
1501
TypeResolutionFlags::SilenceErrors))) {
1499
- Diags.diagnose (identifierLocs[0 ], diag::unknown_precedence_group,
1500
- identifiers[0 ]);
1502
+ Diags.diagnose (loc, diag::unknown_precedence_group, name);
1501
1503
identifiers = identifiers.slice (1 );
1502
- identifierLocs = identifierLocs.slice (1 );
1503
1504
}
1504
1505
}
1505
1506
}
1506
1507
1507
- if (!identifiers.empty () && !enableOperatorDesignatedTypes) {
1508
- assert (!group);
1509
- Diags.diagnose (identifierLocs[0 ], diag::unknown_precedence_group,
1510
- identifiers[0 ]);
1511
- identifiers = identifiers.slice (1 );
1512
- identifierLocs = identifierLocs.slice (1 );
1513
- assert (identifiers.empty () && identifierLocs.empty ());
1514
- }
1508
+ // Unless operator designed types are enabled, the parser will ensure that
1509
+ // only one identifier is allowed in the clause, which we should have just
1510
+ // handled.
1511
+ assert (identifiers.empty () || enableOperatorDesignatedTypes);
1515
1512
1516
1513
if (!group) {
1517
- group = TypeChecker::lookupPrecedenceGroup (
1518
- IOD->getDeclContext (), IOD->getASTContext ().Id_DefaultPrecedence ,
1519
- SourceLoc ());
1514
+ group = TypeChecker::lookupPrecedenceGroup (dc, ctx.Id_DefaultPrecedence ,
1515
+ SourceLoc ());
1520
1516
}
1521
1517
1522
1518
if (!group) {
1523
1519
Diags.diagnose (IOD->getLoc (), diag::missing_builtin_precedence_group,
1524
- IOD-> getASTContext () .Id_DefaultPrecedence );
1520
+ ctx .Id_DefaultPrecedence );
1525
1521
}
1526
1522
1527
1523
auto nominalTypes = IOD->getDesignatedNominalTypes ();
1528
1524
if (nominalTypes.empty () && enableOperatorDesignatedTypes) {
1529
- if (checkDesignatedTypes (IOD, identifiers, identifierLocs,
1530
- IOD->getASTContext ())) {
1525
+ if (checkDesignatedTypes (IOD, identifiers)) {
1531
1526
IOD->setInvalid ();
1532
1527
}
1533
1528
}
0 commit comments