Skip to content

Commit 3938d56

Browse files
joewillsherDougGregor
authored andcommitted
[SE-0095] [Runtime], [Demangler], & AST printer updated to new composition syntax
- All parts of the compiler now use ‘P1 & P2’ syntax - The demangler and AST printer wrap the composition in parens if it is in a metatype lookup - IRGen mangles compositions differently - “protocol<>” is now “swift.Any” - “protocol<_TP1P,_TP1Q>” is now “_TP1P&_TP1Q” - Tests cases are updated and added to test the new syntax and mangling
1 parent 622c86b commit 3938d56

File tree

68 files changed

+321
-309
lines changed

Some content is hidden

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

68 files changed

+321
-309
lines changed

include/swift/AST/Types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3476,7 +3476,7 @@ END_CAN_TYPE_WRAPPER(ProtocolType, NominalType)
34763476
/// \code
34773477
/// protocol P { /* ... */ }
34783478
/// protocol Q { /* ... */ }
3479-
/// var x : protocol<P, Q>
3479+
/// var x : P & Q
34803480
/// \endcode
34813481
///
34823482
/// Here, the type of x is a composition of the protocols 'P' and 'Q'.

lib/AST/ASTPrinter.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3294,6 +3294,12 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
32943294
return !arch->isOpenedExistential();
32953295
}
32963296

3297+
case TypeKind::ProtocolComposition: {
3298+
// 'Any' and single protocol compositions are simple
3299+
auto composition = type->getAs<ProtocolCompositionType>();
3300+
return composition->getProtocols().size() <= 1;
3301+
}
3302+
32973303
default:
32983304
return true;
32993305
}
@@ -4043,16 +4049,18 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
40434049
}
40444050

40454051
void visitProtocolCompositionType(ProtocolCompositionType *T) {
4046-
Printer << tok::kw_protocol << "<";
4047-
bool First = true;
4048-
for (auto Proto : T->getProtocols()) {
4049-
if (First)
4050-
First = false;
4051-
else
4052-
Printer << ", ";
4053-
visit(Proto);
4052+
if (T->getProtocols().empty()) {
4053+
Printer << "Any";
4054+
} else {
4055+
bool First = true;
4056+
for (auto Proto : T->getProtocols()) {
4057+
if (First)
4058+
First = false;
4059+
else
4060+
Printer << " & ";
4061+
visit(Proto);
4062+
}
40544063
}
4055-
Printer << ">";
40564064
}
40574065

40584066
void visitLValueType(LValueType *T) {

lib/AST/ArchetypeBuilder.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -826,23 +826,17 @@ void ArchetypeBuilder::PotentialArchetype::dump(llvm::raw_ostream &Out,
826826
if (!ConformsTo.empty()) {
827827
Out << " : ";
828828

829-
if (ConformsTo.size() != 1)
830-
Out << "protocol<";
831-
832829
bool First = true;
833830
for (const auto &ProtoAndSource : ConformsTo) {
834831
if (First)
835832
First = false;
836833
else
837-
Out << ", ";
834+
Out << " & ";
838835

839836
Out << ProtoAndSource.first->getName().str() << " [";
840837
ProtoAndSource.second.dump(Out, SrcMgr);
841838
Out << "]";
842839
}
843-
844-
if (ConformsTo.size() != 1)
845-
Out << ">";
846840
}
847841

848842
if (Representative != this) {

lib/AST/TypeRepr.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -434,16 +434,18 @@ ProtocolCompositionTypeRepr::create(ASTContext &C,
434434

435435
void ProtocolCompositionTypeRepr::printImpl(ASTPrinter &Printer,
436436
const PrintOptions &Opts) const {
437-
Printer << "protocol<";
438-
bool First = true;
439-
for (auto Proto : Protocols) {
440-
if (First)
441-
First = false;
442-
else
443-
Printer << ", ";
444-
printTypeRepr(Proto, Printer, Opts);
437+
if (Protocols.empty()) {
438+
Printer << "Any";
439+
} else {
440+
bool First = true;
441+
for (auto Proto : Protocols) {
442+
if (First)
443+
First = false;
444+
else
445+
Printer << " & ";
446+
printTypeRepr(Proto, Printer, Opts);
447+
}
445448
}
446-
Printer << ">";
447449
}
448450

449451
void MetatypeTypeRepr::printImpl(ASTPrinter &Printer,

lib/Basic/Demangle.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3465,12 +3465,10 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType)
34653465
NodePointer type_list = pointer->getChild(0);
34663466
if (!type_list)
34673467
return;
3468-
bool needs_proto_marker = (type_list->getNumChildren() != 1);
3469-
if (needs_proto_marker)
3470-
Printer << "protocol<";
3471-
printChildren(type_list, ", ");
3472-
if (needs_proto_marker)
3473-
Printer << ">";
3468+
if (type_list->getNumChildren() == 0)
3469+
Printer << "Any";
3470+
else
3471+
printChildren(type_list, " & ");
34743472
return;
34753473
}
34763474
case Node::Kind::Archetype: {

lib/IDE/TypeReconstruction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,7 @@ static void VisitNodeProtocolList(
18901890
nodes.push_back(cur_node->getFirstChild());
18911891
VisitNode(ast, nodes, protocol_types_result, generic_context);
18921892
if (protocol_types_result._error
1893-
.empty() /* cannot check for empty type list as protocol<> is allowed */) {
1893+
.empty() /* cannot check for empty type list as Any is allowed */) {
18941894
if (ast) {
18951895
result._types.push_back(
18961896
ProtocolCompositionType::get(*ast, protocol_types_result._types));

lib/IRGen/GenExistential.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ class ExistentialTypeInfoBase : public Base,
258258

259259
/// A TypeInfo implementation for existential types, i.e., types like:
260260
/// Printable
261-
/// protocol<Printable, Serializable>
261+
/// Printable & Serializable
262+
/// Any
262263
/// with the semantic translation:
263264
/// \exists t : Printable . t
264265
/// t here is an ArchetypeType.

lib/IRGen/GenType.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,16 +1657,18 @@ llvm::StructType *IRGenModule::createNominalType(CanType type) {
16571657
llvm::StructType *
16581658
IRGenModule::createNominalType(ProtocolCompositionType *type) {
16591659
llvm::SmallString<32> typeName;
1660-
1660+
16611661
SmallVector<ProtocolDecl *, 4> protocols;
16621662
type->getAnyExistentialTypeProtocols(protocols);
1663-
1664-
typeName.append("protocol<");
1665-
for (unsigned i = 0, e = protocols.size(); i != e; ++i) {
1666-
if (i) typeName.push_back(',');
1667-
LinkEntity::forNonFunction(protocols[i]).mangle(typeName);
1663+
1664+
if (protocols.empty()) {
1665+
typeName.append("swift.Any");
1666+
} else {
1667+
for (unsigned i = 0, e = protocols.size(); i != e; ++i) {
1668+
if (i) typeName.push_back('&');
1669+
LinkEntity::forNonFunction(protocols[i]).mangle(typeName);
1670+
}
16681671
}
1669-
typeName.push_back('>');
16701672
return llvm::StructType::create(getLLVMContext(), typeName.str());
16711673
}
16721674

stdlib/public/runtime/Casting.cpp

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -123,34 +123,33 @@ static const char *_getProtocolName(const ProtocolDescriptor *protocol) {
123123
}
124124

125125
static void _buildExistentialTypeName(const ProtocolDescriptorList *protocols,
126+
TypeSyntaxLevel level,
126127
bool qualified,
127128
std::string &result) {
128129
auto options = Demangle::DemangleOptions();
129130
options.QualifyEntities = qualified;
130131
options.DisplayDebuggerGeneratedModule = false;
131-
132+
132133
// If there's only one protocol, the existential type name is the protocol
133-
// name.
134+
// name. If there are 0 protocols it is 'Any'
134135
auto descriptors = protocols->getProtocols();
136+
auto numProtocols = protocols->NumProtocols;
135137

136-
if (protocols->NumProtocols == 1) {
137-
auto name = _getProtocolName(descriptors[0]);
138-
result += Demangle::demangleTypeAsString(name,
139-
strlen(name),
140-
options);
141-
return;
142-
}
143-
144-
result += "protocol<";
145-
for (unsigned i = 0, e = protocols->NumProtocols; i < e; ++i) {
146-
if (i > 0)
147-
result += ", ";
148-
auto name = _getProtocolName(descriptors[i]);
149-
result += Demangle::demangleTypeAsString(name,
150-
strlen(name),
151-
options);
138+
if (numProtocols == 0) {
139+
result += "Any";
140+
} else {
141+
// compositions of more than 1 protocol need parens in .Type contexts
142+
bool needsParens = level >= TypeSyntaxLevel::TypeSimple && numProtocols != 1;
143+
if (needsParens) result += "(";
144+
for (unsigned i = 0, e = numProtocols; i < e; ++i) {
145+
if (i) result += " & ";
146+
auto name = _getProtocolName(descriptors[i]);
147+
result += Demangle::demangleTypeAsString(name,
148+
strlen(name),
149+
options);
150+
}
151+
if (needsParens) result += ")";
152152
}
153-
result += ">";
154153
}
155154

156155
static void _buildFunctionTypeName(const FunctionTypeMetadata *func,
@@ -233,7 +232,7 @@ static void _buildNameForMetadata(const Metadata *type,
233232
}
234233
case MetadataKind::Existential: {
235234
auto exis = static_cast<const ExistentialTypeMetadata *>(type);
236-
_buildExistentialTypeName(&exis->Protocols, qualified, result);
235+
_buildExistentialTypeName(&exis->Protocols, level, qualified, result);
237236
return;
238237
}
239238
case MetadataKind::ExistentialMetatype: {

stdlib/public/runtime/Reflection.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ - (id)debugQuickLookObject;
4747

4848
namespace {
4949

50-
/// The layout of protocol<>.
50+
/// The layout of Any.
5151
using Any = OpaqueExistentialContainer;
5252

5353
// Swift assumes Any is returned in memory.

0 commit comments

Comments
 (0)