Skip to content

Commit 6d00750

Browse files
authored
Merge pull request #70653 from gottesmm/transferring
[region-isolation] Initial refactoring work for supporting Transferring Args and Results
2 parents 8e2aa52 + abba624 commit 6d00750

22 files changed

+523
-393
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,10 +2160,10 @@ ERROR(duplicate_storage_restrictions_attr_label,none,
21602160
ERROR(storage_restrictions_attr_expected_name,none,
21612161
"expected property name in @storageRestrictions list", ())
21622162

2163-
ERROR(requires_non_escapable_types, none,
2164-
"'%0' %select{attribute|parameter specifier}1 is only valid when experimental "
2165-
"NonescapableTypes is enabled",
2166-
(StringRef, bool))
2163+
ERROR(requires_experimental_feature, none,
2164+
"'%0' %select{attribute|parameter specifier}1 is only valid when experimental feature "
2165+
"%2 is enabled",
2166+
(StringRef, bool, StringRef))
21672167

21682168
#define UNDEFINE_DIAGNOSTIC_MACROS
21692169
#include "DefineDiagnosticMacros.h"

include/swift/AST/TypeDifferenceVisitor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
291291
bool visitComponent(CanType type1, CanType type2,
292292
SILParameterInfo param1, SILParameterInfo param2) {
293293
if (param1.getConvention() != param2.getConvention() ||
294-
param1.getDifferentiability() != param2.getDifferentiability())
294+
param1.getOptions().containsOnly(param2.getOptions()))
295295
return asImpl().visitDifferentTypeStructure(type1, type2);
296296

297297
return asImpl().visit(param1.getInterfaceType(),

include/swift/AST/Types.h

Lines changed: 175 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4092,54 +4092,50 @@ inline bool isPackParameter(ParameterConvention conv) {
40924092
llvm_unreachable("bad convention kind");
40934093
}
40944094

4095-
/// The differentiability of a SIL function type parameter.
4096-
enum class SILParameterDifferentiability : bool {
4097-
/// Either differentiable or not applicable.
4098-
///
4099-
/// - If the function type is not `@differentiable`, parameter
4100-
/// differentiability is not applicable. This case is the default value.
4101-
/// - If the function type is `@differentiable`, the function is
4102-
/// differentiable with respect to this parameter.
4103-
DifferentiableOrNotApplicable,
4104-
4105-
/// Not differentiable: a `@noDerivative` parameter.
4106-
///
4107-
/// May be applied only to parameters of `@differentiable` function types.
4108-
/// The function type is not differentiable with respect to this parameter.
4109-
NotDifferentiable,
4110-
};
4111-
41124095
/// A parameter type and the rules for passing it.
41134096
class SILParameterInfo {
4114-
CanType Type;
4115-
ParameterConvention Convention;
4116-
SILParameterDifferentiability Differentiability;
4097+
public:
4098+
enum Flag : uint8_t {
4099+
/// Not differentiable: a `@noDerivative` parameter.
4100+
///
4101+
/// May be applied only to parameters of `@differentiable` function types.
4102+
/// The function type is not differentiable with respect to this parameter.
4103+
///
4104+
/// If this is not set then the parameter is either differentiable or
4105+
/// differentiation is not applicable to the parameter:
4106+
///
4107+
/// - If the function type is not `@differentiable`, parameter
4108+
/// differentiability is not applicable. This case is the default value.
4109+
/// - If the function type is `@differentiable`, the function is
4110+
/// differentiable with respect to this parameter.
4111+
NotDifferentiable = 0x1,
4112+
};
4113+
4114+
using Options = OptionSet<Flag>;
4115+
4116+
private:
4117+
CanType type;
4118+
ParameterConvention convention;
4119+
Options options;
41174120

41184121
public:
41194122
SILParameterInfo() = default;//: Ty(), Convention((ParameterConvention)0) {}
4120-
SILParameterInfo(
4121-
CanType type, ParameterConvention conv,
4122-
SILParameterDifferentiability differentiability =
4123-
SILParameterDifferentiability::DifferentiableOrNotApplicable)
4124-
: Type(type), Convention(conv), Differentiability(differentiability) {
4123+
SILParameterInfo(CanType type, ParameterConvention conv, Options options = {})
4124+
: type(type), convention(conv), options(options) {
41254125
assert(type->isLegalSILType() && "SILParameterInfo has illegal SIL type");
41264126
}
41274127

41284128
/// Return the unsubstituted parameter type that describes the abstract
41294129
/// calling convention of the parameter.
41304130
///
41314131
/// For most purposes, you probably want \c getArgumentType .
4132-
CanType getInterfaceType() const {
4133-
return Type;
4134-
}
4135-
4132+
CanType getInterfaceType() const { return type; }
4133+
41364134
/// Return the type of a call argument matching this parameter.
41374135
///
41384136
/// \c t must refer back to the function type this is a parameter for.
41394137
CanType getArgumentType(SILModule &M, const SILFunctionType *t, TypeExpansionContext context) const;
4140-
ParameterConvention getConvention() const {
4141-
return Convention;
4142-
}
4138+
ParameterConvention getConvention() const { return convention; }
41434139
// Does this parameter convention require indirect storage? This reflects a
41444140
// SILFunctionType's formal (immutable) conventions, as opposed to the
41454141
// transient SIL conventions that dictate SILValue types.
@@ -4186,14 +4182,65 @@ class SILParameterInfo {
41864182
return isGuaranteedParameter(getConvention());
41874183
}
41884184

4189-
SILParameterDifferentiability getDifferentiability() const {
4190-
return Differentiability;
4185+
bool hasOption(Flag flag) const { return options.contains(flag); }
4186+
4187+
Options getOptions() const { return options; }
4188+
4189+
SILParameterInfo addingOption(Flag flag) const {
4190+
auto options = getOptions();
4191+
options |= flag;
4192+
return SILParameterInfo(getInterfaceType(), getConvention(), options);
4193+
}
4194+
4195+
SILParameterInfo removingOption(Flag flag) const {
4196+
auto options = getOptions();
4197+
options &= flag;
4198+
return SILParameterInfo(getInterfaceType(), getConvention(), options);
4199+
}
4200+
4201+
/// Add all flags in \p arg into a copy of this parameter info and return the
4202+
/// parameter info.
4203+
///
4204+
/// NOTE: You can pass in SILParameterInfo::Flag to this function since said
4205+
/// type auto converts to Options.
4206+
SILParameterInfo operator|(Options arg) const {
4207+
return SILParameterInfo(getInterfaceType(), getConvention(),
4208+
getOptions() | arg);
4209+
}
4210+
4211+
SILParameterInfo &operator|=(Options arg) {
4212+
options |= arg;
4213+
return *this;
41914214
}
41924215

4193-
SILParameterInfo getWithDifferentiability(
4194-
SILParameterDifferentiability differentiability) const {
4216+
/// Copy this parameter and intersect \p arg with the parameters former
4217+
/// options.
4218+
///
4219+
/// NOTE: You can pass in SILParameterInfo::Flag to this function since said
4220+
/// type auto converts to Options.
4221+
SILParameterInfo operator&(Options arg) const {
41954222
return SILParameterInfo(getInterfaceType(), getConvention(),
4196-
differentiability);
4223+
getOptions() & arg);
4224+
}
4225+
4226+
SILParameterInfo &operator&=(Options arg) {
4227+
options &= arg;
4228+
return *this;
4229+
}
4230+
4231+
/// Copy this parameter such that its options contains the set subtraction of
4232+
/// \p arg from the parameters former options.
4233+
///
4234+
/// NOTE: You can pass in SILParameterInfo::Flag to this function since said
4235+
/// type auto converts to Options.
4236+
SILParameterInfo operator-(Options arg) const {
4237+
return SILParameterInfo(getInterfaceType(), getConvention(),
4238+
getOptions() - arg);
4239+
}
4240+
4241+
SILParameterInfo &operator-=(Options arg) {
4242+
options -= arg;
4243+
return *this;
41974244
}
41984245

41994246
/// The SIL storage type determines the ABI for arguments based purely on the
@@ -4209,12 +4256,12 @@ class SILParameterInfo {
42094256

42104257
/// Return a version of this parameter info with the type replaced.
42114258
SILParameterInfo getWithInterfaceType(CanType type) const {
4212-
return SILParameterInfo(type, getConvention(), getDifferentiability());
4259+
return SILParameterInfo(type, getConvention(), getOptions());
42134260
}
42144261

42154262
/// Return a version of this parameter info with the convention replaced.
42164263
SILParameterInfo getWithConvention(ParameterConvention c) const {
4217-
return SILParameterInfo(getInterfaceType(), c, getDifferentiability());
4264+
return SILParameterInfo(getInterfaceType(), c, getOptions());
42184265
}
42194266

42204267
/// Transform this SILParameterInfo by applying the user-provided
@@ -4244,7 +4291,7 @@ class SILParameterInfo {
42444291
void profile(llvm::FoldingSetNodeID &id) {
42454292
id.AddPointer(getInterfaceType().getPointer());
42464293
id.AddInteger((unsigned)getConvention());
4247-
id.AddInteger((unsigned)getDifferentiability());
4294+
id.AddInteger((unsigned)getOptions().toRaw());
42484295
}
42494296

42504297
SWIFT_DEBUG_DUMP;
@@ -4260,7 +4307,7 @@ class SILParameterInfo {
42604307
bool operator==(SILParameterInfo rhs) const {
42614308
return getInterfaceType() == rhs.getInterfaceType() &&
42624309
getConvention() == rhs.getConvention() &&
4263-
getDifferentiability() == rhs.getDifferentiability();
4310+
getOptions().containsOnly(rhs.getOptions());
42644311
}
42654312
bool operator!=(SILParameterInfo rhs) const {
42664313
return !(*this == rhs);
@@ -4309,64 +4356,112 @@ inline bool isIndirectFormalResult(ResultConvention convention) {
43094356
convention == ResultConvention::Pack;
43104357
}
43114358

4312-
/// The differentiability of a SIL function type result.
4313-
enum class SILResultDifferentiability : bool {
4314-
/// Either differentiable or not applicable.
4315-
///
4316-
/// - If the function type is not `@differentiable`, result
4317-
/// differentiability is not applicable. This case is the default value.
4318-
/// - If the function type is `@differentiable`, the function is
4319-
/// differentiable with respect to this result.
4320-
DifferentiableOrNotApplicable,
4321-
4322-
/// Not differentiable: a `@noDerivative` result.
4323-
///
4324-
/// May be applied only to result of `@differentiable` function types.
4325-
/// The function type is not differentiable with respect to this result.
4326-
NotDifferentiable,
4327-
};
4328-
43294359
/// A result type and the rules for returning it.
43304360
class SILResultInfo {
4331-
CanType Type;
4332-
ResultConvention Convention;
4333-
SILResultDifferentiability Differentiability;
4361+
public:
4362+
enum Flag : uint8_t {
4363+
/// Not differentiable: a `@noDerivative` result.
4364+
///
4365+
/// May be applied only to result of `@differentiable` function types.
4366+
/// The function type is not differentiable with respect to this result.
4367+
///
4368+
/// If this is not set then the function is either differentiable or
4369+
/// differentiability is not applicable. This can occur if:
4370+
///
4371+
/// - The function type is not `@differentiable`, result
4372+
/// differentiability is not applicable. This case is the default value.
4373+
/// - The function type is `@differentiable`, the function is
4374+
/// differentiable with respect to this result.
4375+
NotDifferentiable = 0x1,
4376+
};
4377+
4378+
using Options = OptionSet<Flag>;
4379+
4380+
private:
4381+
CanType type;
4382+
ResultConvention convention;
4383+
Options options;
43344384

43354385
public:
43364386
SILResultInfo() = default;
4337-
SILResultInfo(CanType type, ResultConvention conv,
4338-
SILResultDifferentiability differentiability =
4339-
SILResultDifferentiability::DifferentiableOrNotApplicable)
4340-
: Type(type), Convention(conv), Differentiability(differentiability) {
4387+
SILResultInfo(CanType type, ResultConvention conv, Options options = {})
4388+
: type(type), convention(conv), options(options) {
43414389
assert(type->isLegalSILType() && "SILResultInfo has illegal SIL type");
43424390
}
43434391

43444392
/// Return the unsubstituted parameter type that describes the abstract
43454393
/// calling convention of the parameter.
43464394
///
43474395
/// For most purposes, you probably want \c getReturnValueType .
4348-
CanType getInterfaceType() const {
4349-
return Type;
4350-
}
4351-
4396+
CanType getInterfaceType() const { return type; }
4397+
43524398
/// The type of a return value corresponding to this result.
43534399
///
43544400
/// \c t must refer back to the function type this is a parameter for.
43554401
CanType getReturnValueType(SILModule &M, const SILFunctionType *t,
43564402
TypeExpansionContext context) const;
43574403

4358-
ResultConvention getConvention() const {
4359-
return Convention;
4404+
ResultConvention getConvention() const { return convention; }
4405+
4406+
Options getOptions() const { return options; }
4407+
4408+
bool hasOption(Flag flag) const { return options.contains(flag); }
4409+
4410+
SILResultInfo addingOption(Flag flag) const {
4411+
auto options = getOptions();
4412+
options |= flag;
4413+
return SILResultInfo(getInterfaceType(), getConvention(), options);
4414+
}
4415+
4416+
SILResultInfo removingOption(Flag flag) const {
4417+
auto options = getOptions();
4418+
options &= flag;
4419+
return SILResultInfo(getInterfaceType(), getConvention(), options);
4420+
}
4421+
4422+
/// Add all flags in \p arg into a copy of this parameter info and return the
4423+
/// parameter info.
4424+
///
4425+
/// NOTE: You can pass in SILResultInfo::Flag to this function since said
4426+
/// type auto converts to Options.
4427+
SILResultInfo operator|(Options arg) const {
4428+
return SILResultInfo(getInterfaceType(), getConvention(),
4429+
getOptions() | arg);
43604430
}
43614431

4362-
SILResultDifferentiability getDifferentiability() const {
4363-
return Differentiability;
4432+
SILResultInfo &operator|=(Options arg) {
4433+
options |= arg;
4434+
return *this;
43644435
}
43654436

4366-
SILResultInfo
4367-
getWithDifferentiability(SILResultDifferentiability differentiability) const {
4437+
/// Copy this parameter and intersect \p arg with the parameters former
4438+
/// options.
4439+
///
4440+
/// NOTE: You can pass in SILResultInfo::Flag to this function since said
4441+
/// type auto converts to Options.
4442+
SILResultInfo operator&(Options arg) const {
43684443
return SILResultInfo(getInterfaceType(), getConvention(),
4369-
differentiability);
4444+
getOptions() & arg);
4445+
}
4446+
4447+
SILResultInfo &operator&=(Options arg) {
4448+
options &= arg;
4449+
return *this;
4450+
}
4451+
4452+
/// Copy this parameter such that its options contains the set subtraction of
4453+
/// \p arg from the parameters former options.
4454+
///
4455+
/// NOTE: You can pass in SILResultInfo::Flag to this function since said
4456+
/// type auto converts to Options.
4457+
SILResultInfo operator-(Options arg) const {
4458+
return SILResultInfo(getInterfaceType(), getConvention(),
4459+
getOptions() - arg);
4460+
}
4461+
4462+
SILResultInfo &operator-=(Options arg) {
4463+
options -= arg;
4464+
return *this;
43704465
}
43714466

43724467
/// The SIL storage type determines the ABI for arguments based purely on the
@@ -4429,9 +4524,9 @@ class SILResultInfo {
44294524
}
44304525

44314526
void profile(llvm::FoldingSetNodeID &id) {
4432-
id.AddPointer(Type.getPointer());
4527+
id.AddPointer(type.getPointer());
44334528
id.AddInteger(unsigned(getConvention()));
4434-
id.AddInteger(unsigned(getDifferentiability()));
4529+
id.AddInteger(unsigned(getOptions().toRaw()));
44354530
}
44364531

44374532
SWIFT_DEBUG_DUMP;
@@ -4448,8 +4543,8 @@ class SILResultInfo {
44484543
getOwnershipKind(SILFunction &, CanSILFunctionType fTy) const; // in SILType.cpp
44494544

44504545
bool operator==(SILResultInfo rhs) const {
4451-
return Type == rhs.Type && Convention == rhs.Convention
4452-
&& Differentiability == rhs.Differentiability;
4546+
return type == rhs.type && convention == rhs.convention &&
4547+
getOptions().containsOnly(rhs.getOptions());
44534548
}
44544549
bool operator!=(SILResultInfo rhs) const {
44554550
return !(*this == rhs);

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ EXPERIMENTAL_FEATURE(FixedArrays, true)
281281
// Group Main Actor Isolation Errors by Scope
282282
EXPERIMENTAL_FEATURE(GroupActorErrors, true)
283283

284+
// Allow for the 'transferring' keyword to be applied to arguments and results.
285+
EXPERIMENTAL_FEATURE(TransferringArgsAndResults, true)
286+
284287
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
285288
#undef EXPERIMENTAL_FEATURE
286289
#undef UPCOMING_FEATURE

0 commit comments

Comments
 (0)