Skip to content

Commit 3f2f702

Browse files
committed
Generate the Copyable ProtocolDecl instead.
Pulling the explicit decl out the stdlib helps future-proof us if we decide to define `Swift.Copyable` as some other "thing" other than a protocol. Older compilers would only end up emitting `~Swift.Copyable` in interfaces. Newer compilers can interpret in a different way, such as a layout constraint. On the other side, if in the future we do end up writing `Swift.Copyable` explicitly in the stdlib as a ProtocolDecl, older compilers will pick-up that decl instead of synthesizing their own.
1 parent 3e735ab commit 3f2f702

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

lib/AST/ASTContext.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,7 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12271227
case KnownProtocolKind::UnsafeCxxRandomAccessIterator:
12281228
M = getLoadedModule(Id_Cxx);
12291229
break;
1230+
case KnownProtocolKind::Copyable:
12301231
default:
12311232
M = getStdlibModule();
12321233
break;
@@ -1246,6 +1247,27 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12461247
}
12471248
}
12481249

1250+
// Fall-back option upon look-up failure: synthesize the protocol decl.
1251+
if (kind == KnownProtocolKind::Copyable) {
1252+
assert(M->isStdlibModule());
1253+
auto *protocol = new(*this) ProtocolDecl(M->getDeclContext(),
1254+
SourceLoc(),
1255+
SourceLoc(),
1256+
getIdentifier("Copyable"),
1257+
/*AssociatedTypeNames*/{},
1258+
/*Inherited*/{},
1259+
/*TrailingWhere*/nullptr);
1260+
protocol->getAttrs().add(new(*this) MarkerAttr(/*IsImplicit*/true));
1261+
protocol->setImplicit(true);
1262+
1263+
// Save it!
1264+
getImpl().KnownProtocols[index] = protocol;
1265+
1266+
assert(protocol->isMarkerProtocol());
1267+
assert(protocol->isSpecificProtocol(KnownProtocolKind::Copyable));
1268+
return protocol;
1269+
}
1270+
12491271
return nullptr;
12501272
}
12511273

stdlib/public/core/CompilerProtocols.swift

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -973,18 +973,7 @@ public protocol _ExpressibleByFileReferenceLiteral {
973973
public protocol _DestructorSafeContainer {
974974
}
975975

976-
/// This marker protocol describes the category of types that support implicit
977-
/// copying. By default, all types in Swift implicitly support copying and thus
978-
/// conformance to `Copyable` is implicitly synthesized. To suppress the
979-
/// implicit conformance synthesis, write `~Copyable` on the type declaration:
980-
///
981-
/// struct FileDescriptor: ~Copyable { /* ... */ }
982-
///
983-
/// The reading of this type declaration is "FileDescriptor suppresses implicit
984-
/// Copyable conformance".
985-
@_marker public protocol Copyable {}
986-
987976
/// For older compilers interacting with newer stdlibs, define the unavailable
988977
/// `_Copyable` marker protocol that they expect to find.
989978
@available(*, unavailable)
990-
typealias _Copyable = Copyable
979+
@_marker public protocol _Copyable {}

0 commit comments

Comments
 (0)