15
15
#include " swift/AST/ASTWalker.h"
16
16
#include " swift/AST/DiagnosticsSIL.h"
17
17
#include " swift/AST/Expr.h"
18
+ #include " swift/AST/ProtocolConformance.h"
19
+ #include " swift/AST/SourceFile.h"
18
20
#include " swift/AST/Type.h"
19
21
#include " swift/Basic/FrozenMultiMap.h"
20
22
#include " swift/Basic/ImmutablePointerSet.h"
35
37
#include " swift/SILOptimizer/PassManager/Transforms.h"
36
38
#include " swift/SILOptimizer/Utils/PartitionUtils.h"
37
39
#include " swift/SILOptimizer/Utils/VariableNameUtils.h"
40
+ #include " swift/Sema/Concurrency.h"
38
41
#include " llvm/ADT/DenseMap.h"
39
42
#include " llvm/Support/Debug.h"
40
43
@@ -55,6 +58,33 @@ using Region = PartitionPrimitives::Region;
55
58
// MARK: Utilities
56
59
// ===----------------------------------------------------------------------===//
57
60
61
+ static std::optional<DiagnosticBehavior>
62
+ getDiagnosticBehaviorLimitForValue (SILValue value) {
63
+ auto *nom = value->getType ().getNominalOrBoundGenericNominal ();
64
+ if (!nom)
65
+ return {};
66
+
67
+ auto declRef = value->getFunction ()->getDeclRef ();
68
+ if (!declRef)
69
+ return {};
70
+
71
+ auto *fromDC = declRef.getInnermostDeclContext ();
72
+ auto attributedImport = nom->findImport (fromDC);
73
+ if (!attributedImport ||
74
+ !attributedImport->options .contains (ImportFlags::Preconcurrency))
75
+ return {};
76
+
77
+ if (auto *sourceFile = fromDC->getParentSourceFile ())
78
+ sourceFile->setImportUsedPreconcurrency (*attributedImport);
79
+
80
+ if (hasExplicitSendableConformance (nom))
81
+ return DiagnosticBehavior::Warning;
82
+
83
+ return attributedImport->module .importedModule ->isConcurrencyChecked ()
84
+ ? DiagnosticBehavior::Warning
85
+ : DiagnosticBehavior::Ignore;
86
+ }
87
+
58
88
static Expr *inferArgumentExprFromApplyExpr (ApplyExpr *sourceApply,
59
89
FullApplySite fai,
60
90
const Operand *op) {
@@ -438,14 +468,19 @@ class UseAfterTransferDiagnosticEmitter {
438
468
emitUnknownPatternError ();
439
469
}
440
470
471
+ std::optional<DiagnosticBehavior> getBehaviorLimit () const {
472
+ return getDiagnosticBehaviorLimitForValue (transferOp->get ());
473
+ }
474
+
441
475
void
442
476
emitNamedIsolationCrossingError (SILLocation loc, Identifier name,
443
477
SILIsolationInfo namedValuesIsolationInfo,
444
478
ApplyIsolationCrossing isolationCrossing) {
445
479
// Emit the short error.
446
480
diagnoseError (loc, diag::regionbasedisolation_named_transfer_yields_race,
447
481
name)
448
- .highlight (loc.getSourceRange ());
482
+ .highlight (loc.getSourceRange ())
483
+ .limitBehaviorIf (getBehaviorLimit ());
449
484
450
485
// Then emit the note with greater context.
451
486
SmallString<64 > descriptiveKindStr;
@@ -466,7 +501,8 @@ class UseAfterTransferDiagnosticEmitter {
466
501
loc, diag::regionbasedisolation_transfer_yields_race_with_isolation,
467
502
inferredType, isolationCrossing.getCallerIsolation (),
468
503
isolationCrossing.getCalleeIsolation ())
469
- .highlight (loc.getSourceRange ());
504
+ .highlight (loc.getSourceRange ())
505
+ .limitBehaviorIf (getBehaviorLimit ());
470
506
emitRequireInstDiagnostics ();
471
507
}
472
508
@@ -475,7 +511,8 @@ class UseAfterTransferDiagnosticEmitter {
475
511
// Emit the short error.
476
512
diagnoseError (loc, diag::regionbasedisolation_named_transfer_yields_race,
477
513
name)
478
- .highlight (loc.getSourceRange ());
514
+ .highlight (loc.getSourceRange ())
515
+ .limitBehaviorIf (getBehaviorLimit ());
479
516
480
517
// Then emit the note with greater context.
481
518
diagnoseNote (
@@ -493,7 +530,8 @@ class UseAfterTransferDiagnosticEmitter {
493
530
diag::
494
531
regionbasedisolation_transfer_yields_race_stronglytransferred_binding,
495
532
inferredType)
496
- .highlight (loc.getSourceRange ());
533
+ .highlight (loc.getSourceRange ())
534
+ .limitBehaviorIf (getBehaviorLimit ());
497
535
emitRequireInstDiagnostics ();
498
536
}
499
537
@@ -502,7 +540,8 @@ class UseAfterTransferDiagnosticEmitter {
502
540
diagnoseError (loc,
503
541
diag::regionbasedisolation_transfer_yields_race_no_isolation,
504
542
inferredType)
505
- .highlight (loc.getSourceRange ());
543
+ .highlight (loc.getSourceRange ())
544
+ .limitBehaviorIf (getBehaviorLimit ());
506
545
emitRequireInstDiagnostics ();
507
546
}
508
547
@@ -513,7 +552,8 @@ class UseAfterTransferDiagnosticEmitter {
513
552
// Emit the short error.
514
553
diagnoseError (loc, diag::regionbasedisolation_named_transfer_yields_race,
515
554
name)
516
- .highlight (loc.getSourceRange ());
555
+ .highlight (loc.getSourceRange ())
556
+ .limitBehaviorIf (getBehaviorLimit ());
517
557
518
558
SmallString<64 > descriptiveKindStr;
519
559
{
@@ -535,13 +575,15 @@ class UseAfterTransferDiagnosticEmitter {
535
575
diagnoseError (loc, diag::regionbasedisolation_isolated_capture_yields_race,
536
576
inferredType, isolationCrossing.getCalleeIsolation (),
537
577
isolationCrossing.getCallerIsolation ())
538
- .highlight (loc.getSourceRange ());
578
+ .highlight (loc.getSourceRange ())
579
+ .limitBehaviorIf (getBehaviorLimit ());
539
580
emitRequireInstDiagnostics ();
540
581
}
541
582
542
583
void emitUnknownPatternError () {
543
584
diagnoseError (transferOp->getUser (),
544
- diag::regionbasedisolation_unknown_pattern);
585
+ diag::regionbasedisolation_unknown_pattern)
586
+ .limitBehaviorIf (getBehaviorLimit ());
545
587
}
546
588
547
589
private:
@@ -941,20 +983,26 @@ class TransferNonTransferrableDiagnosticEmitter {
941
983
return info.nonTransferrable .dyn_cast <SILInstruction *>();
942
984
}
943
985
986
+ std::optional<DiagnosticBehavior> getBehaviorLimit () const {
987
+ return getDiagnosticBehaviorLimitForValue (info.transferredOperand ->get ());
988
+ }
989
+
944
990
// / Return the isolation region info for \p getNonTransferrableValue().
945
991
SILIsolationInfo getIsolationRegionInfo () const {
946
992
return info.isolationRegionInfo ;
947
993
}
948
994
949
995
void emitUnknownPatternError () {
950
996
diagnoseError (getOperand ()->getUser (),
951
- diag::regionbasedisolation_unknown_pattern);
997
+ diag::regionbasedisolation_unknown_pattern)
998
+ .limitBehaviorIf (getBehaviorLimit ());
952
999
}
953
1000
954
1001
void emitUnknownUse (SILLocation loc) {
955
1002
// TODO: This will eventually be an unknown pattern error.
956
- diagnoseError (
957
- loc, diag::regionbasedisolation_task_or_actor_isolated_transferred);
1003
+ diagnoseError (loc,
1004
+ diag::regionbasedisolation_task_or_actor_isolated_transferred)
1005
+ .limitBehaviorIf (getBehaviorLimit ());
958
1006
}
959
1007
960
1008
void emitFunctionArgumentApply (SILLocation loc, Type type,
@@ -967,7 +1015,8 @@ class TransferNonTransferrableDiagnosticEmitter {
967
1015
diagnoseError (loc, diag::regionbasedisolation_arg_transferred,
968
1016
StringRef (descriptiveKindStr), type,
969
1017
crossing.getCalleeIsolation ())
970
- .highlight (getOperand ()->getUser ()->getLoc ().getSourceRange ());
1018
+ .highlight (getOperand ()->getUser ()->getLoc ().getSourceRange ())
1019
+ .limitBehaviorIf (getBehaviorLimit ());
971
1020
}
972
1021
973
1022
void emitNamedFunctionArgumentClosure (SILLocation loc, Identifier name,
@@ -995,13 +1044,15 @@ class TransferNonTransferrableDiagnosticEmitter {
995
1044
auto diag =
996
1045
diag::regionbasedisolation_arg_passed_to_strongly_transferred_param;
997
1046
diagnoseError (loc, diag, descriptiveKindStr, type)
998
- .highlight (getOperand ()->getUser ()->getLoc ().getSourceRange ());
1047
+ .highlight (getOperand ()->getUser ()->getLoc ().getSourceRange ())
1048
+ .limitBehaviorIf (getBehaviorLimit ());
999
1049
}
1000
1050
1001
1051
void emitNamedOnlyError (SILLocation loc, Identifier name) {
1002
1052
diagnoseError (loc, diag::regionbasedisolation_named_transfer_yields_race,
1003
1053
name)
1004
- .highlight (getOperand ()->getUser ()->getLoc ().getSourceRange ());
1054
+ .highlight (getOperand ()->getUser ()->getLoc ().getSourceRange ())
1055
+ .limitBehaviorIf (getBehaviorLimit ());
1005
1056
}
1006
1057
1007
1058
void emitNamedIsolation (SILLocation loc, Identifier name,
@@ -1176,7 +1227,7 @@ bool TransferNonTransferrableDiagnosticInferrer::run() {
1176
1227
if (!isolation) {
1177
1228
// Otherwise, emit a "we don't know error" that tells the user to file a
1178
1229
// bug.
1179
- diagnoseError (op-> getUser (), diag::regionbasedisolation_unknown_pattern );
1230
+ diagnosticEmitter. emitUnknownPatternError ( );
1180
1231
return false ;
1181
1232
}
1182
1233
assert (isolation && " Expected non-null" );
0 commit comments