@@ -982,10 +982,47 @@ bool GenericContext::isComputingGenericSignature() const {
982
982
GenericSignatureRequest{const_cast <GenericContext*>(this )});
983
983
}
984
984
985
+ // / If we hit a cycle while building the generic signature, we can't return
986
+ // / nullptr, since this breaks invariants elsewhere. Instead, build a dummy
987
+ // / signature with no requirements.
988
+ static GenericSignature getPlaceholderGenericSignature (
989
+ const DeclContext *DC) {
990
+ SmallVector<GenericParamList *, 2 > gpLists;
991
+ DC->forEachGenericContext ([&](GenericParamList *genericParams) {
992
+ gpLists.push_back (genericParams);
993
+ });
994
+
995
+ if (gpLists.empty ())
996
+ return nullptr ;
997
+
998
+ std::reverse (gpLists.begin (), gpLists.end ());
999
+ for (unsigned i : indices (gpLists))
1000
+ gpLists[i]->setDepth (i);
1001
+
1002
+ SmallVector<GenericTypeParamType *, 2 > result;
1003
+ for (auto *genericParams : gpLists) {
1004
+ for (auto *genericParam : *genericParams) {
1005
+ result.push_back (genericParam->getDeclaredInterfaceType ()
1006
+ ->castTo <GenericTypeParamType>());
1007
+ }
1008
+ }
1009
+
1010
+ return GenericSignature::get (result, {});
1011
+ }
1012
+
985
1013
GenericSignature GenericContext::getGenericSignature () const {
986
- return evaluateOrDefault (
987
- getASTContext ().evaluator ,
988
- GenericSignatureRequest{const_cast <GenericContext *>(this )}, nullptr );
1014
+ // Don't use evaluateOrDefault() here, because getting the 'default value'
1015
+ // is slightly expensive here so we don't want to do it eagerly.
1016
+ auto result = getASTContext ().evaluator (
1017
+ GenericSignatureRequest{const_cast <GenericContext *>(this )});
1018
+ if (auto err = result.takeError ()) {
1019
+ llvm::handleAllErrors (std::move (err),
1020
+ [](const CyclicalRequestError<GenericSignatureRequest> &E) {
1021
+ // cycle detected
1022
+ });
1023
+ return getPlaceholderGenericSignature (this );
1024
+ }
1025
+ return *result;
989
1026
}
990
1027
991
1028
GenericEnvironment *GenericContext::getGenericEnvironment () const {
0 commit comments