[SE-0470] Track the potential introduction of isolated conformances in regions

When we introduce isolation due to a (potential) isolated conformance,
keep track of the protocol to which the conformance could be
introduced. Use this information for two reasons:

1. Downgrade the error to a warning in Swift < 7, because we are newly
diagnosing these
2. Add a note indicating where the isolated conformance could be introduced.
This commit is contained in:
Doug Gregor
2025-07-08 11:13:50 -07:00
parent c33ce3f029
commit 02c34bb830
6 changed files with 132 additions and 56 deletions

View File

@@ -1070,6 +1070,10 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
}
void SILIsolationInfo::printOptions(llvm::raw_ostream &os) const {
if (isolatedConformance) {
os << "isolated-conformance-to(" << isolatedConformance->getName() << ")";
}
auto opts = getOptions();
if (!opts)
return;
@@ -1255,9 +1259,11 @@ void SILIsolationInfo::Profile(llvm::FoldingSetNodeID &id) const {
return;
case Task:
id.AddPointer(getIsolatedValue());
id.AddPointer(getIsolatedConformance());
return;
case Actor:
id.AddPointer(getIsolatedValue());
id.AddPointer(getIsolatedConformance());
getActorIsolation().Profile(id);
return;
}
@@ -1570,7 +1576,7 @@ SILDynamicMergedIsolationInfo::merge(SILIsolationInfo other) const {
// If both innerInfo and other have the same isolation, we are obviously
// done. Just return innerInfo since we could return either.
if (innerInfo.hasSameIsolation(other))
return {innerInfo};
return {innerInfo.withMergedIsolatedConformance(other.getIsolatedConformance())};
// Ok, there is some difference in between innerInfo and other. Lets see if
// they are both actor instance isolated and if either are unapplied
@@ -1579,9 +1585,9 @@ SILDynamicMergedIsolationInfo::merge(SILIsolationInfo other) const {
if (innerInfo.getActorIsolation().isActorInstanceIsolated() &&
other.getActorIsolation().isActorInstanceIsolated()) {
if (innerInfo.isUnappliedIsolatedAnyParameter())
return other;
return other.withMergedIsolatedConformance(innerInfo.getIsolatedConformance());
if (other.isUnappliedIsolatedAnyParameter())
return innerInfo;
return innerInfo.withMergedIsolatedConformance(other.getIsolatedConformance());
}
// Otherwise, they do not match... so return None to signal merge failure.
@@ -1610,7 +1616,8 @@ SILDynamicMergedIsolationInfo::merge(SILIsolationInfo other) const {
if (innerInfo.isTaskIsolated() && other.isTaskIsolated()) {
if (innerInfo.isNonisolatedNonsendingTaskIsolated() ||
other.isNonisolatedNonsendingTaskIsolated())
return other.withNonisolatedNonsendingTaskIsolated(true);
return other.withNonisolatedNonsendingTaskIsolated(true)
.withMergedIsolatedConformance(innerInfo.getIsolatedConformance());
}
// Otherwise, just return other.