@@ -630,6 +630,8 @@ struct ASTContext::Implementation {
630630
631631 // / The declared interface type of Builtin.TheTupleType.
632632 BuiltinTupleType *TheTupleType = nullptr ;
633+
634+ std::array<ProtocolDecl *, NumInvertibleProtocols> InvertibleProtocolDecls = {};
633635};
634636
635637ASTContext::Implementation::Implementation ()
@@ -1189,6 +1191,47 @@ Type ASTContext::get##NAME##Type() const { \
11891191
11901192#include " swift/AST/KnownSDKTypes.def"
11911193
1194+ ProtocolDecl *
1195+ ASTContext::synthesizeInvertibleProtocolDecl (InvertibleProtocolKind ip) const {
1196+ const uint8_t index = (uint8_t )ip;
1197+ if (auto *proto = getImpl ().InvertibleProtocolDecls [index])
1198+ return proto;
1199+
1200+ ModuleDecl *stdlib = getStdlibModule ();
1201+ FileUnit *file = nullptr ;
1202+ if (stdlib) {
1203+ file = &stdlib->getFiles ()[0 ]->getOrCreateSynthesizedFile ();
1204+ } else {
1205+ file = &TheBuiltinModule->getMainFile (FileUnitKind::Builtin);
1206+ }
1207+
1208+ // No need to form an inheritance clause; invertible protocols do not
1209+ // implicitly inherit from other invertible protocols.
1210+ auto identifier = getIdentifier (getProtocolName (getKnownProtocolKind (ip)));
1211+ ProtocolDecl *protocol = new (*this ) ProtocolDecl (file,
1212+ SourceLoc (), SourceLoc (),
1213+ identifier,
1214+ /* primaryAssocTypes=*/ {},
1215+ /* inherited=*/ {},
1216+ /* whereClause=*/ nullptr );
1217+ protocol->setImplicit (true );
1218+
1219+ // @_marker
1220+ protocol->getAttrs ().add (new (*this ) MarkerAttr (/* implicit=*/ true ));
1221+
1222+ // public
1223+ protocol->setAccess (AccessLevel::Public);
1224+
1225+ // Hack to get name lookup to work after synthesizing it into the stdlib.
1226+ if (stdlib) {
1227+ cast<SynthesizedFileUnit>(file)->addTopLevelDecl (protocol);
1228+ stdlib->clearLookupCache ();
1229+ }
1230+
1231+ getImpl ().InvertibleProtocolDecls [index] = protocol;
1232+ return protocol;
1233+ }
1234+
11921235ProtocolDecl *ASTContext::getProtocol (KnownProtocolKind kind) const {
11931236 // Check whether we've already looked for and cached this protocol.
11941237 unsigned index = (unsigned )kind;
@@ -1200,6 +1243,7 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12001243 SmallVector<ValueDecl *, 1 > results;
12011244
12021245 const ModuleDecl *M;
1246+ NLKind NameLookupKind = NLKind::UnqualifiedLookup;
12031247 switch (kind) {
12041248 case KnownProtocolKind::BridgedNSError:
12051249 case KnownProtocolKind::BridgedStoredNSError:
@@ -1245,6 +1289,16 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12451289 case KnownProtocolKind::UnsafeCxxMutableRandomAccessIterator:
12461290 M = getLoadedModule (Id_Cxx);
12471291 break ;
1292+ case KnownProtocolKind::Copyable:
1293+ case KnownProtocolKind::Escapable:
1294+ // If there's no stdlib, do qualified lookup in the Builtin module,
1295+ // which will trigger the correct synthesis of the protocols in that module.
1296+ M = getStdlibModule ();
1297+ if (!M) {
1298+ NameLookupKind = NLKind::QualifiedLookup;
1299+ M = TheBuiltinModule;
1300+ }
1301+ break ;
12481302 default :
12491303 M = getStdlibModule ();
12501304 break ;
@@ -1253,7 +1307,7 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12531307 if (!M)
12541308 return nullptr ;
12551309 M->lookupValue (getIdentifier (getProtocolName (kind)),
1256- NLKind::UnqualifiedLookup ,
1310+ NameLookupKind ,
12571311 ModuleLookupFlags::ExcludeMacroExpansions,
12581312 results);
12591313
@@ -1264,6 +1318,14 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12641318 }
12651319 }
12661320
1321+ // If the invertible protocol wasn't found in the stdlib, synthesize it there.
1322+ if (auto ip = getInvertibleProtocolKind (kind)) {
1323+ assert (M == getStdlibModule ());
1324+ auto *protocol = synthesizeInvertibleProtocolDecl (*ip);
1325+ getImpl ().KnownProtocols [index] = protocol;
1326+ return protocol;
1327+ }
1328+
12671329 return nullptr ;
12681330}
12691331
@@ -6394,7 +6456,7 @@ BuiltinTupleDecl *ASTContext::getBuiltinTupleDecl() {
63946456 if (result)
63956457 return result;
63966458
6397- auto *dc = TheBuiltinModule->getFiles ()[ 0 ] ;
6459+ auto *dc = & TheBuiltinModule->getMainFile (FileUnitKind::Builtin) ;
63986460
63996461 result = new (*this ) BuiltinTupleDecl (Id_TheTupleType, dc);
64006462 result->setAccess (AccessLevel::Public);
0 commit comments