@@ -1301,9 +1301,10 @@ bool GenericContext::isComputingGenericSignature() const {
13011301
13021302// / If we hit a cycle while building the generic signature, we can't return
13031303// / nullptr, since this breaks invariants elsewhere. Instead, build a dummy
1304- // / signature with no requirements.
1304+ // / signature where everything is Copyable and Escapable, to avoid spurious
1305+ // / downstream diagnostics concerning move-only types.
13051306static GenericSignature getPlaceholderGenericSignature (
1306- const DeclContext *DC) {
1307+ ASTContext &ctx, const DeclContext *DC) {
13071308 SmallVector<GenericParamList *, 2 > gpLists;
13081309 DC->forEachGenericContext ([&](GenericParamList *genericParams) {
13091310 gpLists.push_back (genericParams);
@@ -1316,23 +1317,32 @@ static GenericSignature getPlaceholderGenericSignature(
13161317 for (unsigned i : indices (gpLists))
13171318 gpLists[i]->setDepth (i);
13181319
1319- SmallVector<GenericTypeParamType *, 2 > result;
1320- for (auto *genericParams : gpLists) {
1321- for (auto *genericParam : *genericParams) {
1322- result.push_back (genericParam->getDeclaredInterfaceType ()
1323- ->castTo <GenericTypeParamType>());
1320+ SmallVector<GenericTypeParamType *, 2 > genericParams;
1321+ SmallVector<Requirement, 2 > requirements;
1322+
1323+ for (auto *gpList : gpLists) {
1324+ for (auto *genericParam : *gpList) {
1325+ auto type = genericParam->getDeclaredInterfaceType ();
1326+ genericParams.push_back (type->castTo <GenericTypeParamType>());
1327+
1328+ if (ctx.LangOpts .hasFeature (Feature::NoncopyableGenerics)) {
1329+ for (auto ip : InvertibleProtocolSet::full ()) {
1330+ auto proto = ctx.getProtocol (getKnownProtocolKind (ip));
1331+ requirements.emplace_back (RequirementKind::Conformance, type,
1332+ proto->getDeclaredInterfaceType ());
1333+ }
1334+ }
13241335 }
13251336 }
13261337
1327- return GenericSignature::get (result, {} );
1338+ return GenericSignature::get (genericParams, requirements );
13281339}
13291340
13301341GenericSignature GenericContext::getGenericSignature () const {
1331- // Don't use evaluateOrDefault() here, because getting the 'default value'
1332- // is slightly expensive here so we don't want to do it eagerly.
1333- return getASTContext ().evaluator (
1342+ auto &ctx = getASTContext ();
1343+ return ctx.evaluator (
13341344 GenericSignatureRequest{const_cast <GenericContext *>(this )},
1335- [this ]() { return getPlaceholderGenericSignature (this ); });
1345+ [&ctx, this ]() { return getPlaceholderGenericSignature (ctx, this ); });
13361346}
13371347
13381348GenericEnvironment *GenericContext::getGenericEnvironment () const {
@@ -6912,10 +6922,46 @@ ProtocolDecl::getProtocolDependencies() const {
69126922 llvm::None);
69136923}
69146924
6925+ // / If we hit a request cycle, give the protocol a requirement signature where
6926+ // / everything is Copyable and Escapable. Otherwise, we'll get spurious
6927+ // / downstream diagnostics concerning move-only types.
6928+ static RequirementSignature getPlaceholderRequirementSignature (
6929+ const ProtocolDecl *proto) {
6930+ auto &ctx = proto->getASTContext ();
6931+
6932+ SmallVector<Requirement, 2 > requirements;
6933+
6934+ if (ctx.LangOpts .hasFeature (Feature::NoncopyableGenerics)) {
6935+ auto add = [&](Type type) {
6936+ for (auto ip : InvertibleProtocolSet::full ()) {
6937+ auto proto = ctx.getProtocol (getKnownProtocolKind (ip));
6938+ requirements.emplace_back (RequirementKind::Conformance, type,
6939+ proto->getDeclaredInterfaceType ());
6940+ }
6941+ };
6942+
6943+ add (proto->getSelfInterfaceType ());
6944+
6945+ for (auto *assocTypeDecl : proto->getAssociatedTypeMembers ())
6946+ add (assocTypeDecl->getDeclaredInterfaceType ());
6947+ }
6948+
6949+ // Maintain invariants.
6950+ llvm::array_pod_sort (requirements.begin (), requirements.end (),
6951+ [](const Requirement *lhs, const Requirement *rhs) -> int {
6952+ return lhs->compare (*rhs);
6953+ });
6954+
6955+ return RequirementSignature (ctx.AllocateCopy (requirements),
6956+ ArrayRef<ProtocolTypeAlias>());
6957+ }
6958+
69156959RequirementSignature ProtocolDecl::getRequirementSignature () const {
6916- return evaluateOrDefault ( getASTContext ().evaluator ,
6960+ return getASTContext ().evaluator (
69176961 RequirementSignatureRequest { const_cast <ProtocolDecl *>(this ) },
6918- RequirementSignature ());
6962+ [this ]() {
6963+ return getPlaceholderRequirementSignature (this );
6964+ });
69196965}
69206966
69216967bool ProtocolDecl::isComputingRequirementSignature () const {
0 commit comments