Skip to content

Commit ae1ef6d

Browse files
committed
RequirementMachine: Eliminate RequirementMachine::initWithAbstractRequirements()
1 parent e326c01 commit ae1ef6d

File tree

4 files changed

+47
-63
lines changed

4 files changed

+47
-63
lines changed

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 24 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -36,38 +36,46 @@ RequirementMachine::RequirementMachine(RewriteContext &ctx)
3636

3737
RequirementMachine::~RequirementMachine() {}
3838

39-
static void checkCompletionResult(const RequirementMachine &machine,
40-
CompletionResult result) {
39+
/// Checks the result of a completion in a context where we can't diagnose
40+
/// failure, either when building a rewrite system from an existing
41+
/// minimal signature (which should have been checked when it was
42+
/// minimized) or from AbstractGenericSignatureRequest (where failure
43+
/// is fatal).
44+
void RequirementMachine::checkCompletionResult(CompletionResult result) const {
4145
switch (result) {
4246
case CompletionResult::Success:
4347
break;
4448

4549
case CompletionResult::MaxRuleCount:
4650
llvm::errs() << "Rewrite system exceeded maximum rule count\n";
47-
machine.dump(llvm::errs());
51+
dump(llvm::errs());
4852
abort();
4953

5054
case CompletionResult::MaxRuleLength:
5155
llvm::errs() << "Rewrite system exceeded rule length limit\n";
52-
machine.dump(llvm::errs());
56+
dump(llvm::errs());
5357
abort();
5458

5559
case CompletionResult::MaxConcreteNesting:
5660
llvm::errs() << "Rewrite system exceeded concrete type nesting depth limit\n";
57-
machine.dump(llvm::errs());
61+
dump(llvm::errs());
5862
abort();
5963
}
6064
}
6165

6266
/// Build a requirement machine for the requirements of a generic signature.
6367
///
68+
/// In this mode, minimization is not going to be performed, so rewrite loops
69+
/// are not recorded.
70+
///
6471
/// This must only be called exactly once, before any other operations are
6572
/// performed on this requirement machine.
6673
///
6774
/// Used by ASTContext::getOrCreateRequirementMachine().
6875
///
69-
/// Asserts if completion fails within the configured number of steps.
70-
void RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
76+
/// Returns failure if completion fails within the configured number of steps.
77+
std::pair<CompletionResult, unsigned>
78+
RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
7179
Sig = sig;
7280
Params.append(sig.getGenericParams().begin(),
7381
sig.getGenericParams().end());
@@ -92,17 +100,21 @@ void RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
92100
std::move(builder.RequirementRules));
93101

94102
auto result = computeCompletion(RewriteSystem::DisallowInvalidRequirements);
95-
checkCompletionResult(*this, result.first);
96103

97104
if (Dump) {
98105
llvm::dbgs() << "}\n";
99106
}
107+
108+
return result;
100109
}
101110

102111
/// Build a requirement machine for the structural requirements of a set
103112
/// of protocols, which are understood to form a strongly-connected component
104113
/// (SCC) of the protocol dependency graph.
105114
///
115+
/// In this mode, minimization will be performed, so rewrite loops are recorded
116+
/// during completion.
117+
///
106118
/// This must only be called exactly once, before any other operations are
107119
/// performed on this requirement machine.
108120
///
@@ -138,55 +150,16 @@ RequirementMachine::initWithProtocols(ArrayRef<const ProtocolDecl *> protos) {
138150
return result;
139151
}
140152

141-
/// Build a requirement machine from a set of generic parameters and
142-
/// (possibly non-canonical or non-minimal) abstract requirements.
143-
///
144-
/// This must only be called exactly once, before any other operations are
145-
/// performed on this requirement machine.
146-
///
147-
/// Used by AbstractGenericSignatureRequest.
148-
///
149-
/// Asserts if completion fails within the configured number of steps.
150-
void RequirementMachine::initWithAbstractRequirements(
151-
ArrayRef<GenericTypeParamType *> genericParams,
152-
ArrayRef<Requirement> requirements) {
153-
Params.append(genericParams.begin(), genericParams.end());
154-
155-
FrontendStatsTracer tracer(Stats, "build-rewrite-system");
156-
157-
if (Dump) {
158-
llvm::dbgs() << "Adding generic parameters:";
159-
for (auto *paramTy : genericParams)
160-
llvm::dbgs() << " " << Type(paramTy);
161-
llvm::dbgs() << "\n";
162-
}
163-
164-
// Collect the top-level requirements, and all transtively-referenced
165-
// protocol requirement signatures.
166-
RuleBuilder builder(Context, System.getProtocolMap());
167-
builder.addRequirements(requirements);
168-
169-
// Add the initial set of rewrite rules to the rewrite system.
170-
System.initialize(/*recordLoops=*/true,
171-
/*protos=*/ArrayRef<const ProtocolDecl *>(),
172-
std::move(builder.PermanentRules),
173-
std::move(builder.RequirementRules));
174-
175-
auto result = computeCompletion(RewriteSystem::AllowInvalidRequirements);
176-
checkCompletionResult(*this, result.first);
177-
178-
if (Dump) {
179-
llvm::dbgs() << "}\n";
180-
}
181-
}
182-
183153
/// Build a requirement machine from a set of generic parameters and
184154
/// structural requirements.
185155
///
156+
/// In this mode, minimization will be performed, so rewrite loops are recorded
157+
/// during completion.
158+
///
186159
/// This must only be called exactly once, before any other operations are
187160
/// performed on this requirement machine.
188161
///
189-
/// Used by InferredGenericSignatureRequest.
162+
/// Used by AbstractGenericSignatureRequest and InferredGenericSignatureRequest.
190163
///
191164
/// Returns failure if completion fails within the configured number of steps.
192165
std::pair<CompletionResult, unsigned>

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,14 @@ class RequirementMachine final {
8888
RequirementMachine &operator=(const RequirementMachine &) = delete;
8989
RequirementMachine &operator=(RequirementMachine &&) = delete;
9090

91-
void initWithGenericSignature(CanGenericSignature sig);
91+
void checkCompletionResult(CompletionResult result) const;
92+
93+
std::pair<CompletionResult, unsigned>
94+
initWithGenericSignature(CanGenericSignature sig);
95+
9296
std::pair<CompletionResult, unsigned>
9397
initWithProtocols(ArrayRef<const ProtocolDecl *> protos);
94-
void initWithAbstractRequirements(
95-
ArrayRef<GenericTypeParamType *> genericParams,
96-
ArrayRef<Requirement> requirements);
98+
9799
std::pair<CompletionResult, unsigned>
98100
initWithWrittenRequirements(
99101
ArrayRef<GenericTypeParamType *> genericParams,

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,9 @@ AbstractGenericSignatureRequestRQM::evaluate(
473473
return GenericSignatureWithError(result, /*hadError=*/false);
474474
}
475475

476-
SmallVector<Requirement, 4> requirements(
477-
baseSignature.getRequirements().begin(),
478-
baseSignature.getRequirements().end());
476+
SmallVector<StructuralRequirement, 4> requirements;
477+
for (auto req : baseSignature.getRequirements())
478+
requirements.push_back({req, SourceLoc(), /*wasInferred=*/false});
479479

480480
// We need to create this errors vector to pass to
481481
// desugarRequirement, but this request should never
@@ -492,14 +492,20 @@ AbstractGenericSignatureRequestRQM::evaluate(
492492
// Desugaring converts these kinds of requirements into "proper"
493493
// requirements where the subject type is always a type parameter,
494494
// which is what the RuleBuilder expects.
495-
for (auto req : addedRequirements)
496-
desugarRequirement(req, requirements, errors);
495+
for (auto req : addedRequirements) {
496+
SmallVector<Requirement, 2> reqs;
497+
desugarRequirement(req, reqs, errors);
498+
for (auto req : reqs)
499+
requirements.push_back({req, SourceLoc(), /*wasInferred=*/false});
500+
}
497501

498502
// Heap-allocate the requirement machine to save stack space.
499503
std::unique_ptr<RequirementMachine> machine(new RequirementMachine(
500504
ctx.getRewriteContext()));
501505

502-
machine->initWithAbstractRequirements(genericParams, requirements);
506+
auto status =
507+
machine->initWithWrittenRequirements(genericParams, requirements);
508+
machine->checkCompletionResult(status.first);
503509

504510
auto minimalRequirements =
505511
machine->computeMinimalGenericSignatureRequirements();
@@ -611,7 +617,8 @@ InferredGenericSignatureRequestRQM::evaluate(
611617
std::unique_ptr<RequirementMachine> machine(new RequirementMachine(
612618
ctx.getRewriteContext()));
613619

614-
auto status = machine->initWithWrittenRequirements(genericParams, requirements);
620+
auto status =
621+
machine->initWithWrittenRequirements(genericParams, requirements);
615622
if (status.first != CompletionResult::Success) {
616623
ctx.Diags.diagnose(loc,
617624
diag::requirement_machine_completion_failed,

lib/AST/RequirementMachine/RewriteContext.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ RequirementMachine *RewriteContext::getRequirementMachine(
133133

134134
// This might re-entrantly invalidate 'machine', which is a reference
135135
// into Protos.
136-
newMachine->initWithGenericSignature(sig);
136+
auto status = newMachine->initWithGenericSignature(sig);
137+
newMachine->checkCompletionResult(status.first);
138+
137139
return newMachine;
138140
}
139141

0 commit comments

Comments
 (0)