Skip to content

Commit 76e71e7

Browse files
authored
Merge pull request #72196 from gottesmm/rest-of-rdar123488540
[region-isolation] Make fields of global actor guarded types that are non-Sendable be considered as actor isolated.
2 parents 463d8e1 + d8b2631 commit 76e71e7

File tree

18 files changed

+510
-329
lines changed

18 files changed

+510
-329
lines changed

include/swift/AST/ExtInfo.h

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -935,8 +935,7 @@ class SILExtInfoBuilder {
935935
DifferentiabilityMask = 0x7 << DifferentiabilityMaskOffset,
936936
UnimplementableMask = 1 << 12,
937937
ErasedIsolationMask = 1 << 13,
938-
TransferringResultMask = 1 << 14,
939-
NumMaskBits = 15
938+
NumMaskBits = 14
940939
};
941940

942941
unsigned bits; // Naturally sized for speed.
@@ -957,17 +956,15 @@ class SILExtInfoBuilder {
957956
bool isNoEscape, bool isSendable,
958957
bool isAsync, bool isUnimplementable,
959958
SILFunctionTypeIsolation isolation,
960-
bool hasTransferringResult,
961959
DifferentiabilityKind diffKind) {
962960
return ((unsigned)rep) | (isPseudogeneric ? PseudogenericMask : 0) |
963961
(isNoEscape ? NoEscapeMask : 0) | (isSendable ? SendableMask : 0) |
964962
(isAsync ? AsyncMask : 0) |
965963
(isUnimplementable ? UnimplementableMask : 0) |
966-
(isolation == SILFunctionTypeIsolation::Erased
967-
? ErasedIsolationMask : 0) |
964+
(isolation == SILFunctionTypeIsolation::Erased ? ErasedIsolationMask
965+
: 0) |
968966
(((unsigned)diffKind << DifferentiabilityMaskOffset) &
969-
DifferentiabilityMask) |
970-
(hasTransferringResult ? TransferringResultMask : 0);
967+
DifferentiabilityMask);
971968
}
972969

973970
public:
@@ -976,19 +973,18 @@ class SILExtInfoBuilder {
976973
SILExtInfoBuilder()
977974
: SILExtInfoBuilder(makeBits(SILFunctionTypeRepresentation::Thick, false,
978975
false, false, false, false,
979-
SILFunctionTypeIsolation::Unknown, false,
976+
SILFunctionTypeIsolation::Unknown,
980977
DifferentiabilityKind::NonDifferentiable),
981978
ClangTypeInfo(nullptr), LifetimeDependenceInfo()) {}
982979

983980
SILExtInfoBuilder(Representation rep, bool isPseudogeneric, bool isNoEscape,
984981
bool isSendable, bool isAsync, bool isUnimplementable,
985982
SILFunctionTypeIsolation isolation,
986983
DifferentiabilityKind diffKind, const clang::Type *type,
987-
LifetimeDependenceInfo lifetimeDependenceInfo,
988-
bool hasTransferringResult)
984+
LifetimeDependenceInfo lifetimeDependenceInfo)
989985
: SILExtInfoBuilder(makeBits(rep, isPseudogeneric, isNoEscape, isSendable,
990986
isAsync, isUnimplementable, isolation,
991-
hasTransferringResult, diffKind),
987+
diffKind),
992988
ClangTypeInfo(type), lifetimeDependenceInfo) {}
993989

994990
// Constructor for polymorphic type.
@@ -999,7 +995,6 @@ class SILExtInfoBuilder {
999995
info.getIsolation().isErased()
1000996
? SILFunctionTypeIsolation::Erased
1001997
: SILFunctionTypeIsolation::Unknown,
1002-
/*has transferring result*/ false,
1003998
info.getDifferentiabilityKind()),
1004999
info.getClangTypeInfo(),
10051000
info.getLifetimeDependenceInfo()) {}
@@ -1029,10 +1024,6 @@ class SILExtInfoBuilder {
10291024

10301025
constexpr bool isAsync() const { return bits & AsyncMask; }
10311026

1032-
constexpr bool hasTransferringResult() const {
1033-
return bits & TransferringResultMask;
1034-
}
1035-
10361027
constexpr DifferentiabilityKind getDifferentiabilityKind() const {
10371028
return DifferentiabilityKind((bits & DifferentiabilityMask) >>
10381029
DifferentiabilityMaskOffset);
@@ -1166,14 +1157,6 @@ class SILExtInfoBuilder {
11661157
clangTypeInfo, lifetimeDependenceInfo);
11671158
}
11681159

1169-
[[nodiscard]] SILExtInfoBuilder
1170-
withTransferringResult(bool hasTransferringResult = true) const {
1171-
return SILExtInfoBuilder(hasTransferringResult
1172-
? (bits | TransferringResultMask)
1173-
: (bits & ~TransferringResultMask),
1174-
clangTypeInfo, lifetimeDependenceInfo);
1175-
}
1176-
11771160
[[nodiscard]]
11781161
SILExtInfoBuilder
11791162
withDifferentiabilityKind(DifferentiabilityKind differentiability) const {
@@ -1239,11 +1222,11 @@ class SILExtInfo {
12391222

12401223
/// A default ExtInfo but with a Thin convention.
12411224
static SILExtInfo getThin() {
1242-
return SILExtInfoBuilder(
1243-
SILExtInfoBuilder::Representation::Thin, false, false, false,
1244-
false, false, SILFunctionTypeIsolation::Unknown,
1245-
DifferentiabilityKind::NonDifferentiable, nullptr,
1246-
LifetimeDependenceInfo(), false /*transferring result*/)
1225+
return SILExtInfoBuilder(SILExtInfoBuilder::Representation::Thin, false,
1226+
false, false, false, false,
1227+
SILFunctionTypeIsolation::Unknown,
1228+
DifferentiabilityKind::NonDifferentiable, nullptr,
1229+
LifetimeDependenceInfo())
12471230
.build();
12481231
}
12491232

@@ -1281,10 +1264,6 @@ class SILExtInfo {
12811264
return builder.getIsolation();
12821265
}
12831266

1284-
constexpr bool hasTransferringResult() const {
1285-
return builder.hasTransferringResult();
1286-
}
1287-
12881267
constexpr DifferentiabilityKind getDifferentiabilityKind() const {
12891268
return builder.getDifferentiabilityKind();
12901269
}
@@ -1331,10 +1310,6 @@ class SILExtInfo {
13311310
return builder.withUnimplementable(isUnimplementable).build();
13321311
}
13331312

1334-
SILExtInfo withTransferringResult(bool hasTransferringResult = true) const {
1335-
return builder.withTransferringResult(hasTransferringResult).build();
1336-
}
1337-
13381313
SILExtInfo withLifetimeDependenceInfo(LifetimeDependenceInfo info) const {
13391314
return builder.withLifetimeDependenceInfo(info);
13401315
}

include/swift/AST/Types.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
383383

384384
protected:
385385
enum { NumAFTExtInfoBits = 15 };
386-
enum { NumSILExtInfoBits = 15 };
386+
enum { NumSILExtInfoBits = 14 };
387387

388388
// clang-format off
389389
union { uint64_t OpaqueBits;
@@ -4462,6 +4462,11 @@ class SILResultInfo {
44624462
/// - The function type is `@differentiable`, the function is
44634463
/// differentiable with respect to this result.
44644464
NotDifferentiable = 0x1,
4465+
4466+
/// Set if a return type is transferring. This means that the returned value
4467+
/// must be disconnected and not in any strongly structured regions like an
4468+
/// actor or a task isolated variable.
4469+
IsTransferring = 0x2,
44654470
};
44664471

44674472
using Options = OptionSet<Flag>;
@@ -4906,8 +4911,13 @@ class SILFunctionType final
49064911
SILFunctionTypeIsolation getIsolation() const {
49074912
return getExtInfo().getIsolation();
49084913
}
4914+
4915+
/// Return true if all
49094916
bool hasTransferringResult() const {
4910-
return getExtInfo().hasTransferringResult();
4917+
// For now all functions either have all transferring results or no
4918+
// transferring results. This is validated with a SILVerifier check.
4919+
return getNumResults() &&
4920+
getResults().front().hasOption(SILResultInfo::IsTransferring);
49114921
}
49124922

49134923
/// Return the array of all the yields.

include/swift/Demangling/TypeDecoder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ using ImplParameterInfoOptions = OptionSet<ImplParameterInfoFlags>;
116116

117117
enum class ImplResultInfoFlags : uint8_t {
118118
NotDifferentiable = 0x1,
119+
IsTransferring = 0x2,
119120
};
120121

121122
using ImplResultInfoOptions = OptionSet<ImplResultInfoFlags>;

lib/AST/ASTDemangler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,11 @@ getResultOptions(ImplResultInfoOptions implOptions) {
558558
result |= SILResultInfo::NotDifferentiable;
559559
}
560560

561+
if (implOptions.contains(ImplResultInfoFlags::IsTransferring)) {
562+
implOptions -= ImplResultInfoFlags::IsTransferring;
563+
result |= SILResultInfo::IsTransferring;
564+
}
565+
561566
// If we did not remove all of the options from implOptions, someone forgot to
562567
// update this code for a new type of flag. Return none to signal error!
563568
if (bool(implOptions))
@@ -664,8 +669,7 @@ Type ASTBuilder::createImplFunctionType(
664669
auto einfo = SILFunctionType::ExtInfoBuilder(
665670
representation, flags.isPseudogeneric(), !flags.isEscaping(),
666671
flags.isSendable(), flags.isAsync(), unimplementable,
667-
isolation, diffKind, clangFnType, LifetimeDependenceInfo(),
668-
flags.hasTransferringResult())
672+
isolation, diffKind, clangFnType, LifetimeDependenceInfo())
669673
.build();
670674

671675
return SILFunctionType::get(genericSig, einfo, funcCoroutineKind,

lib/AST/ASTPrinter.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6740,10 +6740,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
67406740
}
67416741
sub->Printer << ") -> ";
67426742

6743-
if (T->hasTransferringResult()) {
6744-
sub->Printer << "transferring ";
6745-
}
6746-
67476743
auto lifetimeDependenceInfo = T->getLifetimeDependenceInfo();
67486744
if (!lifetimeDependenceInfo.empty()) {
67496745
sub->Printer << lifetimeDependenceInfo.getString() << " ";
@@ -7532,6 +7528,11 @@ void SILResultInfo::print(ASTPrinter &Printer, const PrintOptions &Opts) const {
75327528
Printer << "@noDerivative ";
75337529
}
75347530

7531+
if (options.contains(SILResultInfo::IsTransferring)) {
7532+
options -= SILResultInfo::IsTransferring;
7533+
Printer << "@sil_transferring ";
7534+
}
7535+
75357536
assert(!bool(options) && "ResultInfo has option that was not handled?!");
75367537

75377538
Printer << getStringForResultConvention(getConvention());

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,12 +1254,15 @@ class DestructureResults {
12541254
const Conventions &Convs;
12551255
SmallVectorImpl<SILResultInfo> &Results;
12561256
TypeExpansionContext context;
1257+
bool hasTransferringResult;
12571258

12581259
public:
12591260
DestructureResults(TypeExpansionContext context, TypeConverter &TC,
12601261
const Conventions &conventions,
1261-
SmallVectorImpl<SILResultInfo> &results)
1262-
: TC(TC), Convs(conventions), Results(results), context(context) {}
1262+
SmallVectorImpl<SILResultInfo> &results,
1263+
bool hasTransferringResult)
1264+
: TC(TC), Convs(conventions), Results(results), context(context),
1265+
hasTransferringResult(hasTransferringResult) {}
12631266

12641267
void destructure(AbstractionPattern origType, CanType substType) {
12651268
// Recur into tuples.
@@ -1290,6 +1293,8 @@ class DestructureResults {
12901293
SILPackType::ExtInfo extInfo(indirect);
12911294
auto packType = SILPackType::get(TC.Context, extInfo, packElts);
12921295
SILResultInfo result(packType, ResultConvention::Pack);
1296+
if (hasTransferringResult)
1297+
result = result.addingOption(SILResultInfo::IsTransferring);
12931298
Results.push_back(result);
12941299
});
12951300
return;
@@ -1331,6 +1336,8 @@ class DestructureResults {
13311336

13321337
SILResultInfo result(substResultTL.getLoweredType().getASTType(),
13331338
convention);
1339+
if (hasTransferringResult)
1340+
result = result.addingOption(SILResultInfo::IsTransferring);
13341341
Results.push_back(result);
13351342
}
13361343

@@ -2359,8 +2366,8 @@ static CanSILFunctionType getSILFunctionType(
23592366
// Destructure the result tuple type.
23602367
SmallVector<SILResultInfo, 8> results;
23612368
{
2362-
DestructureResults destructurer(expansionContext, TC, conventions,
2363-
results);
2369+
DestructureResults destructurer(expansionContext, TC, conventions, results,
2370+
hasTransferringResult);
23642371
destructurer.destructure(origResultType, substFormalResultType);
23652372
}
23662373

@@ -2405,7 +2412,6 @@ static CanSILFunctionType getSILFunctionType(
24052412
.withUnimplementable(unimplementable)
24062413
.withLifetimeDependenceInfo(
24072414
extInfoBuilder.getLifetimeDependenceInfo())
2408-
.withTransferringResult(hasTransferringResult)
24092415
.build();
24102416

24112417
return SILFunctionType::get(genericSig, silExtInfo, coroutineKind,

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6518,6 +6518,17 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
65186518
require(!FTy->hasErasedIsolation() ||
65196519
FTy->getRepresentation() == SILFunctionType::Representation::Thick,
65206520
"only thick function types can have erased isolation");
6521+
6522+
// If our function hasTransferringResult, then /all/ results must be
6523+
// transferring.
6524+
require(FTy->hasTransferringResult() ==
6525+
(FTy->getResults().size() &&
6526+
llvm::all_of(FTy->getResults(),
6527+
[](SILResultInfo result) {
6528+
return result.hasOption(
6529+
SILResultInfo::IsTransferring);
6530+
})),
6531+
"transferring result means all results are transferring");
65216532
}
65226533

65236534
struct VerifyFlowSensitiveRulesDetails {

0 commit comments

Comments
 (0)