@@ -491,10 +491,10 @@ class UseAfterTransferDiagnosticEmitter {
491
491
emitUnknownPatternError ();
492
492
}
493
493
494
- void emitNamedIsolationCrossingError (SILLocation loc, Identifier name,
495
- SILIsolationInfo namesIsolationInfo ,
496
- ApplyIsolationCrossing isolationCrossing ,
497
- SILLocation variableDefinedLoc ) {
494
+ void
495
+ emitNamedIsolationCrossingError (SILLocation loc, Identifier name ,
496
+ SILIsolationInfo namedValuesIsolationInfo ,
497
+ ApplyIsolationCrossing isolationCrossing ) {
498
498
// Emit the short error.
499
499
diagnoseError (loc, diag::regionbasedisolation_named_transfer_yields_race,
500
500
name)
@@ -504,7 +504,7 @@ class UseAfterTransferDiagnosticEmitter {
504
504
SmallString<64 > descriptiveKindStr;
505
505
{
506
506
llvm::raw_svector_ostream os (descriptiveKindStr);
507
- namesIsolationInfo .printForDiagnostics (os);
507
+ namedValuesIsolationInfo .printForDiagnostics (os);
508
508
}
509
509
diagnoseNote (
510
510
loc, diag::regionbasedisolation_named_info_transfer_yields_race, name,
@@ -523,7 +523,24 @@ class UseAfterTransferDiagnosticEmitter {
523
523
emitRequireInstDiagnostics ();
524
524
}
525
525
526
- void emitUseOfStronglyTransferredValue (SILLocation loc, Type inferredType) {
526
+ void emitNamedUseOfStronglyTransferredValue (SILLocation loc,
527
+ Identifier name) {
528
+ // Emit the short error.
529
+ diagnoseError (loc, diag::regionbasedisolation_named_transfer_yields_race,
530
+ name)
531
+ .highlight (loc.getSourceRange ());
532
+
533
+ // Then emit the note with greater context.
534
+ diagnoseNote (
535
+ loc, diag::regionbasedisolation_named_stronglytransferred_binding, name)
536
+ .highlight (loc.getSourceRange ());
537
+
538
+ // Finally the require points.
539
+ emitRequireInstDiagnostics ();
540
+ }
541
+
542
+ void emitTypedUseOfStronglyTransferredValue (SILLocation loc,
543
+ Type inferredType) {
527
544
diagnoseError (
528
545
loc,
529
546
diag::
@@ -542,6 +559,29 @@ class UseAfterTransferDiagnosticEmitter {
542
559
emitRequireInstDiagnostics ();
543
560
}
544
561
562
+ void emitNamedIsolationCrossingDueToCapture (
563
+ SILLocation loc, Identifier name,
564
+ SILIsolationInfo namedValuesIsolationInfo,
565
+ ApplyIsolationCrossing isolationCrossing) {
566
+ // Emit the short error.
567
+ diagnoseError (loc, diag::regionbasedisolation_named_transfer_yields_race,
568
+ name)
569
+ .highlight (loc.getSourceRange ());
570
+
571
+ SmallString<64 > descriptiveKindStr;
572
+ {
573
+ llvm::raw_svector_ostream os (descriptiveKindStr);
574
+ namedValuesIsolationInfo.printForDiagnostics (os);
575
+ }
576
+
577
+ diagnoseNote (
578
+ loc, diag::regionbasedisolation_named_isolated_closure_yields_race,
579
+ descriptiveKindStr, name, isolationCrossing.getCalleeIsolation (),
580
+ isolationCrossing.getCallerIsolation ())
581
+ .highlight (loc.getSourceRange ());
582
+ emitRequireInstDiagnostics ();
583
+ }
584
+
545
585
void emitTypedIsolationCrossingDueToCapture (
546
586
SILLocation loc, Type inferredType,
547
587
ApplyIsolationCrossing isolationCrossing) {
@@ -617,7 +657,7 @@ class UseAfterTransferDiagnosticInferrer {
617
657
SILLocation baseLoc = SILLocation::invalid();
618
658
Type baseInferredType;
619
659
620
- struct Walker ;
660
+ struct AutoClosureWalker ;
621
661
622
662
public:
623
663
UseAfterTransferDiagnosticInferrer (
@@ -671,16 +711,25 @@ bool UseAfterTransferDiagnosticInferrer::initForIsolatedPartialApply(
671
711
return false ;
672
712
673
713
unsigned opIndex = ApplySite (op->getUser ()).getAppliedArgIndex (*op);
714
+ bool emittedDiagnostic = false ;
674
715
for (auto &p : foundCapturedIsolationCrossing) {
675
- if (std::get<1 >(p) == opIndex) {
676
- diagnosticEmitter.emitTypedIsolationCrossingDueToCapture (
677
- RegularLocation (std::get<0 >(p).getLoc ()), baseInferredType,
678
- std::get<2 >(p));
679
- return true ;
716
+ if (std::get<1 >(p) != opIndex)
717
+ continue ;
718
+ emittedDiagnostic = true ;
719
+
720
+ if (auto rootValueAndName = inferNameAndRootFromValue (transferOp->get ())) {
721
+ diagnosticEmitter.emitNamedIsolationCrossingDueToCapture (
722
+ RegularLocation (std::get<0 >(p).getLoc ()), rootValueAndName->first ,
723
+ transferOp->getIsolationInfo (), std::get<2 >(p));
724
+ continue ;
680
725
}
726
+
727
+ diagnosticEmitter.emitTypedIsolationCrossingDueToCapture (
728
+ RegularLocation (std::get<0 >(p).getLoc ()), baseInferredType,
729
+ std::get<2 >(p));
681
730
}
682
731
683
- return false ;
732
+ return emittedDiagnostic ;
684
733
}
685
734
686
735
void UseAfterTransferDiagnosticInferrer::initForApply (Operand *op,
@@ -701,14 +750,19 @@ void UseAfterTransferDiagnosticInferrer::initForApply(Operand *op,
701
750
isolationCrossing);
702
751
}
703
752
704
- struct UseAfterTransferDiagnosticInferrer ::Walker : ASTWalker {
753
+ // / This walker visits an AutoClosureExpr and looks for uses of a specific
754
+ // / captured value. We want to error on the uses in the autoclosure.
755
+ struct UseAfterTransferDiagnosticInferrer ::AutoClosureWalker : ASTWalker {
705
756
UseAfterTransferDiagnosticInferrer &foundTypeInfo;
706
757
ValueDecl *targetDecl;
758
+ SILIsolationInfo targetDeclIsolationInfo;
707
759
SmallPtrSet<Expr *, 8 > visitedCallExprDeclRefExprs;
708
760
709
- Walker (UseAfterTransferDiagnosticInferrer &foundTypeInfo,
710
- ValueDecl *targetDecl)
711
- : foundTypeInfo(foundTypeInfo), targetDecl(targetDecl) {}
761
+ AutoClosureWalker (UseAfterTransferDiagnosticInferrer &foundTypeInfo,
762
+ ValueDecl *targetDecl,
763
+ SILIsolationInfo targetDeclIsolationInfo)
764
+ : foundTypeInfo(foundTypeInfo), targetDecl(targetDecl),
765
+ targetDeclIsolationInfo (targetDeclIsolationInfo) {}
712
766
713
767
Expr *lookThroughExpr (Expr *expr) {
714
768
while (true ) {
@@ -761,9 +815,9 @@ struct UseAfterTransferDiagnosticInferrer::Walker : ASTWalker {
761
815
if (declRef->getDecl () == targetDecl) {
762
816
// Found our target!
763
817
visitedCallExprDeclRefExprs.insert (declRef);
764
- foundTypeInfo.diagnosticEmitter .emitTypedIsolationCrossing (
765
- foundTypeInfo.baseLoc , declRef-> findOriginalType (),
766
- *isolationCrossing);
818
+ foundTypeInfo.diagnosticEmitter .emitNamedIsolationCrossingError (
819
+ foundTypeInfo.baseLoc , targetDecl-> getBaseIdentifier (),
820
+ targetDeclIsolationInfo, *isolationCrossing);
767
821
return Action::Continue (expr);
768
822
}
769
823
}
@@ -783,7 +837,16 @@ void UseAfterTransferDiagnosticInferrer::infer() {
783
837
" We should never transfer an indirect out parameter" );
784
838
if (fas.getArgumentParameterInfo (*transferOp->getOperand ())
785
839
.hasOption (SILParameterInfo::Transferring)) {
786
- return diagnosticEmitter.emitUseOfStronglyTransferredValue (
840
+
841
+ // First try to do the named diagnostic if we can find a name.
842
+ if (auto rootValueAndName =
843
+ inferNameAndRootFromValue (transferOp->get ())) {
844
+ return diagnosticEmitter.emitNamedUseOfStronglyTransferredValue (
845
+ baseLoc, rootValueAndName->first );
846
+ }
847
+
848
+ // Otherwise, emit the typed diagnostic.
849
+ return diagnosticEmitter.emitTypedUseOfStronglyTransferredValue (
787
850
baseLoc, baseInferredType);
788
851
}
789
852
}
@@ -804,20 +867,9 @@ void UseAfterTransferDiagnosticInferrer::infer() {
804
867
// Before we do anything further, see if we can find a name and emit a name
805
868
// error.
806
869
if (auto rootValueAndName = inferNameAndRootFromValue (transferOp->get ())) {
807
- if (auto *svi =
808
- dyn_cast<SingleValueInstruction>(rootValueAndName->second )) {
809
- return diagnosticEmitter.emitNamedIsolationCrossingError (
810
- baseLoc, rootValueAndName->first , transferOp->getIsolationInfo (),
811
- *sourceApply->getIsolationCrossing (), svi->getLoc ());
812
- }
813
-
814
- if (auto *fArg =
815
- dyn_cast<SILFunctionArgument>(rootValueAndName->second )) {
816
- return diagnosticEmitter.emitNamedIsolationCrossingError (
817
- baseLoc, rootValueAndName->first , transferOp->getIsolationInfo (),
818
- *sourceApply->getIsolationCrossing (),
819
- RegularLocation (fArg ->getDecl ()->getLoc ()));
820
- }
870
+ return diagnosticEmitter.emitNamedIsolationCrossingError (
871
+ baseLoc, rootValueAndName->first , transferOp->getIsolationInfo (),
872
+ *sourceApply->getIsolationCrossing ());
821
873
}
822
874
823
875
// Otherwise, try to infer from the ApplyExpr.
@@ -843,7 +895,7 @@ void UseAfterTransferDiagnosticInferrer::infer() {
843
895
auto captureInfo =
844
896
autoClosureExpr->getCaptureInfo ().getCaptures ()[captureIndex];
845
897
auto *captureDecl = captureInfo.getDecl ();
846
- Walker walker (*this , captureDecl);
898
+ AutoClosureWalker walker (*this , captureDecl, transferOp-> getIsolationInfo () );
847
899
autoClosureExpr->walk (walker);
848
900
}
849
901
0 commit comments