Skip to content

Commit 42c0a28

Browse files
committed
RequirementMachine: Add RequirementMachine::initWithWrittenRequirements()
1 parent 1c78b04 commit 42c0a28

File tree

4 files changed

+66
-3
lines changed

4 files changed

+66
-3
lines changed

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,21 @@ void RuleBuilder::addRequirements(ArrayRef<Requirement> requirements) {
692692
addRequirement(req, /*proto=*/nullptr);
693693
}
694694

695+
void RuleBuilder::addRequirements(ArrayRef<StructuralRequirement> requirements) {
696+
// Collect all protocols transitively referenced from these requirements.
697+
for (auto req : requirements) {
698+
if (req.req.getKind() == RequirementKind::Conformance) {
699+
addProtocol(req.req.getProtocolDecl(), /*initialComponent=*/false);
700+
}
701+
}
702+
703+
collectRulesFromReferencedProtocols();
704+
705+
// Add rewrite rules for all top-level requirements.
706+
for (const auto &req : requirements)
707+
addRequirement(req, /*proto=*/nullptr);
708+
}
709+
695710
void RuleBuilder::addProtocols(ArrayRef<const ProtocolDecl *> protos) {
696711
// Collect all protocols transitively referenced from this connected component
697712
// of the protocol dependency graph.
@@ -849,6 +864,12 @@ void RuleBuilder::addRequirement(const Requirement &req,
849864
RequirementRules.emplace_back(subjectTerm, constraintTerm);
850865
}
851866

867+
void RuleBuilder::addRequirement(const StructuralRequirement &req,
868+
const ProtocolDecl *proto) {
869+
// FIXME: Preserve source location information for diagnostics.
870+
addRequirement(req.req.getCanonical(), proto);
871+
}
872+
852873
/// Record information about a protocol if we have no seen it yet.
853874
void RuleBuilder::addProtocol(const ProtocolDecl *proto,
854875
bool initialComponent) {
@@ -902,10 +923,8 @@ void RuleBuilder::collectRulesFromReferencedProtocols() {
902923
// we can trigger the computation of the requirement signatures of the
903924
// next component recursively.
904925
if (ProtocolMap[proto]) {
905-
// FIXME: Keep source location information around for redundancy
906-
// diagnostics.
907926
for (auto req : proto->getStructuralRequirements())
908-
addRequirement(req.req.getCanonical(), proto);
927+
addRequirement(req, proto);
909928

910929
for (auto req : proto->getTypeAliasRequirements())
911930
addRequirement(req.getCanonical(), proto);

lib/AST/RequirementMachine/RequirementLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,16 @@ struct RuleBuilder {
9393

9494
RuleBuilder(RewriteContext &ctx, bool dump) : Context(ctx), Dump(dump) {}
9595
void addRequirements(ArrayRef<Requirement> requirements);
96+
void addRequirements(ArrayRef<StructuralRequirement> requirements);
9697
void addProtocols(ArrayRef<const ProtocolDecl *> proto);
9798
void addProtocol(const ProtocolDecl *proto,
9899
bool initialComponent);
99100
void addAssociatedType(const AssociatedTypeDecl *type,
100101
const ProtocolDecl *proto);
101102
void addRequirement(const Requirement &req,
102103
const ProtocolDecl *proto);
104+
void addRequirement(const StructuralRequirement &req,
105+
const ProtocolDecl *proto);
103106
void collectRulesFromReferencedProtocols();
104107
};
105108

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,44 @@ void RequirementMachine::initWithAbstractRequirements(
257257
}
258258
}
259259

260+
/// Build a requirement machine from a set of generic parameters and
261+
/// structural requirements.
262+
///
263+
/// This must only be called exactly once, before any other operations are
264+
/// performed on this requirement machine.
265+
///
266+
/// Used by InferredGenericSignatureRequest.
267+
void RequirementMachine::initWithWrittenRequirements(
268+
ArrayRef<GenericTypeParamType *> genericParams,
269+
ArrayRef<StructuralRequirement> requirements) {
270+
Params.append(genericParams.begin(), genericParams.end());
271+
272+
FrontendStatsTracer tracer(Stats, "build-rewrite-system");
273+
274+
if (Dump) {
275+
llvm::dbgs() << "Adding generic parameters:";
276+
for (auto *paramTy : genericParams)
277+
llvm::dbgs() << " " << Type(paramTy);
278+
llvm::dbgs() << "\n";
279+
}
280+
281+
// Collect the top-level requirements, and all transtively-referenced
282+
// protocol requirement signatures.
283+
RuleBuilder builder(Context, Dump);
284+
builder.addRequirements(requirements);
285+
286+
// Add the initial set of rewrite rules to the rewrite system.
287+
System.initialize(/*recordLoops=*/true,
288+
std::move(builder.PermanentRules),
289+
std::move(builder.RequirementRules));
290+
291+
computeCompletion(RewriteSystem::AllowInvalidRequirements);
292+
293+
if (Dump) {
294+
llvm::dbgs() << "}\n";
295+
}
296+
}
297+
260298
/// Attempt to obtain a confluent rewrite system by iterating the Knuth-Bendix
261299
/// completion procedure together with property map construction until fixed
262300
/// point.

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ class RequirementMachine final {
8686
void initWithAbstractRequirements(
8787
ArrayRef<GenericTypeParamType *> genericParams,
8888
ArrayRef<Requirement> requirements);
89+
void initWithWrittenRequirements(
90+
ArrayRef<GenericTypeParamType *> genericParams,
91+
ArrayRef<StructuralRequirement> requirements);
8992

9093
bool isComplete() const;
9194

0 commit comments

Comments
 (0)