@@ -558,6 +558,35 @@ class UseAfterTransferDiagnosticEmitter {
558
558
emitRequireInstDiagnostics ();
559
559
}
560
560
561
+ void
562
+ emitNamedIsolationCrossingError (SILLocation loc, Identifier name,
563
+ SILIsolationInfo namedValuesIsolationInfo,
564
+ ApplyIsolationCrossing isolationCrossing,
565
+ DeclName calleeDeclName,
566
+ DescriptiveDeclKind calleeDeclKind) {
567
+ // Emit the short error.
568
+ diagnoseError (loc, diag::regionbasedisolation_named_transfer_yields_race,
569
+ name)
570
+ .highlight (loc.getSourceRange ())
571
+ .limitBehaviorIf (getBehaviorLimit ());
572
+
573
+ // Then emit the note with greater context.
574
+ SmallString<64 > descriptiveKindStr;
575
+ {
576
+ if (!namedValuesIsolationInfo.isDisconnected ()) {
577
+ llvm::raw_svector_ostream os (descriptiveKindStr);
578
+ namedValuesIsolationInfo.printForDiagnostics (os);
579
+ os << ' ' ;
580
+ }
581
+ }
582
+
583
+ diagnoseNote (
584
+ loc, diag::regionbasedisolation_named_info_transfer_yields_race_callee,
585
+ name, descriptiveKindStr, isolationCrossing.getCalleeIsolation (),
586
+ calleeDeclKind, calleeDeclName, isolationCrossing.getCallerIsolation ());
587
+ emitRequireInstDiagnostics ();
588
+ }
589
+
561
590
void emitTypedIsolationCrossing (SILLocation loc, Type inferredType,
562
591
ApplyIsolationCrossing isolationCrossing) {
563
592
diagnoseError (
@@ -872,6 +901,38 @@ struct UseAfterTransferDiagnosticInferrer::AutoClosureWalker : ASTWalker {
872
901
if (declRef->getDecl () == targetDecl) {
873
902
// Found our target!
874
903
visitedCallExprDeclRefExprs.insert (declRef);
904
+
905
+ // See if we can find a valueDecl/name for our callee so we can
906
+ // emit a nicer error.
907
+ ConcreteDeclRef concreteDecl =
908
+ callExpr->getDirectCallee ()->getReferencedDecl ();
909
+
910
+ // If we do not find a direct one, see if we are calling a method
911
+ // on a nominal type.
912
+ if (!concreteDecl) {
913
+ if (auto *dot = dyn_cast<DotSyntaxCallExpr>(
914
+ callExpr->getDirectCallee ())) {
915
+ concreteDecl = dot->getSemanticFn ()->getReferencedDecl ();
916
+ }
917
+ }
918
+
919
+ if (concreteDecl) {
920
+ auto *valueDecl = concreteDecl.getDecl ();
921
+ assert (valueDecl &&
922
+ " Should be non-null if concreteDecl is valid" );
923
+ if (valueDecl->hasName ()) {
924
+ foundTypeInfo.diagnosticEmitter
925
+ .emitNamedIsolationCrossingError (
926
+ foundTypeInfo.baseLoc ,
927
+ targetDecl->getBaseIdentifier (),
928
+ targetDeclIsolationInfo, *isolationCrossing,
929
+ valueDecl->getName (),
930
+ valueDecl->getDescriptiveKind ());
931
+ return Action::Continue (expr);
932
+ }
933
+ }
934
+
935
+ // Otherwise default back to the "callee" error.
875
936
foundTypeInfo.diagnosticEmitter .emitNamedIsolationCrossingError (
876
937
foundTypeInfo.baseLoc , targetDecl->getBaseIdentifier (),
877
938
targetDeclIsolationInfo, *isolationCrossing);
0 commit comments