Skip to content

Commit ac36e2b

Browse files
committed
[ASTPrinter] Restructure the code for printing metatype instance types.
1 parent 429488f commit ac36e2b

File tree

2 files changed

+28
-31
lines changed

2 files changed

+28
-31
lines changed

include/swift/AST/Types.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5466,7 +5466,12 @@ class ExistentialType final : public TypeBase {
54665466

54675467
bool shouldPrintWithAny() const { return PrintWithAny; }
54685468

5469-
void forcePrintWithAny(bool value) { PrintWithAny = value; }
5469+
void forcePrintWithAny(llvm::function_ref<void(Type)> print) {
5470+
bool oldValue = PrintWithAny;
5471+
PrintWithAny = true;
5472+
print(this);
5473+
PrintWithAny = oldValue;
5474+
}
54705475

54715476
bool requiresClass() const {
54725477
if (auto protocol = ConstraintType->getAs<ProtocolType>())

lib/AST/ASTPrinter.cpp

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5632,38 +5632,30 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
56325632
}
56335633

56345634
Type instanceType = T->getInstanceType();
5635-
bool didPrintInstanceType = false;
5636-
if (Options.PrintExplicitAny) {
5637-
if (T->is<ExistentialMetatypeType>()) {
5638-
Printer << "any ";
5639-
5640-
// FIXME: We need to replace nested existential metatypes so that
5641-
// we don't print duplicate 'any'. This will be unnecessary once
5642-
// ExistentialMetatypeType is split into ExistentialType(MetatypeType).
5643-
instanceType = Type(instanceType).transform([](Type type) -> Type {
5644-
if (auto existential = type->getAs<ExistentialMetatypeType>())
5645-
return MetatypeType::get(existential->getInstanceType());
5646-
5647-
return type;
5648-
});
5649-
} else if (auto existential = instanceType->getAs<ExistentialType>()) {
5650-
// The 'any' keyword is needed to distinguish between existential
5651-
// metatypes and singleton metatypes. However, 'any' usually isn't
5652-
// printed for Any and AnyObject, because it's unnecessary to write
5653-
// 'any' with these specific constraints. Set a bit on the existential
5654-
// type to force printing with 'any' for metatypes. This bit doesn't
5655-
// matter for anything other than printing.
5656-
if (!existential->shouldPrintWithAny()) {
5657-
existential->forcePrintWithAny(true);
5658-
printWithParensIfNotSimple(existential);
5659-
existential->forcePrintWithAny(false);
5660-
didPrintInstanceType = true;
5661-
}
5662-
}
5663-
}
5635+
if (Options.PrintExplicitAny && T->is<ExistentialMetatypeType>()) {
5636+
Printer << "any ";
5637+
5638+
// FIXME: We need to replace nested existential metatypes so that
5639+
// we don't print duplicate 'any'. This will be unnecessary once
5640+
// ExistentialMetatypeType is split into ExistentialType(MetatypeType).
5641+
printWithParensIfNotSimple(instanceType.transform([](Type type) -> Type {
5642+
if (auto existential = type->getAs<ExistentialMetatypeType>())
5643+
return MetatypeType::get(existential->getInstanceType());
56645644

5665-
if (!didPrintInstanceType)
5645+
return type;
5646+
}));
5647+
} else if (T->is<MetatypeType>() && instanceType->is<ExistentialType>()) {
5648+
// The 'any' keyword is needed to distinguish between existential
5649+
// metatypes and singleton metatypes. However, 'any' usually isn't
5650+
// printed for Any and AnyObject, because it's unnecessary to write
5651+
// 'any' with these specific constraints. Force printing with 'any'
5652+
// for the existential instance type in this case.
5653+
instanceType->getAs<ExistentialType>()->forcePrintWithAny([&](Type ty) {
5654+
printWithParensIfNotSimple(ty);
5655+
});
5656+
} else {
56665657
printWithParensIfNotSimple(instanceType);
5658+
}
56675659

56685660
// We spell normal metatypes of existential types as .Protocol.
56695661
if (isa<MetatypeType>(T) &&

0 commit comments

Comments
 (0)