Skip to content

Commit 3585126

Browse files
authored
Merge pull request #11074 from CodaFi/the-sharing-economy
Staging for __shared and __owned
2 parents a5cf777 + 4babbe9 commit 3585126

Some content is hidden

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

45 files changed

+442
-141
lines changed

docs/ABI.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,8 @@ Types
10391039
type-list ::= list-type '_' list-type* // list of types
10401040
type-list ::= empty-list
10411041

1042-
list-type ::= type identifier? 'z'? 'd'? // type with optional label, inout convention and variadic specifier
1042+
// FIXME: Consider replacing 'h' with a two-char code
1043+
list-type ::= type identifier? 'z'? 'h'? 'd'? // type with optional label, inout convention, shared convention, and variadic specifier
10431044

10441045
METATYPE-REPR ::= 't' // Thin metatype representation
10451046
METATYPE-REPR ::= 'T' // Thick metatype representation

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4336,6 +4336,7 @@ class VarDecl : public AbstractStorageDecl {
43364336

43374337
Owned = Let,
43384338
InOut = 2,
4339+
Shared = 3,
43394340
};
43404341

43414342
protected:
@@ -4486,6 +4487,8 @@ class VarDecl : public AbstractStorageDecl {
44864487

44874488
/// Is this an immutable 'let' property?
44884489
bool isLet() const { return getSpecifier() == Specifier::Let; }
4490+
/// Is this an immutable 'shared' property?
4491+
bool isShared() const { return getSpecifier() == Specifier::Shared; }
44894492

44904493
/// Is this an element in a capture list?
44914494
bool isCaptureList() const { return VarDeclBits.IsCaptureList; }

include/swift/AST/DiagnosticsParse.def

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -811,8 +811,8 @@ ERROR(extra_var_in_multiple_pattern_list,none,
811811
"%0 must be bound in every pattern", (Identifier))
812812
ERROR(let_pattern_in_immutable_context,none,
813813
"'let' pattern cannot appear nested in an already immutable context", ())
814-
ERROR(inout_must_have_type,none,
815-
"'inout' arguments must have a type specified", ())
814+
ERROR(specifier_must_have_type,none,
815+
"%0 arguments must have a type specified", (StringRef))
816816
ERROR(expected_rparen_parameter,PointsToFirstBadToken,
817817
"expected ')' in parameter", ())
818818
ERROR(expected_parameter_type,PointsToFirstBadToken,
@@ -828,13 +828,14 @@ ERROR(multiple_parameter_ellipsis,none,
828828
ERROR(parameter_vararg_default,none,
829829
"variadic parameter cannot have a default value", ())
830830
ERROR(inout_as_attr_disallowed,none,
831-
"'inout' before a parameter name is not allowed, place it before the parameter type instead",
832-
())
833-
ERROR(parameter_inout_var_let_repeated,none,
834-
"parameter may not have multiple 'inout', 'var', or 'let' specifiers",
835-
())
831+
"%0 before a parameter name is not allowed, place it before the parameter type instead",
832+
(StringRef))
833+
ERROR(parameter_specifier_repeated,none,
834+
"parameter may not have multiple '__owned', 'inout', '__shared',"
835+
" 'var', or 'let' specifiers", ())
836836
ERROR(parameter_let_var_as_attr,none,
837-
"'%select{var|let}0' as a parameter attribute is not allowed", (unsigned))
837+
"'%0' as a parameter attribute is not allowed",
838+
(StringRef))
838839

839840

840841
ERROR(expected_behavior_name,none,

include/swift/AST/PrintOptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ struct PrintOptions {
221221

222222
/// Whether to skip placeholder members.
223223
bool SkipMissingMemberPlaceholders = true;
224-
224+
225225
/// Whether to print a long attribute like '\@available' on a separate line
226226
/// from the declaration or other attributes.
227227
bool PrintLongAttrsOnSeparateLines = false;
@@ -328,6 +328,9 @@ struct PrintOptions {
328328
llvm::Optional<TypeTransformContext> TransformContext;
329329

330330
bool PrintAsMember = false;
331+
332+
/// Whether to print parameter specifiers as 'let' and 'var'.
333+
bool PrintParameterSpecifiers = false;
331334

332335
/// \see ShouldQualifyNestedDeclarations
333336
enum class QualifyNestedDeclarations {
@@ -488,6 +491,7 @@ struct PrintOptions {
488491
PO.SkipPrivateStdlibDecls = true;
489492
PO.ExplodeEnumCaseDecls = true;
490493
PO.ShouldQualifyNestedDeclarations = QualifyNestedDeclarations::TypesOnly;
494+
PO.PrintParameterSpecifiers = true;
491495
return PO;
492496
}
493497
};

include/swift/AST/TypeRepr.h

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -833,34 +833,62 @@ class ProtocolTypeRepr : public TypeRepr {
833833
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
834834
friend class TypeRepr;
835835
};
836-
837-
/// \brief An 'inout' type.
838-
/// \code
839-
/// inout x : Int
840-
/// \endcode
841-
class InOutTypeRepr : public TypeRepr {
836+
837+
class SpecifierTypeRepr : public TypeRepr {
842838
TypeRepr *Base;
843-
SourceLoc InOutLoc;
839+
SourceLoc SpecifierLoc;
844840

845841
public:
846-
InOutTypeRepr(TypeRepr *Base, SourceLoc InOutLoc)
847-
: TypeRepr(TypeReprKind::InOut), Base(Base), InOutLoc(InOutLoc) {
842+
SpecifierTypeRepr(TypeReprKind Kind, TypeRepr *Base, SourceLoc Loc)
843+
: TypeRepr(Kind), Base(Base), SpecifierLoc(Loc) {
848844
}
849845

850846
TypeRepr *getBase() const { return Base; }
851-
SourceLoc getInOutLoc() const { return InOutLoc; }
847+
SourceLoc getSpecifierLoc() const { return SpecifierLoc; }
852848

853849
static bool classof(const TypeRepr *T) {
854-
return T->getKind() == TypeReprKind::InOut;
850+
return T->getKind() == TypeReprKind::InOut
851+
|| T->getKind() == TypeReprKind::Shared;
855852
}
856-
static bool classof(const InOutTypeRepr *T) { return true; }
853+
static bool classof(const SpecifierTypeRepr *T) { return true; }
857854

858855
private:
859-
SourceLoc getStartLocImpl() const { return InOutLoc; }
856+
SourceLoc getStartLocImpl() const { return SpecifierLoc; }
860857
SourceLoc getEndLocImpl() const { return Base->getEndLoc(); }
861858
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
862859
friend class TypeRepr;
863860
};
861+
862+
/// \brief An 'inout' type.
863+
/// \code
864+
/// x : inout Int
865+
/// \endcode
866+
class InOutTypeRepr : public SpecifierTypeRepr {
867+
public:
868+
InOutTypeRepr(TypeRepr *Base, SourceLoc InOutLoc)
869+
: SpecifierTypeRepr(TypeReprKind::InOut, Base, InOutLoc) {}
870+
871+
static bool classof(const TypeRepr *T) {
872+
return T->getKind() == TypeReprKind::InOut;
873+
}
874+
static bool classof(const InOutTypeRepr *T) { return true; }
875+
};
876+
877+
/// \brief A 'shared' type.
878+
/// \code
879+
/// x : shared Int
880+
/// \endcode
881+
class SharedTypeRepr : public SpecifierTypeRepr {
882+
public:
883+
SharedTypeRepr(TypeRepr *Base, SourceLoc SharedLoc)
884+
: SpecifierTypeRepr(TypeReprKind::Shared, Base, SharedLoc) {}
885+
886+
static bool classof(const TypeRepr *T) {
887+
return T->getKind() == TypeReprKind::Shared;
888+
}
889+
static bool classof(const SharedTypeRepr *T) { return true; }
890+
};
891+
864892

865893
/// \brief A TypeRepr for a known, fixed type.
866894
///
@@ -997,6 +1025,7 @@ inline bool TypeRepr::isSimple() const {
9971025
case TypeReprKind::Fixed:
9981026
case TypeReprKind::Array:
9991027
case TypeReprKind::SILBox:
1028+
case TypeReprKind::Shared:
10001029
return true;
10011030
}
10021031
llvm_unreachable("bad TypeRepr kind");

include/swift/AST/TypeReprNodes.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ TYPEREPR(Tuple, TypeRepr)
4949
TYPEREPR(Composition, TypeRepr)
5050
TYPEREPR(Metatype, TypeRepr)
5151
TYPEREPR(Protocol, TypeRepr)
52-
TYPEREPR(InOut, TypeRepr)
52+
ABSTRACT_TYPEREPR(Specifier, TypeRepr)
53+
TYPEREPR(InOut, SpecifierTypeRepr)
54+
TYPEREPR(Shared, SpecifierTypeRepr)
5355
TYPEREPR(Fixed, TypeRepr)
5456
TYPEREPR(SILBox, TypeRepr)
5557

include/swift/AST/Types.h

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,8 +1399,9 @@ class ParameterTypeFlags {
13991399
AutoClosure = 1 << 1,
14001400
Escaping = 1 << 2,
14011401
InOut = 1 << 3,
1402-
1403-
NumBits = 4
1402+
Shared = 1 << 4,
1403+
1404+
NumBits = 5
14041405
};
14051406
OptionSet<ParameterFlags> value;
14061407
static_assert(NumBits < 8*sizeof(OptionSet<ParameterFlags>), "overflowed");
@@ -1410,22 +1411,25 @@ class ParameterTypeFlags {
14101411
public:
14111412
ParameterTypeFlags() = default;
14121413

1413-
ParameterTypeFlags(bool variadic, bool autoclosure, bool escaping, bool inOut)
1414+
ParameterTypeFlags(bool variadic, bool autoclosure, bool escaping, bool inOut, bool shared)
14141415
: value((variadic ? Variadic : 0) |
14151416
(autoclosure ? AutoClosure : 0) |
14161417
(escaping ? Escaping : 0) |
1417-
(inOut ? InOut : 0)) {}
1418+
(inOut ? InOut : 0) |
1419+
(shared ? Shared : 0)) {}
14181420

14191421
/// Create one from what's present in the parameter type
14201422
inline static ParameterTypeFlags fromParameterType(Type paramTy,
1421-
bool isVariadic);
1423+
bool isVariadic,
1424+
bool isShared);
14221425

14231426
bool isNone() const { return !value; }
14241427
bool isVariadic() const { return value.contains(Variadic); }
14251428
bool isAutoClosure() const { return value.contains(AutoClosure); }
14261429
bool isEscaping() const { return value.contains(Escaping); }
14271430
bool isInOut() const { return value.contains(InOut); }
1428-
1431+
bool isShared() const { return value.contains(Shared); }
1432+
14291433
ParameterTypeFlags withEscaping(bool escaping) const {
14301434
return ParameterTypeFlags(escaping ? value | ParameterTypeFlags::Escaping
14311435
: value - ParameterTypeFlags::Escaping);
@@ -1435,6 +1439,11 @@ class ParameterTypeFlags {
14351439
return ParameterTypeFlags(isInout ? value | ParameterTypeFlags::InOut
14361440
: value - ParameterTypeFlags::InOut);
14371441
}
1442+
1443+
ParameterTypeFlags withShared(bool isShared) const {
1444+
return ParameterTypeFlags(isShared ? value | ParameterTypeFlags::Shared
1445+
: value - ParameterTypeFlags::Shared);
1446+
}
14381447

14391448
bool operator ==(const ParameterTypeFlags &other) const {
14401449
return value.toRaw() == other.value.toRaw();
@@ -2354,6 +2363,9 @@ class AnyFunctionType : public TypeBase {
23542363

23552364
/// Whether the parameter is marked 'inout'
23562365
bool isInOut() const { return Flags.isInOut(); }
2366+
2367+
/// Whether the parameter is marked 'shared'
2368+
bool isShared() const { return Flags.isShared(); }
23572369
};
23582370

23592371
class CanParam : public Param {
@@ -4795,7 +4807,7 @@ inline TupleTypeElt TupleTypeElt::getWithType(Type T) const {
47954807

47964808
/// Create one from what's present in the parameter decl and type
47974809
inline ParameterTypeFlags
4798-
ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic) {
4810+
ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic, bool isShared) {
47994811
bool autoclosure = paramTy->is<AnyFunctionType>() &&
48004812
paramTy->castTo<AnyFunctionType>()->isAutoClosure();
48014813
bool escaping = paramTy->is<AnyFunctionType>() &&
@@ -4805,7 +4817,7 @@ ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic) {
48054817
// callers, then remove this, then remove
48064818
// ParameterTypeFlags::fromParameterType entirely.
48074819
bool inOut = paramTy->is<InOutType>();
4808-
return {isVariadic, autoclosure, escaping, inOut};
4820+
return {isVariadic, autoclosure, escaping, inOut, isShared};
48094821
}
48104822

48114823
/// \brief If this is a method in a type or extension thereof, compute

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ NODE(QualifiedArchetype)
135135
NODE(ReabstractionThunk)
136136
NODE(ReabstractionThunkHelper)
137137
NODE(ReturnType)
138+
NODE(Shared)
138139
NODE(SILBoxType)
139140
NODE(SILBoxTypeWithLayout)
140141
NODE(SILBoxLayout)

include/swift/Parse/Parser.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -756,12 +756,15 @@ class Parser {
756756
bool parseVersionTuple(clang::VersionTuple &Version, SourceRange &Range,
757757
const Diagnostic &D);
758758

759-
bool parseTypeAttributeList(SourceLoc &InOutLoc, TypeAttributes &Attributes) {
760-
if (Tok.is(tok::at_sign) || Tok.is(tok::kw_inout))
761-
return parseTypeAttributeListPresent(InOutLoc, Attributes);
759+
bool parseTypeAttributeList(VarDecl::Specifier &Specifier,
760+
SourceLoc &SpecifierLoc,
761+
TypeAttributes &Attributes) {
762+
if (Tok.isAny(tok::at_sign, tok::kw_inout, tok::kw___shared, tok::kw___owned))
763+
return parseTypeAttributeListPresent(Specifier, SpecifierLoc, Attributes);
762764
return false;
763765
}
764-
bool parseTypeAttributeListPresent(SourceLoc &InOutLoc,
766+
bool parseTypeAttributeListPresent(VarDecl::Specifier &Specifier,
767+
SourceLoc &SpecifierLoc,
765768
TypeAttributes &Attributes);
766769
bool parseTypeAttribute(TypeAttributes &Attributes,
767770
bool justChecking = false);
@@ -933,8 +936,9 @@ class Parser {
933936
bool isImplicitlyUnwrappedOptionalToken(const Token &T) const;
934937
SourceLoc consumeImplicitlyUnwrappedOptionalToken();
935938

936-
TypeRepr *applyAttributeToType(TypeRepr *Ty, SourceLoc InOutLoc,
937-
const TypeAttributes &Attr);
939+
TypeRepr *applyAttributeToType(TypeRepr *Ty, const TypeAttributes &Attr,
940+
VarDecl::Specifier Specifier,
941+
SourceLoc SpecifierLoc);
938942

939943
//===--------------------------------------------------------------------===//
940944
// Pattern Parsing

include/swift/Parse/Token.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,11 @@ class Token {
178178
if (is(tok::identifier) || isEscapedIdentifier() || is(tok::kw__))
179179
return true;
180180

181-
// 'let', 'var', and 'inout' cannot be argument labels.
182-
if (isAny(tok::kw_let, tok::kw_var, tok::kw_inout)) return false;
181+
// 'let', 'var', 'inout', '__shared', and '__owned'
182+
// cannot be argument labels.
183+
if (isAny(tok::kw_let, tok::kw_var, tok::kw_inout,
184+
tok::kw___owned, tok::kw___shared))
185+
return false;
183186

184187
// All other keywords can be argument labels.
185188
return isKeyword();

include/swift/Serialization/ModuleFormat.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
57-
const uint16_t VERSION_MINOR = 351; // Last change: open_existential_box_value
57+
const uint16_t VERSION_MINOR = 352; // Last change: 'shared' type attribute
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;
@@ -195,6 +195,7 @@ enum class VarDeclSpecifier : uint8_t {
195195
Let = 0,
196196
Var,
197197
InOut,
198+
Shared,
198199
};
199200
using VarDeclSpecifierField = BCFixed<2>;
200201

@@ -617,7 +618,8 @@ namespace decls_block {
617618
BCFixed<1>, // vararg?
618619
BCFixed<1>, // autoclosure?
619620
BCFixed<1>, // escaping?
620-
BCFixed<1> // inout?
621+
BCFixed<1>, // inout?
622+
BCFixed<1> // shared?
621623
>;
622624

623625
using TupleTypeLayout = BCRecordLayout<
@@ -631,7 +633,8 @@ namespace decls_block {
631633
BCFixed<1>, // vararg?
632634
BCFixed<1>, // autoclosure?
633635
BCFixed<1>, // escaping?
634-
BCFixed<1> // inout?
636+
BCFixed<1>, // inout?
637+
BCFixed<1> // shared?
635638
>;
636639

637640
using FunctionTypeLayout = BCRecordLayout<

include/swift/Syntax/TokenKinds.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ DECL_KEYWORD(struct)
140140
DECL_KEYWORD(subscript)
141141
DECL_KEYWORD(typealias)
142142
DECL_KEYWORD(var)
143+
DECL_KEYWORD(__shared)
144+
DECL_KEYWORD(__owned)
143145

144146
DECL_KEYWORD(fileprivate)
145147
DECL_KEYWORD(internal)

lib/AST/ASTContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3271,7 +3271,7 @@ void AnyFunctionType::decomposeInput(
32713271
// assert(type->is<InOutType>() && "Found naked inout type");
32723272
result.push_back(AnyFunctionType::Param(type->getInOutObjectType(),
32733273
Identifier(),
3274-
ParameterTypeFlags::fromParameterType(type, false)));
3274+
ParameterTypeFlags::fromParameterType(type, false, false)));
32753275
return;
32763276
}
32773277
}

lib/AST/ASTDumper.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,8 +941,12 @@ namespace {
941941
PrintWithColorRAII(OS, InterfaceTypeColor) << "'";
942942
}
943943

944-
if (!P->isLet())
944+
if (P->getSpecifier() == VarDecl::Specifier::Var)
945945
OS << " mutable";
946+
if (P->getSpecifier() == VarDecl::Specifier::InOut)
947+
OS << " inout";
948+
if (P->isShared())
949+
OS << " shared";
946950

947951
if (P->isVariadic())
948952
OS << " variadic";
@@ -2683,6 +2687,12 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {
26832687
printRec(T->getBase());
26842688
PrintWithColorRAII(OS, ParenthesisColor) << ')';
26852689
}
2690+
2691+
void visitSharedTypeRepr(SharedTypeRepr *T) {
2692+
printCommon("type_shared") << '\n';
2693+
printRec(T->getBase());
2694+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2695+
}
26862696
};
26872697

26882698
} // end anonymous namespace

0 commit comments

Comments
 (0)