@@ -558,6 +558,35 @@ class UseAfterTransferDiagnosticEmitter {
558558 emitRequireInstDiagnostics ();
559559 }
560560
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+
561590 void emitTypedIsolationCrossing (SILLocation loc, Type inferredType,
562591 ApplyIsolationCrossing isolationCrossing) {
563592 diagnoseError (
@@ -872,6 +901,38 @@ struct UseAfterTransferDiagnosticInferrer::AutoClosureWalker : ASTWalker {
872901 if (declRef->getDecl () == targetDecl) {
873902 // Found our target!
874903 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.
875936 foundTypeInfo.diagnosticEmitter .emitNamedIsolationCrossingError (
876937 foundTypeInfo.baseLoc , targetDecl->getBaseIdentifier (),
877938 targetDeclIsolationInfo, *isolationCrossing);
0 commit comments