Skip to content

Commit d3b6bff

Browse files
committed
Sema: Dance around to avoid re-entrant RequirementMachine construction
1 parent 2d851ff commit d3b6bff

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

include/swift/AST/ASTContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,11 @@ class ASTContext final {
11811181
rewriting::RequirementMachine *getOrCreateRequirementMachine(
11821182
CanGenericSignature sig);
11831183

1184+
/// This is a hack to break cycles. Don't introduce new callers of this
1185+
/// method.
1186+
bool isRecursivelyConstructingRequirementMachine(
1187+
CanGenericSignature sig);
1188+
11841189
/// Retrieve a generic signature with a single unconstrained type parameter,
11851190
/// like `<T>`.
11861191
CanGenericSignature getSingleGenericParameterSignature() const;

lib/AST/ASTContext.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,22 @@ ASTContext::getOrCreateRequirementMachine(CanGenericSignature sig) {
19971997
return machine;
19981998
}
19991999

2000+
bool ASTContext::isRecursivelyConstructingRequirementMachine(
2001+
CanGenericSignature sig) {
2002+
auto &rewriteCtx = getImpl().TheRewriteContext;
2003+
if (!rewriteCtx)
2004+
return false;
2005+
2006+
auto arena = getArena(sig);
2007+
auto &machines = getImpl().getArena(arena).RequirementMachines;
2008+
2009+
auto found = machines.find(sig);
2010+
if (found == machines.end())
2011+
return false;
2012+
2013+
return !found->second->isComplete();
2014+
}
2015+
20002016
Optional<llvm::TinyPtrVector<ValueDecl *>>
20012017
OverriddenDeclsRequest::getCachedResult() const {
20022018
auto decl = std::get<0>(getStorage());

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -819,9 +819,14 @@ Type AssociatedTypeInference::computeFixedTypeWitness(
819819
!conformedProto->inheritsFrom(assocType->getProtocol()))
820820
continue;
821821

822-
const auto ty =
823-
conformedProto->getGenericSignature()->getCanonicalTypeInContext(
824-
structuralTy);
822+
auto sig = conformedProto->getGenericSignature();
823+
824+
// FIXME: The RequirementMachine will assert on re-entrant construction.
825+
// We should find a more principled way of breaking this cycle.
826+
if (ctx.isRecursivelyConstructingRequirementMachine(sig.getCanonicalSignature()))
827+
continue;
828+
829+
const auto ty = sig->getCanonicalTypeInContext(structuralTy);
825830

826831
// A dependent member type with an identical base and name indicates that
827832
// the protocol does not same-type constrain it in any way; move on to

0 commit comments

Comments
 (0)