Skip to content

Commit a8b1890

Browse files
committed
[ASTPrinter] Restructure the code for printing metatype instance types.
1 parent 8930d58 commit a8b1890

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
@@ -5420,7 +5420,12 @@ class ExistentialType final : public TypeBase {
54205420

54215421
bool shouldPrintWithAny() const { return PrintWithAny; }
54225422

5423-
void forcePrintWithAny(bool value) { PrintWithAny = value; }
5423+
void forcePrintWithAny(llvm::function_ref<void(Type)> print) {
5424+
bool oldValue = PrintWithAny;
5425+
PrintWithAny = true;
5426+
print(this);
5427+
PrintWithAny = oldValue;
5428+
}
54245429

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

lib/AST/ASTPrinter.cpp

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

55835583
Type instanceType = T->getInstanceType();
5584-
bool didPrintInstanceType = false;
5585-
if (Options.PrintExplicitAny) {
5586-
if (T->is<ExistentialMetatypeType>()) {
5587-
Printer << "any ";
5588-
5589-
// FIXME: We need to replace nested existential metatypes so that
5590-
// we don't print duplicate 'any'. This will be unnecessary once
5591-
// ExistentialMetatypeType is split into ExistentialType(MetatypeType).
5592-
instanceType = Type(instanceType).transform([](Type type) -> Type {
5593-
if (auto existential = type->getAs<ExistentialMetatypeType>())
5594-
return MetatypeType::get(existential->getInstanceType());
5595-
5596-
return type;
5597-
});
5598-
} else if (auto existential = instanceType->getAs<ExistentialType>()) {
5599-
// The 'any' keyword is needed to distinguish between existential
5600-
// metatypes and singleton metatypes. However, 'any' usually isn't
5601-
// printed for Any and AnyObject, because it's unnecessary to write
5602-
// 'any' with these specific constraints. Set a bit on the existential
5603-
// type to force printing with 'any' for metatypes. This bit doesn't
5604-
// matter for anything other than printing.
5605-
if (!existential->shouldPrintWithAny()) {
5606-
existential->forcePrintWithAny(true);
5607-
printWithParensIfNotSimple(existential);
5608-
existential->forcePrintWithAny(false);
5609-
didPrintInstanceType = true;
5610-
}
5611-
}
5612-
}
5584+
if (Options.PrintExplicitAny && T->is<ExistentialMetatypeType>()) {
5585+
Printer << "any ";
5586+
5587+
// FIXME: We need to replace nested existential metatypes so that
5588+
// we don't print duplicate 'any'. This will be unnecessary once
5589+
// ExistentialMetatypeType is split into ExistentialType(MetatypeType).
5590+
printWithParensIfNotSimple(instanceType.transform([](Type type) -> Type {
5591+
if (auto existential = type->getAs<ExistentialMetatypeType>())
5592+
return MetatypeType::get(existential->getInstanceType());
56135593

5614-
if (!didPrintInstanceType)
5594+
return type;
5595+
}));
5596+
} else if (T->is<MetatypeType>() && instanceType->is<ExistentialType>()) {
5597+
// The 'any' keyword is needed to distinguish between existential
5598+
// metatypes and singleton metatypes. However, 'any' usually isn't
5599+
// printed for Any and AnyObject, because it's unnecessary to write
5600+
// 'any' with these specific constraints. Force printing with 'any'
5601+
// for the existential instance type in this case.
5602+
instanceType->getAs<ExistentialType>()->forcePrintWithAny([&](Type ty) {
5603+
printWithParensIfNotSimple(ty);
5604+
});
5605+
} else {
56155606
printWithParensIfNotSimple(instanceType);
5607+
}
56165608

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

0 commit comments

Comments
 (0)