Skip to content

Commit dca292c

Browse files
committed
Serialization: Don't serialize contextual enum argument type
Storing this separately is unnecessary since we already serialize the enum element's interface type. Also, this eliminates one of the few remaining cases where we serialize archetypes during AST serialization.
1 parent 00bceec commit dca292c

33 files changed

+102
-97
lines changed

include/swift/AST/Decl.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,11 @@ class alignas(1 << DeclAlignInBits) Decl {
325325
/// \brief Whether or not this element directly or indirectly references
326326
/// the enum type.
327327
unsigned Recursiveness : 2;
328+
329+
/// \brief Whther or not this element has an associated value.
330+
unsigned HasArgumentType : 1;
328331
};
329-
enum { NumEnumElementDeclBits = NumValueDeclBits + 2 };
332+
enum { NumEnumElementDeclBits = NumValueDeclBits + 3 };
330333
static_assert(NumEnumElementDeclBits <= 32, "fits in an unsigned");
331334

332335
class AbstractFunctionDeclBitfields {
@@ -5323,6 +5326,7 @@ class EnumElementDecl : public ValueDecl {
53235326
public:
53245327
EnumElementDecl(SourceLoc IdentifierLoc, Identifier Name,
53255328
TypeLoc ArgumentType,
5329+
bool HasArgumentType,
53265330
SourceLoc EqualsLoc,
53275331
LiteralExpr *RawValueExpr,
53285332
DeclContext *DC)
@@ -5333,14 +5337,13 @@ class EnumElementDecl : public ValueDecl {
53335337
{
53345338
EnumElementDeclBits.Recursiveness =
53355339
static_cast<unsigned>(ElementRecursiveness::NotRecursive);
5340+
EnumElementDeclBits.HasArgumentType = HasArgumentType;
53365341
}
53375342

53385343
/// \returns false if there was an error during the computation rendering the
53395344
/// EnumElementDecl invalid, true otherwise.
53405345
bool computeType();
53415346

5342-
bool hasArgumentType() const { return !ArgumentType.getType().isNull(); }
5343-
Type getArgumentType() const { return ArgumentType.getType(); }
53445347
Type getArgumentInterfaceType() const;
53455348

53465349
TypeLoc &getArgumentTypeLoc() { return ArgumentType; }

include/swift/Serialization/ModuleFormat.h

Lines changed: 2 additions & 2 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 = 308; // Last change: nested type table
57+
const uint16_t VERSION_MINOR = 309; // Last change: remove enum argument type
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;
@@ -975,8 +975,8 @@ namespace decls_block {
975975
ENUM_ELEMENT_DECL,
976976
IdentifierIDField, // name
977977
DeclContextIDField,// context decl
978-
TypeIDField, // argument type
979978
TypeIDField, // interface type
979+
BCFixed<1>, // has argument type?
980980
BCFixed<1>, // implicit?
981981
EnumElementRawValueKindField, // raw value kind
982982
BCFixed<1>, // negative raw value?

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,10 +2720,9 @@ void PrintAST::printEnumElement(EnumElementDecl *elt) {
27202720
Printer.printName(elt->getName());
27212721
});
27222722

2723-
if (elt->hasArgumentType()) {
2724-
Type Ty = elt->getArgumentType();
2725-
if (!Options.SkipPrivateStdlibDecls || !Ty.isPrivateStdlibType())
2726-
Ty.print(Printer, Options);
2723+
if (auto argTy = elt->getArgumentInterfaceType()) {
2724+
if (!Options.SkipPrivateStdlibDecls || !argTy.isPrivateStdlibType())
2725+
argTy.print(Printer, Options);
27272726
}
27282727

27292728
auto *raw = elt->getRawValueExpr();

lib/AST/ASTWalker.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,9 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
321321
}
322322

323323
bool visitEnumElementDecl(EnumElementDecl *ED) {
324-
if (ED->hasArgumentType()) {
325-
if (auto TR = ED->getArgumentTypeLoc().getTypeRepr()) {
326-
if (doIt(TR)) {
327-
return true;
328-
}
324+
if (auto TR = ED->getArgumentTypeLoc().getTypeRepr()) {
325+
if (doIt(TR)) {
326+
return true;
329327
}
330328
}
331329

lib/AST/Decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4702,7 +4702,7 @@ bool EnumElementDecl::computeType() {
47024702
Type selfTy = MetatypeType::get(resultTy);
47034703

47044704
// The type of the enum element is either (T) -> T or (T) -> ArgType -> T.
4705-
if (auto inputTy = getArgumentType()) {
4705+
if (auto inputTy = getArgumentTypeLoc().getType()) {
47064706
resultTy = FunctionType::get(ED->mapTypeOutOfContext(inputTy), resultTy);
47074707
}
47084708

@@ -4719,7 +4719,7 @@ bool EnumElementDecl::computeType() {
47194719
}
47204720

47214721
Type EnumElementDecl::getArgumentInterfaceType() const {
4722-
if (!hasArgumentType())
4722+
if (!EnumElementDeclBits.HasArgumentType)
47234723
return nullptr;
47244724

47254725
auto interfaceType = getInterfaceType();

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4837,8 +4837,8 @@ Decl *SwiftDeclConverter::importEnumCase(const clang::EnumConstantDecl *decl,
48374837
rawValueExpr->setNegative(SourceLoc());
48384838

48394839
auto element = Impl.createDeclWithClangNode<EnumElementDecl>(
4840-
decl, Accessibility::Public, SourceLoc(), name, TypeLoc(), SourceLoc(),
4841-
rawValueExpr, theEnum);
4840+
decl, Accessibility::Public, SourceLoc(), name, TypeLoc(), false,
4841+
SourceLoc(), rawValueExpr, theEnum);
48424842

48434843
// Give the enum element the appropriate type.
48444844
element->computeType();

lib/IDE/CodeCompletion.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,8 +2694,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
26942694
setClangDeclKeywords(EED, Pairs, Builder);
26952695
addLeadingDot(Builder);
26962696
Builder.addTextChunk(EED->getName().str());
2697-
if (EED->hasArgumentType())
2698-
addPatternFromType(Builder, EED->getArgumentType());
2697+
if (auto argTy = EED->getArgumentInterfaceType())
2698+
addPatternFromType(Builder, argTy);
26992699

27002700
// Enum element is of function type such as EnumName.type -> Int ->
27012701
// EnumName; however we should show Int -> EnumName as the type

lib/IRGen/GenEnum.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@ const {
187187

188188
// Empty payload addresses can be left undefined.
189189
if (payloadI == ElementsWithPayload.end()) {
190-
return IGF.getTypeInfoForUnlowered(elt->getArgumentType())
190+
auto argTy = elt->getParentEnum()->mapTypeIntoContext(
191+
elt->getArgumentInterfaceType());
192+
return IGF.getTypeInfoForUnlowered(argTy)
191193
.getUndefAddress();
192194
}
193195

@@ -208,7 +210,9 @@ const {
208210

209211
// Empty payload addresses can be left undefined.
210212
if (payloadI == ElementsWithPayload.end()) {
211-
return IGF.getTypeInfoForUnlowered(Case->getArgumentType())
213+
auto argTy = Case->getParentEnum()->mapTypeIntoContext(
214+
Case->getArgumentInterfaceType());
215+
return IGF.getTypeInfoForUnlowered(argTy)
212216
.getUndefAddress();
213217
}
214218

@@ -4980,7 +4984,7 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
49804984
// strategy. If the abstract layout of the enum is dependent on generic
49814985
// parameters, then we additionally need to constrain any layout
49824986
// optimizations we perform to things that are reproducible by the runtime.
4983-
Type origArgType = elt->getArgumentType();
4987+
Type origArgType = elt->getArgumentInterfaceType();
49844988
if (origArgType.isNull()) {
49854989
elementsWithNoPayload.push_back({elt, nullptr, nullptr});
49864990
continue;
@@ -4994,6 +4998,8 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
49944998
continue;
49954999
}
49965000

5001+
origArgType = theEnum->mapTypeIntoContext(origArgType);
5002+
49975003
auto origArgLoweredTy = TC.IGM.getLoweredType(origArgType);
49985004
const TypeInfo *origArgTI
49995005
= TC.tryGetCompleteTypeInfo(origArgLoweredTy.getSwiftRValueType());

lib/IRGen/GenMeta.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,16 +2458,18 @@ namespace {
24582458
// using the lowered cases, i.e. the cases for Optional<>.
24592459
if (type->classifyAsOptionalType() == OTK_ImplicitlyUnwrappedOptional) {
24602460
assert(enumElements.size() == 1);
2461-
auto caseType =
2462-
IGM.Context.getImplicitlyUnwrappedOptionalSomeDecl()
2463-
->getArgumentType()->getCanonicalType();
2461+
auto decl = IGM.Context.getImplicitlyUnwrappedOptionalSomeDecl();
2462+
auto caseType = decl->getParentEnum()->mapTypeIntoContext(
2463+
decl->getArgumentInterfaceType())
2464+
->getCanonicalType();
24642465
types.push_back(FieldTypeInfo(caseType, false, false));
24652466
return getFieldTypeAccessorFn(IGM, type, types);
24662467
}
24672468

24682469
for (auto &elt : enumElements) {
2469-
assert(elt.decl->hasArgumentType() && "enum case doesn't have arg?!");
2470-
auto caseType = elt.decl->getArgumentType()->getCanonicalType();
2470+
auto caseType = elt.decl->getParentEnum()->mapTypeIntoContext(
2471+
elt.decl->getArgumentInterfaceType())
2472+
->getCanonicalType();
24712473
bool isIndirect = elt.decl->isIndirect()
24722474
|| elt.decl->getParentEnum()->isIndirect();
24732475
types.push_back(FieldTypeInfo(caseType, isIndirect, /*weak*/ false));

lib/IRGen/GenType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ namespace {
14991499
return false;
15001500

15011501
for (auto elt : decl->getAllElements()) {
1502-
if (elt->hasArgumentType() &&
1502+
if (elt->getArgumentInterfaceType() &&
15031503
!elt->isIndirect() &&
15041504
visit(elt->getArgumentInterfaceType()->getCanonicalType()))
15051505
return true;
@@ -1902,7 +1902,7 @@ SILType irgen::getSingletonAggregateFieldType(IRGenModule &IGM, SILType t,
19021902

19031903
auto theCase = allCases.begin();
19041904
if (!allCases.empty() && std::next(theCase) == allCases.end()
1905-
&& (*theCase)->hasArgumentType())
1905+
&& (*theCase)->getArgumentInterfaceType())
19061906
return t.getEnumElementType(*theCase, IGM.getSILModule());
19071907

19081908
return SILType();

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,12 +1147,13 @@ llvm::DINodeArray IRGenDebugInfo::getEnumElements(DebugTypeInfo DbgTy,
11471147
// the storage size from the enum.
11481148
ElemDbgTy = DebugTypeInfo(ED, ED->getRawType(), DbgTy.StorageType,
11491149
DbgTy.size, DbgTy.align);
1150-
else if (ElemDecl->hasArgumentType()) {
1150+
else if (auto ArgTy = ElemDecl->getArgumentInterfaceType()) {
11511151
// A discriminated union. This should really be described as a
11521152
// DW_TAG_variant_type. For now only describing the data.
1153-
auto &TI = IGM.getTypeInfoForUnlowered(ElemDecl->getArgumentType());
1153+
ArgTy = ElemDecl->getParentEnum()->mapTypeIntoContext(ArgTy);
1154+
auto &TI = IGM.getTypeInfoForUnlowered(ArgTy);
11541155
ElemDbgTy =
1155-
DebugTypeInfo::getFromTypeInfo(ED, ElemDecl->getArgumentType(), TI);
1156+
DebugTypeInfo::getFromTypeInfo(ED, ArgTy, TI);
11561157
} else {
11571158
// Discriminated union case without argument. Fallback to Int
11581159
// as the element type; there is no storage here.

lib/Parse/ParseDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5114,8 +5114,10 @@ Parser::parseDeclEnumCase(ParseDeclOptions Flags,
51145114
}
51155115

51165116
// Create the element.
5117+
TypeRepr *ArgTR = ArgType.getPtrOrNull();
51175118
auto *result = new (Context) EnumElementDecl(NameLoc, Name,
5118-
ArgType.getPtrOrNull(),
5119+
ArgTR,
5120+
ArgTR != nullptr,
51195121
EqualsLoc,
51205122
LiteralRawValueExpr,
51215123
CurDeclContext);

lib/SIL/AbstractionPattern.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ AbstractionPattern TypeConverter::getAbstractionPattern(VarDecl *var) {
9191
}
9292

9393
AbstractionPattern TypeConverter::getAbstractionPattern(EnumElementDecl *decl) {
94-
assert(decl->hasArgumentType());
94+
assert(decl->getArgumentInterfaceType());
9595
assert(!decl->hasClangNode());
9696

9797
// This cannot be implemented correctly for Optional.Some.

lib/SIL/SILDeclRef.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind,
258258
} else if (auto *ed = dyn_cast<EnumElementDecl>(vd)) {
259259
assert(kind == Kind::EnumElement
260260
&& "can only create EnumElement SILDeclRef for enum element");
261-
naturalUncurryLevel = ed->hasArgumentType() ? 1 : 0;
261+
naturalUncurryLevel = ed->getArgumentInterfaceType() ? 1 : 0;
262262
} else if (isa<DestructorDecl>(vd)) {
263263
assert((kind == Kind::Destroyer || kind == Kind::Deallocator)
264264
&& "can only create destroyer/deallocator SILDeclRef for dtor");
@@ -315,7 +315,7 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc,
315315
else if (EnumElementDecl *ed = dyn_cast<EnumElementDecl>(vd)) {
316316
loc = ed;
317317
kind = Kind::EnumElement;
318-
naturalUncurryLevel = ed->hasArgumentType() ? 1 : 0;
318+
naturalUncurryLevel = ed->getArgumentInterfaceType() ? 1 : 0;
319319
}
320320
// VarDecl constants require an explicit kind.
321321
else if (isa<VarDecl>(vd)) {

lib/SIL/SILOwnershipVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ OwnershipCompatibilityUseChecker::checkTerminatorArgumentMatchesDestBB(
517517
// Check if this enum has at least one case that is non-trivially typed.
518518
bool HasNonTrivialCase =
519519
llvm::any_of(E->getAllElements(), [this](EnumElementDecl *E) -> bool {
520-
if (!E->hasArgumentType())
520+
if (!E->getArgumentInterfaceType())
521521
return false;
522522
SILType EnumEltType = getType().getEnumElementType(E, Mod);
523523
return !EnumEltType.isTrivial(Mod);

lib/SIL/SILType.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ static bool canUnsafeCastEnum(SILType fromType, EnumDecl *fromEnum,
179179
if (EnumDecl *toEnum = toType.getEnumOrBoundGenericEnum()) {
180180
for (auto toElement : toEnum->getAllElements()) {
181181
++numToElements;
182-
if (!toElement->hasArgumentType())
182+
if (!toElement->getArgumentInterfaceType())
183183
continue;
184184
// Bail on multiple payloads.
185185
if (!toElementTy.isNull())
@@ -203,7 +203,7 @@ static bool canUnsafeCastEnum(SILType fromType, EnumDecl *fromEnum,
203203
// If any of the fromElements can be cast by value to the singleton toElement,
204204
// then the overall enum can be cast by value.
205205
for (auto fromElement : fromElements) {
206-
if (!fromElement->hasArgumentType())
206+
if (!fromElement->getArgumentInterfaceType())
207207
continue;
208208

209209
auto fromElementTy = fromType.getEnumElementType(fromElement, M);
@@ -311,7 +311,7 @@ SILType SILType::getFieldType(VarDecl *field, SILModule &M) const {
311311

312312
SILType SILType::getEnumElementType(EnumElementDecl *elt, SILModule &M) const {
313313
assert(elt->getDeclContext() == getEnumOrBoundGenericEnum());
314-
assert(elt->hasArgumentType());
314+
assert(elt->getArgumentInterfaceType());
315315

316316
if (auto objectType = getSwiftRValueType().getAnyOptionalObjectType()) {
317317
assert(elt == M.getASTContext().getOptionalSomeDecl());
@@ -414,7 +414,7 @@ bool SILType::aggregateContainsRecord(SILType Record, SILModule &Mod) const {
414414
// Then if we have an enum...
415415
if (EnumDecl *E = Ty.getEnumOrBoundGenericEnum()) {
416416
for (auto Elt : E->getAllElements())
417-
if (Elt->hasArgumentType())
417+
if (Elt->getArgumentInterfaceType())
418418
Worklist.push_back(Ty.getEnumElementType(Elt, Mod));
419419
continue;
420420
}

lib/SIL/SILVerifier.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,10 +1511,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
15111511
"EnumInst case must be a case of the result enum type");
15121512
require(UI->getType().isObject(),
15131513
"EnumInst must produce an object");
1514-
require(UI->hasOperand() == UI->getElement()->hasArgumentType(),
1514+
require(UI->hasOperand() == !!UI->getElement()->getArgumentInterfaceType(),
15151515
"EnumInst must take an argument iff the element does");
15161516

1517-
if (UI->getElement()->hasArgumentType()) {
1517+
if (UI->getElement()->getArgumentInterfaceType()) {
15181518
require(UI->getOperand()->getType().isObject(),
15191519
"EnumInst operand must be an object");
15201520
SILType caseTy = UI->getType().getEnumElementType(UI->getElement(),
@@ -1529,7 +1529,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
15291529
require(ud, "InitEnumDataAddrInst must take an enum operand");
15301530
require(UI->getElement()->getParentEnum() == ud,
15311531
"InitEnumDataAddrInst case must be a case of the enum operand type");
1532-
require(UI->getElement()->hasArgumentType(),
1532+
require(UI->getElement()->getArgumentInterfaceType(),
15331533
"InitEnumDataAddrInst case must have a data type");
15341534
require(UI->getOperand()->getType().isAddress(),
15351535
"InitEnumDataAddrInst must take an address operand");
@@ -1548,7 +1548,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
15481548
require(ud, "UncheckedEnumData must take an enum operand");
15491549
require(UI->getElement()->getParentEnum() == ud,
15501550
"UncheckedEnumData case must be a case of the enum operand type");
1551-
require(UI->getElement()->hasArgumentType(),
1551+
require(UI->getElement()->getArgumentInterfaceType(),
15521552
"UncheckedEnumData case must have a data type");
15531553
require(UI->getOperand()->getType().isObject(),
15541554
"UncheckedEnumData must take an address operand");
@@ -1567,7 +1567,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
15671567
require(ud, "UncheckedTakeEnumDataAddrInst must take an enum operand");
15681568
require(UI->getElement()->getParentEnum() == ud,
15691569
"UncheckedTakeEnumDataAddrInst case must be a case of the enum operand type");
1570-
require(UI->getElement()->hasArgumentType(),
1570+
require(UI->getElement()->getArgumentInterfaceType(),
15711571
"UncheckedTakeEnumDataAddrInst case must have a data type");
15721572
require(UI->getOperand()->getType().isAddress(),
15731573
"UncheckedTakeEnumDataAddrInst must take an address operand");
@@ -2992,7 +2992,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
29922992

29932993
// The destination BB can take the argument payload, if any, as a BB
29942994
// arguments, or it can ignore it and take no arguments.
2995-
if (elt->hasArgumentType()) {
2995+
if (elt->getArgumentInterfaceType()) {
29962996
require(dest->getArguments().size() == 0 ||
29972997
dest->getArguments().size() == 1,
29982998
"switch_enum destination for case w/ args must take 0 or 1 "

lib/SIL/TypeLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ namespace {
12441244
bool trivial = true;
12451245
for (auto elt : D->getAllElements()) {
12461246
// No-payload elements do not affect address-only-ness.
1247-
if (!elt->hasArgumentType())
1247+
if (!elt->getArgumentInterfaceType())
12481248
continue;
12491249

12501250
// Indirect elements make the type nontrivial, but don't affect

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4318,7 +4318,7 @@ namespace {
43184318

43194319
// Get the payload argument.
43204320
ArgumentSource payload;
4321-
if (element->hasArgumentType()) {
4321+
if (element->getArgumentInterfaceType()) {
43224322
assert(uncurriedSites.size() == 2);
43234323
formalResultType = formalType.getResult();
43244324
claimNextParamClause(origFormalType);

lib/SILGen/SILGenConstructor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
392392

393393
// Emit the exploded constructor argument.
394394
ArgumentSource payload;
395-
if (element->hasArgumentType()) {
395+
if (element->getArgumentInterfaceType()) {
396396
RValue arg = emitImplicitValueConstructorArg
397397
(*this, Loc, element->getArgumentInterfaceType()->getCanonicalType(),
398398
element->getDeclContext());

0 commit comments

Comments
 (0)