Skip to content

Commit 1311df6

Browse files
committed
AST: Combine various ownership TypeReprs into one OwnershipTypeRepr.
This lets us consolidate code paths that mostly run in parallel over the existing InOutTypeRepr/SharedTypeRepr/OwnedTypeRepr family of types. This patch by itself is NFC but makes it easier to introduce new spellings, particularly the newly-official `borrowing` and `consuming` modifiers that were approved in SE-0377.
1 parent 0c23901 commit 1311df6

File tree

13 files changed

+118
-174
lines changed

13 files changed

+118
-174
lines changed

include/swift/AST/Decl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5983,10 +5983,19 @@ class VarDecl : public AbstractStorageDecl {
59835983
}
59845984
};
59855985

5986+
/// The various spellings of ownership modifier that can be used in source.
59865987
enum class ParamSpecifier : uint8_t {
5988+
/// No explicit ownership specifier was provided. The parameter will use the
5989+
/// default ownership convention for the declaration.
59875990
Default = 0,
5991+
5992+
/// `inout`, indicating exclusive mutable access to the argument for the
5993+
/// duration of a call.
59885994
InOut = 1,
5995+
5996+
/// `__shared`, a legacy spelling of `borrowing`.
59895997
Shared = 2,
5998+
/// `__owned`, a legacy spelling of `consuming`.
59905999
Owned = 3,
59916000
};
59926001

include/swift/AST/TypeRepr.h

Lines changed: 27 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ namespace swift {
4040
class TupleTypeRepr;
4141
class TypeDecl;
4242

43+
enum class ParamSpecifier : uint8_t;
44+
4345
enum class TypeReprKind : uint8_t {
4446
#define TYPEREPR(ID, PARENT) ID,
4547
#define LAST_TYPEREPR(ID) Last_TypeRepr = ID,
@@ -1062,9 +1064,7 @@ class SpecifierTypeRepr : public TypeRepr {
10621064
SourceLoc getSpecifierLoc() const { return SpecifierLoc; }
10631065

10641066
static bool classof(const TypeRepr *T) {
1065-
return T->getKind() == TypeReprKind::InOut ||
1066-
T->getKind() == TypeReprKind::Shared ||
1067-
T->getKind() == TypeReprKind::Owned ||
1067+
return T->getKind() == TypeReprKind::Ownership ||
10681068
T->getKind() == TypeReprKind::Isolated ||
10691069
T->getKind() == TypeReprKind::CompileTimeConst;
10701070
}
@@ -1077,71 +1077,40 @@ class SpecifierTypeRepr : public TypeRepr {
10771077
friend class TypeRepr;
10781078
};
10791079

1080-
// This repr holds types that are associated with some ownership specifier
1081-
// like 'inout', '__shared', etc. It's a simple grouping of those specifiers.
1082-
class OwnershipTypeRepr : public SpecifierTypeRepr {
1083-
public:
1084-
OwnershipTypeRepr(TypeReprKind Kind, TypeRepr *Base, SourceLoc OwnershipLoc)
1085-
: SpecifierTypeRepr(Kind, Base, OwnershipLoc) {
1086-
assert(OwnershipTypeRepr::classof(cast<TypeRepr>(this)));
1087-
}
1088-
1089-
static bool classof(const TypeRepr *T) {
1090-
return T->getKind() == TypeReprKind::InOut ||
1091-
T->getKind() == TypeReprKind::Shared ||
1092-
T->getKind() == TypeReprKind::Owned;
1093-
}
1094-
static bool classof(const OwnershipTypeRepr *T) { return true; }
1095-
friend class SpecifierTypeRepr;
1096-
};
1097-
1098-
/// An 'inout' type.
1080+
/// A parameter type with an ownership specifier, such as `inout`, `borrowing`,
1081+
/// or `consuming`.
10991082
/// \code
11001083
/// x : inout Int
1084+
/// y : consuming Int
1085+
/// z : borrowing Int
11011086
/// \endcode
1102-
class InOutTypeRepr : public OwnershipTypeRepr {
1087+
1088+
class OwnershipTypeRepr : public SpecifierTypeRepr {
1089+
ParamSpecifier Specifier;
11031090
public:
1104-
InOutTypeRepr(TypeRepr *Base, SourceLoc InOutLoc)
1105-
: OwnershipTypeRepr(TypeReprKind::InOut, Base, InOutLoc) {}
1091+
OwnershipTypeRepr(TypeRepr *Base, ParamSpecifier Specifier,
1092+
SourceLoc ModifierLoc)
1093+
: SpecifierTypeRepr(TypeReprKind::Ownership, Base, ModifierLoc),
1094+
Specifier(Specifier) {}
11061095

1107-
static bool classof(const TypeRepr *T) {
1108-
return T->getKind() == TypeReprKind::InOut;
1109-
}
1110-
static bool classof(const InOutTypeRepr *T) { return true; }
1111-
};
1096+
ParamSpecifier getSpecifier() const { return Specifier; }
11121097

1113-
/// A 'borrowing' parameter type.
1114-
/// \code
1115-
/// x : borrowing Int
1116-
/// \endcode
1117-
/// Historically, this attribute was spelled '__shared'.
1118-
class SharedTypeRepr : public OwnershipTypeRepr {
1119-
public:
1120-
SharedTypeRepr(TypeRepr *Base, SourceLoc SharedLoc)
1121-
: OwnershipTypeRepr(TypeReprKind::Shared, Base, SharedLoc) {}
1122-
1123-
static bool classof(const TypeRepr *T) {
1124-
return T->getKind() == TypeReprKind::Shared;
1098+
/// Return the \c ValueOwnership kind that corresponds to the specifier.
1099+
ValueOwnership getValueOwnership() const;
1100+
1101+
/// Return the spelling of the ownership specifier as a string.
1102+
StringRef getSpecifierSpelling() const {
1103+
return getSpecifierSpelling(getSpecifier());
11251104
}
1126-
static bool classof(const SharedTypeRepr *T) { return true; }
1127-
};
1128-
1129-
/// A 'consuming' parameter type.
1130-
/// \code
1131-
/// x : consuming Int
1132-
/// \endcode
1133-
/// Historically, this attribute was spelled '__owned'.
1134-
class OwnedTypeRepr : public OwnershipTypeRepr {
1135-
public:
1136-
OwnedTypeRepr(TypeRepr *Base, SourceLoc OwnedLoc)
1137-
: OwnershipTypeRepr(TypeReprKind::Owned, Base, OwnedLoc) {}
11381105

11391106
static bool classof(const TypeRepr *T) {
1140-
return T->getKind() == TypeReprKind::Owned;
1107+
return T->getKind() == TypeReprKind::Ownership;
11411108
}
1142-
static bool classof(const OwnedTypeRepr *T) { return true; }
1143-
};
1109+
static bool classof(const OwnershipTypeRepr *T) { return true; }
11441110

1111+
static StringRef getSpecifierSpelling(ParamSpecifier spell);
1112+
};
1113+
11451114
/// An 'isolated' type.
11461115
/// \code
11471116
/// x : isolated Actor
@@ -1449,7 +1418,7 @@ inline bool TypeRepr::isSimple() const {
14491418
case TypeReprKind::Attributed:
14501419
case TypeReprKind::Error:
14511420
case TypeReprKind::Function:
1452-
case TypeReprKind::InOut:
1421+
case TypeReprKind::Ownership:
14531422
case TypeReprKind::Composition:
14541423
case TypeReprKind::OpaqueReturn:
14551424
case TypeReprKind::NamedOpaqueReturn:
@@ -1471,8 +1440,6 @@ inline bool TypeRepr::isSimple() const {
14711440
case TypeReprKind::Fixed:
14721441
case TypeReprKind::Array:
14731442
case TypeReprKind::SILBox:
1474-
case TypeReprKind::Shared:
1475-
case TypeReprKind::Owned:
14761443
case TypeReprKind::Isolated:
14771444
case TypeReprKind::Placeholder:
14781445
case TypeReprKind::CompileTimeConst:

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ TYPEREPR(Pack, TypeRepr)
6969
TYPEREPR(PackElement, TypeRepr)
7070
TYPEREPR(Placeholder, TypeRepr)
7171
ABSTRACT_TYPEREPR(Specifier, TypeRepr)
72-
SPECIFIER_TYPEREPR(InOut, SpecifierTypeRepr)
73-
SPECIFIER_TYPEREPR(Shared, SpecifierTypeRepr)
74-
SPECIFIER_TYPEREPR(Owned, SpecifierTypeRepr)
72+
SPECIFIER_TYPEREPR(Ownership, SpecifierTypeRepr)
7573
SPECIFIER_TYPEREPR(Isolated, SpecifierTypeRepr)
7674
SPECIFIER_TYPEREPR(CompileTimeConst, SpecifierTypeRepr)
7775
TYPEREPR(Fixed, TypeRepr)

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3260,24 +3260,15 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {
32603260
PrintWithColorRAII(OS, ParenthesisColor) << ')';
32613261
}
32623262

3263-
void visitInOutTypeRepr(InOutTypeRepr *T) {
3264-
printCommon("type_inout") << '\n';
3263+
void visitOwnershipTypeRepr(OwnershipTypeRepr *T) {
3264+
printCommon("type_ownership")
3265+
<< ' '
3266+
<< T->getSpecifierSpelling()
3267+
<< '\n';
32653268
printRec(T->getBase());
32663269
PrintWithColorRAII(OS, ParenthesisColor) << ')';
32673270
}
32683271

3269-
void visitSharedTypeRepr(SharedTypeRepr *T) {
3270-
printCommon("type_shared") << '\n';
3271-
printRec(T->getBase());
3272-
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3273-
}
3274-
3275-
void visitOwnedTypeRepr(OwnedTypeRepr *T) {
3276-
printCommon("type_owned") << '\n';
3277-
printRec(T->getBase());
3278-
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3279-
}
3280-
32813272
void visitIsolatedTypeRepr(IsolatedTypeRepr *T) {
32823273
printCommon("isolated") << '\n';
32833274
printRec(T->getBase());

lib/AST/ASTWalker.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,15 +2069,7 @@ bool Traversal::visitProtocolTypeRepr(ProtocolTypeRepr *T) {
20692069
return doIt(T->getBase());
20702070
}
20712071

2072-
bool Traversal::visitInOutTypeRepr(InOutTypeRepr *T) {
2073-
return doIt(T->getBase());
2074-
}
2075-
2076-
bool Traversal::visitSharedTypeRepr(SharedTypeRepr *T) {
2077-
return doIt(T->getBase());
2078-
}
2079-
2080-
bool Traversal::visitOwnedTypeRepr(OwnedTypeRepr *T) {
2072+
bool Traversal::visitOwnershipTypeRepr(OwnershipTypeRepr *T) {
20812073
return doIt(T->getBase());
20822074
}
20832075

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,13 +2628,11 @@ directReferencesForTypeRepr(Evaluator &evaluator,
26282628

26292629
case TypeReprKind::Error:
26302630
case TypeReprKind::Function:
2631-
case TypeReprKind::InOut:
2631+
case TypeReprKind::Ownership:
26322632
case TypeReprKind::Isolated:
26332633
case TypeReprKind::CompileTimeConst:
26342634
case TypeReprKind::Metatype:
2635-
case TypeReprKind::Owned:
26362635
case TypeReprKind::Protocol:
2637-
case TypeReprKind::Shared:
26382636
case TypeReprKind::SILBox:
26392637
case TypeReprKind::Placeholder:
26402638
case TypeReprKind::Pack:

lib/AST/TypeRepr.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -591,15 +591,11 @@ void SpecifierTypeRepr::printImpl(ASTPrinter &Printer,
591591
#include "swift/AST/TypeReprNodes.def"
592592
llvm_unreachable("invalid repr kind");
593593
break;
594-
case TypeReprKind::InOut:
595-
Printer.printKeyword("inout", Opts, " ");
596-
break;
597-
case TypeReprKind::Shared:
598-
Printer.printKeyword("__shared", Opts, " ");
599-
break;
600-
case TypeReprKind::Owned:
601-
Printer.printKeyword("__owned", Opts, " ");
594+
case TypeReprKind::Ownership: {
595+
auto ownershipRepr = cast<OwnershipTypeRepr>(this);
596+
Printer.printKeyword(ownershipRepr->getSpecifierSpelling(), Opts, " ");
602597
break;
598+
}
603599
case TypeReprKind::Isolated:
604600
Printer.printKeyword("isolated", Opts, " ");
605601
break;
@@ -610,6 +606,34 @@ void SpecifierTypeRepr::printImpl(ASTPrinter &Printer,
610606
printTypeRepr(Base, Printer, Opts);
611607
}
612608

609+
StringRef OwnershipTypeRepr::getSpecifierSpelling(ParamSpecifier specifier) {
610+
switch (specifier) {
611+
case ParamSpecifier::InOut:
612+
return "inout";
613+
case ParamSpecifier::Shared:
614+
return "__shared";
615+
case ParamSpecifier::Owned:
616+
return "__owned";
617+
case ParamSpecifier::Default:
618+
return "";
619+
}
620+
llvm_unreachable("invalid ParamSpecifier");
621+
}
622+
623+
ValueOwnership OwnershipTypeRepr::getValueOwnership() const {
624+
switch (getSpecifier()) {
625+
case ParamSpecifier::InOut:
626+
return ValueOwnership::InOut;
627+
628+
case ParamSpecifier::Shared:
629+
return ValueOwnership::Shared;
630+
case ParamSpecifier::Owned:
631+
return ValueOwnership::Owned;
632+
case ParamSpecifier::Default:
633+
return ValueOwnership::Default;
634+
}
635+
}
636+
613637
void PlaceholderTypeRepr::printImpl(ASTPrinter &Printer,
614638
const PrintOptions &Opts) const {
615639
Printer.printText("_");

lib/Migrator/APIDiffMigratorPass.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,7 @@ class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
149149
return visit(T->getTypeRepr());
150150
}
151151

152-
FoundResult visitInOutTypeRepr(InOutTypeRepr *T) {
153-
return visit(T->getBase());
154-
}
155-
156-
FoundResult visitSharedTypeRepr(SharedTypeRepr *T) {
157-
return visit(T->getBase());
158-
}
159-
160-
FoundResult visitOwnedTypeRepr(OwnedTypeRepr *T) {
152+
FoundResult visitOwnershipTypeRepr(OwnershipTypeRepr *T) {
161153
return visit(T->getBase());
162154
}
163155

lib/Parse/ParsePattern.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -486,32 +486,33 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
486486
return status;
487487
});
488488
}
489-
template <typename T>
489+
490490
static TypeRepr *
491-
validateParameterWithSpecifier(Parser &parser,
491+
validateParameterWithOwnership(Parser &parser,
492492
Parser::ParsedParameter &paramInfo,
493-
StringRef specifierName,
493+
ParamSpecifier specifier,
494494
bool parsingEnumElt) {
495495
auto type = paramInfo.Type;
496496
auto loc = paramInfo.SpecifierLoc;
497497
// If we're validating an enum element, 'inout' is not allowed
498498
// at all - Sema will catch this for us. In all other contexts, we
499499
// assume the user put 'inout' in the wrong place and offer a fixit.
500500
if (parsingEnumElt) {
501-
return new (parser.Context) T(type, loc);
501+
return new (parser.Context) OwnershipTypeRepr(type, specifier, loc);
502502
}
503503

504504
if (isa<SpecifierTypeRepr>(type)) {
505505
parser.diagnose(loc, diag::parameter_specifier_repeated).fixItRemove(loc);
506506
} else {
507+
auto specifierName = OwnershipTypeRepr::getSpecifierSpelling(specifier);
507508
llvm::SmallString<128> replacement(specifierName);
508509
replacement += " ";
509510
parser
510511
.diagnose(loc, diag::parameter_specifier_as_attr_disallowed,
511512
specifierName)
512513
.fixItRemove(loc)
513514
.fixItInsert(type->getStartLoc(), replacement);
514-
type = new (parser.Context) T(type, loc);
515+
type = new (parser.Context) OwnershipTypeRepr(type, specifier, loc);
515516
}
516517

517518
return type;
@@ -559,17 +560,17 @@ mapParsedParameters(Parser &parser,
559560
if (auto type = paramInfo.Type) {
560561
// If 'inout' was specified, turn the type into an in-out type.
561562
if (paramInfo.SpecifierKind == ParamDecl::Specifier::InOut) {
562-
type = validateParameterWithSpecifier<InOutTypeRepr>(parser, paramInfo,
563-
"inout",
564-
parsingEnumElt);
563+
type = validateParameterWithOwnership(parser, paramInfo,
564+
ParamSpecifier::InOut,
565+
parsingEnumElt);
565566
} else if (paramInfo.SpecifierKind == ParamDecl::Specifier::Shared) {
566-
type = validateParameterWithSpecifier<SharedTypeRepr>(parser, paramInfo,
567-
"__shared",
568-
parsingEnumElt);
567+
type = validateParameterWithOwnership(parser, paramInfo,
568+
ParamSpecifier::Shared,
569+
parsingEnumElt);
569570
} else if (paramInfo.SpecifierKind == ParamDecl::Specifier::Owned) {
570-
type = validateParameterWithSpecifier<OwnedTypeRepr>(parser, paramInfo,
571-
"__owned",
572-
parsingEnumElt);
571+
type = validateParameterWithOwnership(parser, paramInfo,
572+
ParamSpecifier::Owned,
573+
parsingEnumElt);
573574
}
574575

575576
if (paramInfo.IsolatedLoc.isValid()) {

lib/Parse/ParseType.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,9 @@ TypeRepr *Parser::applyAttributeToType(TypeRepr *ty,
4545
if (specifierLoc.isValid()) {
4646
switch (specifier) {
4747
case ParamDecl::Specifier::Owned:
48-
ty = new (Context) OwnedTypeRepr(ty, specifierLoc);
49-
break;
5048
case ParamDecl::Specifier::InOut:
51-
ty = new (Context) InOutTypeRepr(ty, specifierLoc);
52-
break;
5349
case ParamDecl::Specifier::Shared:
54-
ty = new (Context) SharedTypeRepr(ty, specifierLoc);
50+
ty = new (Context) OwnershipTypeRepr(ty, specifier, specifierLoc);
5551
break;
5652
case ParamDecl::Specifier::Default:
5753
break;
@@ -1190,7 +1186,9 @@ ParserResult<TypeRepr> Parser::parseTypeTupleBody() {
11901186
// Build inout type. Note that we bury the inout locator within the
11911187
// named locator. This is weird but required by Sema apparently.
11921188
element.Type =
1193-
new (Context) InOutTypeRepr(element.Type, ObsoletedInOutLoc);
1189+
new (Context) OwnershipTypeRepr(element.Type,
1190+
ParamSpecifier::InOut,
1191+
ObsoletedInOutLoc);
11941192
}
11951193
}
11961194

0 commit comments

Comments
 (0)