Skip to content

Commit b330c60

Browse files
authored
Merge pull request swiftlang#14948 from huonw/at-owned
Make __owned functional, maybe
2 parents 63544b5 + b1115af commit b330c60

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+535
-300
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ Types
396396
type-list ::= empty-list
397397

398398
// FIXME: Consider replacing 'h' with a two-char code
399-
list-type ::= type identifier? 'z'? 'h'? 'd'? // type with optional label, inout convention, shared convention, and variadic specifier
399+
list-type ::= type identifier? 'z'? 'h'? 'n'? 'd'? // type with optional label, inout convention, shared convention, owned convention, and variadic specifier
400400

401401
METATYPE-REPR ::= 't' // Thin metatype representation
402402
METATYPE-REPR ::= 'T' // Thick metatype representation

include/swift/ABI/MetadataValues.h

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -644,26 +644,18 @@ using FunctionTypeFlags = TargetFunctionTypeFlags<size_t>;
644644

645645
template <typename int_type>
646646
class TargetParameterTypeFlags {
647-
enum : int_type {
648-
InOutMask = 1 << 0,
649-
SharedMask = 1 << 1,
650-
VariadicMask = 1 << 2,
651-
};
647+
enum : int_type { ValueOwnershipMask = 0x7F, VariadicMask = 0x80 };
652648
int_type Data;
653649

654650
constexpr TargetParameterTypeFlags(int_type Data) : Data(Data) {}
655651

656652
public:
657653
constexpr TargetParameterTypeFlags() : Data(0) {}
658654

659-
constexpr TargetParameterTypeFlags<int_type> withInOut(bool isInOut) const {
660-
return TargetParameterTypeFlags<int_type>((Data & ~InOutMask) |
661-
(isInOut ? InOutMask : 0));
662-
}
663-
664-
constexpr TargetParameterTypeFlags<int_type> withShared(bool isShared) const {
665-
return TargetParameterTypeFlags<int_type>((Data & ~SharedMask) |
666-
(isShared ? SharedMask : 0));
655+
constexpr TargetParameterTypeFlags<int_type>
656+
withValueOwnership(ValueOwnership ownership) const {
657+
return TargetParameterTypeFlags<int_type>((Data & ~ValueOwnershipMask) |
658+
(int_type)ownership);
667659
}
668660

669661
constexpr TargetParameterTypeFlags<int_type>
@@ -673,10 +665,12 @@ class TargetParameterTypeFlags {
673665
}
674666

675667
bool isNone() const { return Data == 0; }
676-
bool isInOut() const { return Data & InOutMask; }
677-
bool isShared() const { return Data & SharedMask; }
678668
bool isVariadic() const { return Data & VariadicMask; }
679669

670+
ValueOwnership getValueOwnership() const {
671+
return (ValueOwnership)(Data & ValueOwnershipMask);
672+
}
673+
680674
int_type getIntValue() const { return Data; }
681675

682676
static TargetParameterTypeFlags<int_type> fromIntValue(int_type Data) {

include/swift/AST/Decl.h

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,14 @@ class alignas(1 << DeclAlignInBits) Decl {
316316
StorageKind : 4
317317
);
318318

319-
SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+2+1+1+1,
319+
SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+4+1+1+1,
320320
/// \brief Whether this property is a type property (currently unfortunately
321321
/// called 'static').
322322
IsStatic : 1,
323323

324324
/// \brief The specifier associated with this variable or parameter. This
325325
/// determines the storage semantics of the value e.g. mutability.
326-
Specifier : 2,
326+
Specifier : 4,
327327

328328
/// \brief Whether this declaration was an element of a capture list.
329329
IsCaptureList : 1,
@@ -4445,17 +4445,18 @@ class VarDecl : public AbstractStorageDecl {
44454445
public:
44464446
enum class Specifier : uint8_t {
44474447
// For Var Decls
4448-
4449-
Let = 0,
4450-
Var = 1,
4451-
4448+
4449+
Let = 0,
4450+
Var = 1,
4451+
44524452
// For Param Decls
4453-
4454-
Owned = Let,
4453+
4454+
Default = Let,
44554455
InOut = 2,
44564456
Shared = 3,
4457+
Owned = 4,
44574458
};
4458-
4459+
44594460
protected:
44604461
llvm::PointerUnion<PatternBindingDecl*, Stmt*> ParentPattern;
44614462

@@ -4602,10 +4603,23 @@ class VarDecl : public AbstractStorageDecl {
46024603
/// \returns the way 'static'/'class' should be spelled for this declaration.
46034604
StaticSpellingKind getCorrectStaticSpelling() const;
46044605

4606+
bool isImmutable() const {
4607+
switch (getSpecifier()) {
4608+
case Specifier::Let:
4609+
case Specifier::Shared:
4610+
case Specifier::Owned:
4611+
return true;
4612+
case Specifier::Var:
4613+
case Specifier::InOut:
4614+
return false;
4615+
}
4616+
}
46054617
/// Is this an immutable 'let' property?
46064618
bool isLet() const { return getSpecifier() == Specifier::Let; }
46074619
/// Is this an immutable 'shared' property?
46084620
bool isShared() const { return getSpecifier() == Specifier::Shared; }
4621+
/// Is this an immutable 'owned' property?
4622+
bool isOwned() const { return getSpecifier() == Specifier::Owned; }
46094623

46104624
ValueOwnership getValueOwnership() const {
46114625
switch (getSpecifier()) {
@@ -4617,6 +4631,8 @@ class VarDecl : public AbstractStorageDecl {
46174631
return ValueOwnership::InOut;
46184632
case Specifier::Shared:
46194633
return ValueOwnership::Shared;
4634+
case Specifier::Owned:
4635+
return ValueOwnership::Owned;
46204636
}
46214637
}
46224638

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -855,8 +855,8 @@ ERROR(multiple_parameter_ellipsis,none,
855855
"only a single variadic parameter '...' is permitted", ())
856856
ERROR(parameter_vararg_default,none,
857857
"variadic parameter cannot have a default value", ())
858-
ERROR(inout_as_attr_disallowed,none,
859-
"%0 before a parameter name is not allowed, place it before the parameter type instead",
858+
ERROR(parameter_specifier_as_attr_disallowed,none,
859+
"'%0' before a parameter name is not allowed, place it before the parameter type instead",
860860
(StringRef))
861861
ERROR(parameter_specifier_repeated,none,
862862
"parameter must not have multiple '__owned', 'inout', '__shared',"

include/swift/AST/Ownership.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,15 @@ enum class ReferenceOwnership : uint8_t {
4242

4343
/// Different kinds of value ownership supported by Swift.
4444
enum class ValueOwnership : uint8_t {
45-
/// \brief the default ownership (owned)
45+
/// \brief the context-dependent default ownership (sometimes shared,
46+
/// sometimes owned)
4647
Default,
4748
/// \brief an 'inout' mutating pointer-like value
4849
InOut,
4950
/// \brief a '__shared' non-mutating pointer-like value
50-
Shared
51+
Shared,
52+
/// \brief an '__owned' value
53+
Owned
5154
};
5255

5356
} // end namespace swift

include/swift/AST/TypeRepr.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,8 +901,9 @@ class SpecifierTypeRepr : public TypeRepr {
901901
SourceLoc getSpecifierLoc() const { return SpecifierLoc; }
902902

903903
static bool classof(const TypeRepr *T) {
904-
return T->getKind() == TypeReprKind::InOut
905-
|| T->getKind() == TypeReprKind::Shared;
904+
return T->getKind() == TypeReprKind::InOut ||
905+
T->getKind() == TypeReprKind::Shared ||
906+
T->getKind() == TypeReprKind::Owned;
906907
}
907908
static bool classof(const SpecifierTypeRepr *T) { return true; }
908909

@@ -943,6 +944,20 @@ class SharedTypeRepr : public SpecifierTypeRepr {
943944
static bool classof(const SharedTypeRepr *T) { return true; }
944945
};
945946

947+
/// \brief A 'owned' type.
948+
/// \code
949+
/// x : owned Int
950+
/// \endcode
951+
class OwnedTypeRepr : public SpecifierTypeRepr {
952+
public:
953+
OwnedTypeRepr(TypeRepr *Base, SourceLoc OwnedLoc)
954+
: SpecifierTypeRepr(TypeReprKind::Owned, Base, OwnedLoc) {}
955+
956+
static bool classof(const TypeRepr *T) {
957+
return T->getKind() == TypeReprKind::Owned;
958+
}
959+
static bool classof(const OwnedTypeRepr *T) { return true; }
960+
};
946961

947962
/// \brief A TypeRepr for a known, fixed type.
948963
///
@@ -1080,6 +1095,7 @@ inline bool TypeRepr::isSimple() const {
10801095
case TypeReprKind::Array:
10811096
case TypeReprKind::SILBox:
10821097
case TypeReprKind::Shared:
1098+
case TypeReprKind::Owned:
10831099
return true;
10841100
}
10851101
llvm_unreachable("bad TypeRepr kind");

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ TYPEREPR(Protocol, TypeRepr)
5656
ABSTRACT_TYPEREPR(Specifier, TypeRepr)
5757
TYPEREPR(InOut, SpecifierTypeRepr)
5858
TYPEREPR(Shared, SpecifierTypeRepr)
59+
TYPEREPR(Owned, SpecifierTypeRepr)
5960
TYPEREPR(Fixed, TypeRepr)
6061
TYPEREPR(SILBox, TypeRepr)
6162
LAST_TYPEREPR(SILBox)

include/swift/AST/Types.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,8 +1580,9 @@ class ParameterTypeFlags {
15801580
Escaping = 1 << 2,
15811581
InOut = 1 << 3,
15821582
Shared = 1 << 4,
1583+
Owned = 1 << 5,
15831584

1584-
NumBits = 5
1585+
NumBits = 6
15851586
};
15861587
OptionSet<ParameterFlags> value;
15871588
static_assert(NumBits < 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
@@ -1599,7 +1600,8 @@ class ParameterTypeFlags {
15991600
: value((variadic ? Variadic : 0) | (autoclosure ? AutoClosure : 0) |
16001601
(escaping ? Escaping : 0) |
16011602
(ownership == ValueOwnership::InOut ? InOut : 0) |
1602-
(ownership == ValueOwnership::Shared ? Shared : 0)) {}
1603+
(ownership == ValueOwnership::Shared ? Shared : 0) |
1604+
(ownership == ValueOwnership::Owned ? Owned : 0)) {}
16031605

16041606
/// Create one from what's present in the parameter type
16051607
inline static ParameterTypeFlags
@@ -1611,12 +1613,15 @@ class ParameterTypeFlags {
16111613
bool isEscaping() const { return value.contains(Escaping); }
16121614
bool isInOut() const { return value.contains(InOut); }
16131615
bool isShared() const { return value.contains(Shared); }
1616+
bool isOwned() const { return value.contains(Owned); }
16141617

16151618
ValueOwnership getValueOwnership() const {
16161619
if (isInOut())
16171620
return ValueOwnership::InOut;
16181621
else if (isShared())
16191622
return ValueOwnership::Shared;
1623+
else if (isOwned())
1624+
return ValueOwnership::Owned;
16201625

16211626
return ValueOwnership::Default;
16221627
}
@@ -1641,6 +1646,11 @@ class ParameterTypeFlags {
16411646
: value - ParameterTypeFlags::Shared);
16421647
}
16431648

1649+
ParameterTypeFlags withOwned(bool isOwned) const {
1650+
return ParameterTypeFlags(isOwned ? value | ParameterTypeFlags::Owned
1651+
: value - ParameterTypeFlags::Owned);
1652+
}
1653+
16441654
bool operator ==(const ParameterTypeFlags &other) const {
16451655
return value.toRaw() == other.value.toRaw();
16461656
}
@@ -2530,6 +2540,9 @@ class AnyFunctionType : public TypeBase {
25302540

25312541
/// Whether the parameter is marked 'shared'
25322542
bool isShared() const { return Flags.isShared(); }
2543+
2544+
/// Whether the parameter is marked 'owned'
2545+
bool isOwned() const { return Flags.isOwned(); }
25332546
};
25342547

25352548
class CanParam : public Param {

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ NODE(RelatedEntityDeclName)
150150
NODE(RetroactiveConformance)
151151
NODE(ReturnType)
152152
NODE(Shared)
153+
NODE(Owned)
153154
NODE(SILBoxType)
154155
NODE(SILBoxTypeWithLayout)
155156
NODE(SILBoxLayout)

include/swift/Demangling/TypeDecoder.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ class FunctionParam {
5656
void setType(BuiltType type) { Type = type; }
5757

5858
void setVariadic() { Flags = Flags.withVariadic(true); }
59-
void setShared() { Flags = Flags.withShared(true); }
60-
void setInOut() { Flags = Flags.withInOut(true); }
59+
void setValueOwnership(ValueOwnership ownership) {
60+
Flags = Flags.withValueOwnership(ownership);
61+
}
6162
void setFlags(ParameterFlags flags) { Flags = flags; };
6263

6364
FunctionParam withLabel(StringRef label) const {
@@ -531,17 +532,23 @@ class TypeDecoder {
531532
[&](const Demangle::NodePointer &typeNode,
532533
FunctionParam<BuiltType> &param) -> bool {
533534
Demangle::NodePointer node = typeNode;
534-
switch (node->getKind()) {
535-
case NodeKind::InOut:
536-
param.setInOut();
535+
536+
auto setOwnership = [&](ValueOwnership ownership) {
537+
param.setValueOwnership(ownership);
537538
node = node->getFirstChild();
538539
hasParamFlags = true;
540+
};
541+
switch (node->getKind()) {
542+
case NodeKind::InOut:
543+
setOwnership(ValueOwnership::InOut);
539544
break;
540545

541546
case NodeKind::Shared:
542-
param.setShared();
543-
hasParamFlags = true;
544-
node = node->getFirstChild();
547+
setOwnership(ValueOwnership::Shared);
548+
break;
549+
550+
case NodeKind::Owned:
551+
setOwnership(ValueOwnership::Owned);
545552
break;
546553

547554
default:

0 commit comments

Comments
 (0)