@@ -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 ()
@@ -1195,6 +1197,47 @@ Type ASTContext::get##NAME##Type() const { \
11951197
11961198#include " swift/AST/KnownSDKTypes.def"
11971199
1200+ ProtocolDecl *
1201+ ASTContext::synthesizeInvertibleProtocolDecl (InvertibleProtocolKind ip) const {
1202+ const uint8_t index = (uint8_t )ip;
1203+ if (auto *proto = getImpl ().InvertibleProtocolDecls [index])
1204+ return proto;
1205+
1206+ ModuleDecl *stdlib = getStdlibModule ();
1207+ FileUnit *file = nullptr ;
1208+ if (stdlib) {
1209+ file = &stdlib->getFiles ()[0 ]->getOrCreateSynthesizedFile ();
1210+ } else {
1211+ file = &TheBuiltinModule->getMainFile (FileUnitKind::Builtin);
1212+ }
1213+
1214+ // No need to form an inheritance clause; invertible protocols do not
1215+ // implicitly inherit from other invertible protocols.
1216+ auto identifier = getIdentifier (getProtocolName (getKnownProtocolKind (ip)));
1217+ ProtocolDecl *protocol = new (*this ) ProtocolDecl (file,
1218+ SourceLoc (), SourceLoc (),
1219+ identifier,
1220+ /* primaryAssocTypes=*/ {},
1221+ /* inherited=*/ {},
1222+ /* whereClause=*/ nullptr );
1223+ protocol->setImplicit (true );
1224+
1225+ // @_marker
1226+ protocol->getAttrs ().add (new (*this ) MarkerAttr (/* implicit=*/ true ));
1227+
1228+ // public
1229+ protocol->setAccess (AccessLevel::Public);
1230+
1231+ // Hack to get name lookup to work after synthesizing it into the stdlib.
1232+ if (stdlib) {
1233+ cast<SynthesizedFileUnit>(file)->addTopLevelDecl (protocol);
1234+ stdlib->clearLookupCache ();
1235+ }
1236+
1237+ getImpl ().InvertibleProtocolDecls [index] = protocol;
1238+ return protocol;
1239+ }
1240+
11981241ProtocolDecl *ASTContext::getProtocol (KnownProtocolKind kind) const {
11991242 // Check whether we've already looked for and cached this protocol.
12001243 unsigned index = (unsigned )kind;
@@ -1206,6 +1249,7 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12061249 SmallVector<ValueDecl *, 1 > results;
12071250
12081251 const ModuleDecl *M;
1252+ NLKind NameLookupKind = NLKind::UnqualifiedLookup;
12091253 switch (kind) {
12101254 case KnownProtocolKind::BridgedNSError:
12111255 case KnownProtocolKind::BridgedStoredNSError:
@@ -1251,6 +1295,16 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12511295 case KnownProtocolKind::UnsafeCxxMutableRandomAccessIterator:
12521296 M = getLoadedModule (Id_Cxx);
12531297 break ;
1298+ case KnownProtocolKind::Copyable:
1299+ case KnownProtocolKind::Escapable:
1300+ // If there's no stdlib, do qualified lookup in the Builtin module,
1301+ // which will trigger the correct synthesis of the protocols in that module.
1302+ M = getStdlibModule ();
1303+ if (!M) {
1304+ NameLookupKind = NLKind::QualifiedLookup;
1305+ M = TheBuiltinModule;
1306+ }
1307+ break ;
12541308 default :
12551309 M = getStdlibModule ();
12561310 break ;
@@ -1259,7 +1313,7 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12591313 if (!M)
12601314 return nullptr ;
12611315 M->lookupValue (getIdentifier (getProtocolName (kind)),
1262- NLKind::UnqualifiedLookup ,
1316+ NameLookupKind ,
12631317 ModuleLookupFlags::ExcludeMacroExpansions,
12641318 results);
12651319
@@ -1270,6 +1324,14 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
12701324 }
12711325 }
12721326
1327+ // If the invertible protocol wasn't found in the stdlib, synthesize it there.
1328+ if (auto ip = getInvertibleProtocolKind (kind)) {
1329+ assert (M == getStdlibModule ());
1330+ auto *protocol = synthesizeInvertibleProtocolDecl (*ip);
1331+ getImpl ().KnownProtocols [index] = protocol;
1332+ return protocol;
1333+ }
1334+
12731335 return nullptr ;
12741336}
12751337
@@ -6408,7 +6470,7 @@ BuiltinTupleDecl *ASTContext::getBuiltinTupleDecl() {
64086470 if (result)
64096471 return result;
64106472
6411- auto *dc = TheBuiltinModule->getFiles ()[ 0 ] ;
6473+ auto *dc = & TheBuiltinModule->getMainFile (FileUnitKind::Builtin) ;
64126474
64136475 result = new (*this ) BuiltinTupleDecl (Id_TheTupleType, dc);
64146476 result->setAccess (AccessLevel::Public);
0 commit comments