Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.0] Add support for sending #73743

Merged
merged 5 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,7 @@ class TargetExtendedFunctionTypeFlags {
IsolatedAny = 0x00000002U,

// Values if we have a transferring result.
HasTransferringResult = 0x00000010U,
HasSendingResult = 0x00000010U,

/// A InvertibleProtocolSet in the high bits.
InvertedProtocolshift = 16,
Expand Down Expand Up @@ -1228,10 +1228,10 @@ class TargetExtendedFunctionTypeFlags {
}

const TargetExtendedFunctionTypeFlags<int_type>
withTransferringResult(bool newValue = true) const {
withSendingResult(bool newValue = true) const {
return TargetExtendedFunctionTypeFlags<int_type>(
(Data & ~HasTransferringResult) |
(newValue ? HasTransferringResult : 0));
(Data & ~HasSendingResult) |
(newValue ? HasSendingResult : 0));
}

const TargetExtendedFunctionTypeFlags<int_type>
Expand All @@ -1247,8 +1247,8 @@ class TargetExtendedFunctionTypeFlags {
return (Data & IsolationMask) == IsolatedAny;
}

bool hasTransferringResult() const {
return bool(Data & HasTransferringResult);
bool hasSendingResult() const {
return bool(Data & HasSendingResult);
}

int_type getIntValue() const {
Expand Down Expand Up @@ -1295,7 +1295,7 @@ class TargetParameterTypeFlags {
AutoClosureMask = 0x100,
NoDerivativeMask = 0x200,
IsolatedMask = 0x400,
TransferringMask = 0x800,
SendingMask = 0x800,
};
int_type Data;

Expand Down Expand Up @@ -1335,17 +1335,17 @@ class TargetParameterTypeFlags {
}

constexpr TargetParameterTypeFlags<int_type>
withTransferring(bool isTransferring) const {
withSending(bool isSending) const {
return TargetParameterTypeFlags<int_type>(
(Data & ~TransferringMask) | (isTransferring ? TransferringMask : 0));
(Data & ~SendingMask) | (isSending ? SendingMask : 0));
}

bool isNone() const { return Data == 0; }
bool isVariadic() const { return Data & VariadicMask; }
bool isAutoClosure() const { return Data & AutoClosureMask; }
bool isNoDerivative() const { return Data & NoDerivativeMask; }
bool isIsolated() const { return Data & IsolatedMask; }
bool isTransferring() const { return Data & TransferringMask; }
bool isSending() const { return Data & SendingMask; }

ParameterOwnership getOwnership() const {
return (ParameterOwnership)(Data & OwnershipMask);
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,7 @@ enum ENUM_EXTENSIBILITY_ATTR(open) BridgedAttributedTypeSpecifier : size_t {
BridgedAttributedTypeSpecifierIsolated,
BridgedAttributedTypeSpecifierResultDependsOn,
BridgedAttributedTypeSpecifierTransferring,
BridgedAttributedTypeSpecifierSending,
};

SWIFT_NAME("BridgedUnqualifiedIdentTypeRepr.createParsed(_:loc:name:)")
Expand Down
4 changes: 2 additions & 2 deletions include/swift/AST/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(GetCurrentAsyncTask, "getCurrentAsyncTask", "
BUILTIN_MISC_OPERATION_WITH_SILGEN(CancelAsyncTask, "cancelAsyncTask", "", Special)

/// startAsyncLet()<T>: (
/// __owned @escaping () async throws -> transferring T
/// __owned @escaping () async throws -> sending T
/// ) -> Builtin.RawPointer
///
/// DEPRECATED. startAsyncLetWithLocalBuffer is used instead.
Expand All @@ -894,7 +894,7 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(CancelAsyncTask, "cancelAsyncTask", "", Speci
BUILTIN_MISC_OPERATION(StartAsyncLet, "startAsyncLet", "", Special)

/// startAsyncLetWithLocalBuffer()<T>: (
/// __owned @escaping () async throws -> transferring T,
/// __owned @escaping () async throws -> sending T,
/// _ resultBuf: Builtin.RawPointer
/// ) -> Builtin.RawPointer
///
Expand Down
32 changes: 14 additions & 18 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,8 +532,8 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
/// analysis.
HasTopLevelLocalContextCaptures : 1,

/// Set to true if this FuncDecl has a transferring result.
HasTransferringResult : 1
/// Set to true if this FuncDecl has a 'sending' result.
HasSendingResult : 1
);

SWIFT_INLINE_BITFIELD(AccessorDecl, FuncDecl, 4 + 1 + 1,
Expand Down Expand Up @@ -6647,8 +6647,8 @@ class ParamDecl : public VarDecl {
/// Whether or not this paramater is '_resultDependsOn'
IsResultDependsOn = 1 << 3,

/// Whether or not this parameter is 'transferring'.
IsTransferring = 1 << 4,
/// Whether or not this parameter is 'sending'.
IsSending = 1 << 4,
};

/// The type repr and 3 bits used for flags.
Expand Down Expand Up @@ -6902,16 +6902,14 @@ class ParamDecl : public VarDecl {
removeFlag(Flag::IsIsolated);
}

/// Whether or not this parameter is marked with 'transferring'.
bool isTransferring() const {
return getOptions().contains(Flag::IsTransferring);
}
/// Whether or not this parameter is marked with 'sending'.
bool isSending() const { return getOptions().contains(Flag::IsSending); }

void setTransferring(bool value = true) {
void setSending(bool value = true) {
if (value)
addFlag(Flag::IsTransferring);
addFlag(Flag::IsSending);
else
removeFlag(Flag::IsTransferring);
removeFlag(Flag::IsSending);
}

/// Whether or not this parameter is marked with '_const'.
Expand Down Expand Up @@ -7940,7 +7938,7 @@ class FuncDecl : public AbstractFunctionDecl {
Bits.FuncDecl.IsStaticComputed = false;
Bits.FuncDecl.IsStatic = false;
Bits.FuncDecl.HasTopLevelLocalContextCaptures = false;
Bits.FuncDecl.HasTransferringResult = false;
Bits.FuncDecl.HasSendingResult = false;
}

void setResultInterfaceType(Type type);
Expand Down Expand Up @@ -8097,14 +8095,12 @@ class FuncDecl : public AbstractFunctionDecl {
Bits.FuncDecl.ForcedStaticDispatch = flag;
}

/// Returns true if this FuncDecl has a transferring result... returns false
/// Returns true if this FuncDecl has a sending result... returns false
/// otherwise.
bool hasTransferringResult() const {
return Bits.FuncDecl.HasTransferringResult;
}
bool hasSendingResult() const { return Bits.FuncDecl.HasSendingResult; }

void setTransferringResult(bool newValue = true) {
Bits.FuncDecl.HasTransferringResult = newValue;
void setSendingResult(bool newValue = true) {
Bits.FuncDecl.HasSendingResult = newValue;
}

static bool classof(const Decl *D) {
Expand Down
10 changes: 10 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -2207,6 +2207,16 @@ ERROR(transferring_after_parameter_specifier,none,
"'transferring' must be placed before specifier '%0'", (StringRef))
ERROR(transferring_repeated,none,
"parameter may have at most one 'transferring' specifier", ())
ERROR(sending_before_parameter_specifier,none,
"'sending' must be placed after specifier '%0'", (StringRef))
ERROR(sending_repeated,none,
"parameter may have at most one 'sending' specifier", ())
ERROR(sending_and_transferring_used_together,none,
"'transferring' and 'sending' may not be used together", ())
WARNING(transferring_is_now_sendable,none,
"'transferring' has been renamed to 'sending' and the 'transferring' spelling will be removed shortly",
())


#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"
10 changes: 5 additions & 5 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -990,14 +990,14 @@ NOTE(regionbasedisolation_named_transfer_non_transferrable, none,
NOTE(regionbasedisolation_named_transfer_non_transferrable_callee, none,
"sending %1%0 to %2 %3 %4 risks causing data races between %2 and %5 uses",
(Identifier, StringRef, ActorIsolation, DescriptiveDeclKind, DeclName, StringRef))
NOTE(regionbasedisolation_named_transfer_into_transferring_param, none,
"%0%1 is passed as a transferring parameter; Uses in callee may race with later %0uses",
NOTE(regionbasedisolation_named_transfer_into_sending_param, none,
"%0%1 is passed as a 'sending' parameter; Uses in callee may race with later %0uses",
(StringRef, Identifier))
NOTE(regionbasedisolation_named_notransfer_transfer_into_result, none,
"%0%1 cannot be a transferring result. %2 uses may race with caller uses",
"%0%1 cannot be a 'sending' result. %2 uses may race with caller uses",
(StringRef, Identifier, StringRef))
NOTE(regionbasedisolation_named_stronglytransferred_binding, none,
"%0 used after being passed as a transferring parameter; Later uses could race",
NOTE(regionbasedisolation_named_value_used_after_explicit_sending, none,
"%0 used after being passed as a 'sending' parameter; Later uses could race",
(Identifier))
NOTE(regionbasedisolation_named_isolated_closure_yields_race, none,
"%0%1 is captured by a %2 closure. %2 uses in closure may race against later %3 uses",
Expand Down
26 changes: 16 additions & 10 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -7933,17 +7933,23 @@ ERROR(lifetime_dependence_cannot_infer_ambiguous_candidate, none,
"Escapable",
())

//===----------------------------------------------------------------------===//
// MARK: Transferring
//===----------------------------------------------------------------------===//

ERROR(transferring_unsupported_param_specifier, none,
"'%0' cannot be applied to a 'transferring' parameter", (StringRef))
//===----------------------------------------------------------------------===//
// MARK: Transferring
//===----------------------------------------------------------------------===//

ERROR(transferring_only_on_parameters_and_results, none,
"'transferring' may only be used on parameters and results", ())
ERROR(transferring_cannot_be_applied_to_tuple_elt, none,
"'transferring' cannot be applied to tuple elements", ())
ERROR(transferring_unsupported_param_specifier, none,
"'%0' cannot be applied to a 'transferring' parameter", (StringRef))

ERROR(transferring_only_on_parameters_and_results, none,
"'transferring' may only be used on parameters and results", ())
ERROR(transferring_cannot_be_applied_to_tuple_elt, none,
"'transferring' cannot be applied to tuple elements", ())
ERROR(sending_unsupported_param_specifier, none,
"'%0' cannot be applied to a 'sending' parameter", (StringRef))
ERROR(sending_only_on_parameters_and_results, none,
"'sending' may only be used on parameters and results", ())
ERROR(sending_cannot_be_applied_to_tuple_elt, none,
"'sending' cannot be applied to tuple elements", ())

#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"
33 changes: 13 additions & 20 deletions include/swift/AST/ExtInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,8 @@ class ASTExtInfoBuilder {
// If bits are added or removed, then TypeBase::NumAFTExtInfoBits
// and NumMaskBits must be updated, and they must match.
//
// |representation|noEscape|concurrent|async|throws|isolation|differentiability| TransferringResult |
// | 0 .. 3 | 4 | 5 | 6 | 7 | 8 .. 10 | 11 .. 13 | 14 |
// |representation|noEscape|concurrent|async|throws|isolation|differentiability| SendingResult |
// | 0 .. 3 | 4 | 5 | 6 | 7 | 8 .. 10 | 11 .. 13 | 14 |
//
enum : unsigned {
RepresentationMask = 0xF << 0,
Expand All @@ -451,7 +451,7 @@ class ASTExtInfoBuilder {
IsolationMask = 0x7 << IsolationMaskOffset,
DifferentiabilityMaskOffset = 11,
DifferentiabilityMask = 0x7 << DifferentiabilityMaskOffset,
TransferringResultMask = 1 << 14,
SendingResultMask = 1 << 14,
NumMaskBits = 15
};

Expand Down Expand Up @@ -501,14 +501,14 @@ class ASTExtInfoBuilder {
Type thrownError, DifferentiabilityKind diffKind,
const clang::Type *type, FunctionTypeIsolation isolation,
LifetimeDependenceInfo lifetimeDependenceInfo,
bool transferringResult)
bool sendingResult)
: ASTExtInfoBuilder(
((unsigned)rep) | (isNoEscape ? NoEscapeMask : 0) |
(throws ? ThrowsMask : 0) |
(((unsigned)diffKind << DifferentiabilityMaskOffset) &
DifferentiabilityMask) |
(unsigned(isolation.getKind()) << IsolationMaskOffset) |
(transferringResult ? TransferringResultMask : 0),
(sendingResult ? SendingResultMask : 0),
ClangTypeInfo(type), isolation.getOpaqueType(), thrownError,
lifetimeDependenceInfo) {}

Expand All @@ -530,9 +530,7 @@ class ASTExtInfoBuilder {

constexpr bool isThrowing() const { return bits & ThrowsMask; }

constexpr bool hasTransferringResult() const {
return bits & TransferringResultMask;
}
constexpr bool hasSendingResult() const { return bits & SendingResultMask; }

constexpr DifferentiabilityKind getDifferentiabilityKind() const {
return DifferentiabilityKind((bits & DifferentiabilityMask) >>
Expand Down Expand Up @@ -644,12 +642,10 @@ class ASTExtInfoBuilder {
return withThrows(true, Type());
}

[[nodiscard]] ASTExtInfoBuilder
withTransferringResult(bool transferring = true) const {
return ASTExtInfoBuilder(transferring ? (bits | TransferringResultMask)
: (bits & ~TransferringResultMask),
clangTypeInfo, globalActor, thrownError,
lifetimeDependenceInfo);
[[nodiscard]] ASTExtInfoBuilder withSendingResult(bool sending = true) const {
return ASTExtInfoBuilder(
sending ? (bits | SendingResultMask) : (bits & ~SendingResultMask),
clangTypeInfo, globalActor, thrownError, lifetimeDependenceInfo);
}

[[nodiscard]]
Expand Down Expand Up @@ -765,9 +761,7 @@ class ASTExtInfo {

constexpr bool isThrowing() const { return builder.isThrowing(); }

constexpr bool hasTransferringResult() const {
return builder.hasTransferringResult();
}
constexpr bool hasSendingResult() const { return builder.hasSendingResult(); }

constexpr DifferentiabilityKind getDifferentiabilityKind() const {
return builder.getDifferentiabilityKind();
Expand Down Expand Up @@ -838,9 +832,8 @@ class ASTExtInfo {
return builder.withAsync(async).build();
}

[[nodiscard]] ASTExtInfo
withTransferringResult(bool transferring = true) const {
return builder.withTransferringResult(transferring).build();
[[nodiscard]] ASTExtInfo withSendingResult(bool sending = true) const {
return builder.withSendingResult(sending).build();
}

[[nodiscard]]
Expand Down
4 changes: 2 additions & 2 deletions include/swift/AST/PrintOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,8 @@ struct PrintOptions {
/// Suppress 'isolated' and '#isolation' on isolated parameters with optional type.
bool SuppressOptionalIsolatedParams = false;

/// Suppress 'transferring' on arguments and results.
bool SuppressTransferringArgsAndResults = false;
/// Suppress 'sending' on arguments and results.
bool SuppressSendingArgsAndResults = false;

/// Suppress Noncopyable generics.
bool SuppressNoncopyableGenerics = false;
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/TypeAttr.def
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ SIMPLE_SIL_TYPE_ATTR(captures_generics, CapturesGenerics)
// Used at the SIL level to mark a type as moveOnly.
SIMPLE_SIL_TYPE_ATTR(moveOnly, MoveOnly)
SIMPLE_SIL_TYPE_ATTR(sil_isolated, SILIsolated)
SIMPLE_SIL_TYPE_ATTR(sil_transferring, SILTransferring)
SIMPLE_SIL_TYPE_ATTR(sil_sending, SILSending)

// SIL metatype attributes.
SIMPLE_SIL_TYPE_ATTR(thin, Thin)
Expand Down
19 changes: 18 additions & 1 deletion include/swift/AST/TypeRepr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,8 @@ class SpecifierTypeRepr : public TypeRepr {
T->getKind() == TypeReprKind::CompileTimeConst ||
T->getKind() == TypeReprKind::ResultDependsOn ||
T->getKind() == TypeReprKind::LifetimeDependentReturn ||
T->getKind() == TypeReprKind::Transferring;
T->getKind() == TypeReprKind::Transferring ||
T->getKind() == TypeReprKind::Sending;
}
static bool classof(const SpecifierTypeRepr *T) { return true; }

Expand Down Expand Up @@ -1217,6 +1218,21 @@ class TransferringTypeRepr : public SpecifierTypeRepr {
static bool classof(const TransferringTypeRepr *T) { return true; }
};

/// A sending type.
/// \code
/// x : sending Int
/// \endcode
class SendingTypeRepr : public SpecifierTypeRepr {
public:
SendingTypeRepr(TypeRepr *Base, SourceLoc Loc)
: SpecifierTypeRepr(TypeReprKind::Sending, Base, Loc) {}

static bool classof(const TypeRepr *T) {
return T->getKind() == TypeReprKind::Sending;
}
static bool classof(const SendingTypeRepr *T) { return true; }
};

/// A TypeRepr for a known, fixed type.
///
/// Fixed type representations should be used sparingly, in places
Expand Down Expand Up @@ -1618,6 +1634,7 @@ inline bool TypeRepr::isSimple() const {
case TypeReprKind::SILBox:
case TypeReprKind::Isolated:
case TypeReprKind::Transferring:
case TypeReprKind::Sending:
case TypeReprKind::Placeholder:
case TypeReprKind::CompileTimeConst:
case TypeReprKind::ResultDependsOn:
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/TypeReprNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ ABSTRACT_TYPEREPR(Specifier, TypeRepr)
SPECIFIER_TYPEREPR(CompileTimeConst, SpecifierTypeRepr)
SPECIFIER_TYPEREPR(ResultDependsOn, SpecifierTypeRepr)
SPECIFIER_TYPEREPR(Transferring, SpecifierTypeRepr)
SPECIFIER_TYPEREPR(Sending, SpecifierTypeRepr)
TYPEREPR(Fixed, TypeRepr)
TYPEREPR(SILBox, TypeRepr)
TYPEREPR(Self, TypeRepr)
Expand Down
Loading