@@ -35,12 +35,32 @@ RequirementMachine::RequirementMachine(RewriteContext &ctx)
3535
3636RequirementMachine::~RequirementMachine () {}
3737
38+ static void checkCompletionResult (const RequirementMachine &machine,
39+ CompletionResult result) {
40+ switch (result) {
41+ case CompletionResult::Success:
42+ break ;
43+
44+ case CompletionResult::MaxIterations:
45+ llvm::errs () << " Rewrite system exceeds maximum completion step count\n " ;
46+ machine.dump (llvm::errs ());
47+ abort ();
48+
49+ case CompletionResult::MaxDepth:
50+ llvm::errs () << " Rewrite system exceeds maximum completion depth\n " ;
51+ machine.dump (llvm::errs ());
52+ abort ();
53+ }
54+ }
55+
3856// / Build a requirement machine for the requirements of a generic signature.
3957// /
4058// / This must only be called exactly once, before any other operations are
4159// / performed on this requirement machine.
4260// /
4361// / Used by ASTContext::getOrCreateRequirementMachine().
62+ // /
63+ // / Asserts if completion fails within the configured number of steps.
4464void RequirementMachine::initWithGenericSignature (CanGenericSignature sig) {
4565 Sig = sig;
4666 Params.append (sig.getGenericParams ().begin (),
@@ -64,7 +84,8 @@ void RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
6484 std::move (builder.PermanentRules ),
6585 std::move (builder.RequirementRules ));
6686
67- computeCompletion (RewriteSystem::DisallowInvalidRequirements);
87+ auto result = computeCompletion (RewriteSystem::DisallowInvalidRequirements);
88+ checkCompletionResult (*this , result);
6889
6990 if (Dump) {
7091 llvm::dbgs () << " }\n " ;
@@ -79,7 +100,10 @@ void RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
79100// / performed on this requirement machine.
80101// /
81102// / Used by RequirementSignatureRequest.
82- void RequirementMachine::initWithProtocols (ArrayRef<const ProtocolDecl *> protos) {
103+ // /
104+ // / Returns failure if completion fails within the configured number of steps.
105+ CompletionResult
106+ RequirementMachine::initWithProtocols (ArrayRef<const ProtocolDecl *> protos) {
83107 Protos = protos;
84108
85109 FrontendStatsTracer tracer (Stats, " build-rewrite-system" );
@@ -100,12 +124,13 @@ void RequirementMachine::initWithProtocols(ArrayRef<const ProtocolDecl *> protos
100124 std::move (builder.PermanentRules ),
101125 std::move (builder.RequirementRules ));
102126
103- // FIXME: Only if the protocols were written in source, though.
104- computeCompletion (RewriteSystem::AllowInvalidRequirements);
127+ auto result = computeCompletion (RewriteSystem::AllowInvalidRequirements);
105128
106129 if (Dump) {
107130 llvm::dbgs () << " }\n " ;
108131 }
132+
133+ return result;
109134}
110135
111136// / Build a requirement machine from a set of generic parameters and
@@ -115,6 +140,8 @@ void RequirementMachine::initWithProtocols(ArrayRef<const ProtocolDecl *> protos
115140// / performed on this requirement machine.
116141// /
117142// / Used by AbstractGenericSignatureRequest.
143+ // /
144+ // / Asserts if completion fails within the configured number of steps.
118145void RequirementMachine::initWithAbstractRequirements (
119146 ArrayRef<GenericTypeParamType *> genericParams,
120147 ArrayRef<Requirement> requirements) {
@@ -139,7 +166,8 @@ void RequirementMachine::initWithAbstractRequirements(
139166 std::move (builder.PermanentRules ),
140167 std::move (builder.RequirementRules ));
141168
142- computeCompletion (RewriteSystem::AllowInvalidRequirements);
169+ auto result = computeCompletion (RewriteSystem::AllowInvalidRequirements);
170+ checkCompletionResult (*this , result);
143171
144172 if (Dump) {
145173 llvm::dbgs () << " }\n " ;
@@ -153,7 +181,10 @@ void RequirementMachine::initWithAbstractRequirements(
153181// / performed on this requirement machine.
154182// /
155183// / Used by InferredGenericSignatureRequest.
156- void RequirementMachine::initWithWrittenRequirements (
184+ // /
185+ // / Returns failure if completion fails within the configured number of steps.
186+ CompletionResult
187+ RequirementMachine::initWithWrittenRequirements (
157188 ArrayRef<GenericTypeParamType *> genericParams,
158189 ArrayRef<StructuralRequirement> requirements) {
159190 Params.append (genericParams.begin (), genericParams.end ());
@@ -177,17 +208,20 @@ void RequirementMachine::initWithWrittenRequirements(
177208 std::move (builder.PermanentRules ),
178209 std::move (builder.RequirementRules ));
179210
180- computeCompletion (RewriteSystem::AllowInvalidRequirements);
211+ auto result = computeCompletion (RewriteSystem::AllowInvalidRequirements);
181212
182213 if (Dump) {
183214 llvm::dbgs () << " }\n " ;
184215 }
216+
217+ return result;
185218}
186219
187220// / Attempt to obtain a confluent rewrite system by iterating the Knuth-Bendix
188221// / completion procedure together with property map construction until fixed
189222// / point.
190- void RequirementMachine::computeCompletion (RewriteSystem::ValidityPolicy policy) {
223+ CompletionResult
224+ RequirementMachine::computeCompletion (RewriteSystem::ValidityPolicy policy) {
191225 while (true ) {
192226 // First, run the Knuth-Bendix algorithm to resolve overlapping rules.
193227 auto result = System.computeConfluentCompletion (
@@ -200,26 +234,8 @@ void RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy)
200234 }
201235
202236 // Check for failure.
203- auto checkCompletionResult = [&]() {
204- switch (result.first ) {
205- case CompletionResult::Success:
206- break ;
207-
208- case CompletionResult::MaxIterations:
209- llvm::errs () << " Generic signature " << Sig
210- << " exceeds maximum completion step count\n " ;
211- System.dump (llvm::errs ());
212- abort ();
213-
214- case CompletionResult::MaxDepth:
215- llvm::errs () << " Generic signature " << Sig
216- << " exceeds maximum completion depth\n " ;
217- System.dump (llvm::errs ());
218- abort ();
219- }
220- };
221-
222- checkCompletionResult ();
237+ if (result.first != CompletionResult::Success)
238+ return result.first ;
223239
224240 // Check invariants.
225241 System.verifyRewriteRules (policy);
@@ -236,7 +252,9 @@ void RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy)
236252 .NumRequirementMachineUnifiedConcreteTerms += result.second ;
237253 }
238254
239- checkCompletionResult ();
255+ // Check for failure.
256+ if (result.first != CompletionResult::Success)
257+ return result.first ;
240258
241259 // If buildPropertyMap() added new rules, we run another round of
242260 // Knuth-Bendix, and build the property map again.
@@ -250,6 +268,8 @@ void RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy)
250268
251269 assert (!Complete);
252270 Complete = true ;
271+
272+ return CompletionResult::Success;
253273}
254274
255275bool RequirementMachine::isComplete () const {
0 commit comments