Skip to content

Commit c6441c0

Browse files
committed
RequirementMachine: Add machinery for recording concrete type witnesses
1 parent 088c540 commit c6441c0

File tree

2 files changed

+131
-57
lines changed

2 files changed

+131
-57
lines changed

lib/AST/RequirementMachine/PropertyUnification.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,50 @@ void PropertyMap::concretizeTypeWitnessInConformance(
650650
}
651651
}
652652

653+
RewriteSystem::ConcreteTypeWitness::ConcreteTypeWitness(
654+
Symbol concreteConformance,
655+
Symbol assocType,
656+
Symbol concreteType)
657+
: ConcreteConformance(concreteConformance),
658+
AssocType(assocType),
659+
ConcreteType(concreteType) {
660+
assert(concreteConformance.getKind() == Symbol::Kind::ConcreteConformance);
661+
assert(assocType.getKind() == Symbol::Kind::AssociatedType);
662+
assert(concreteType.getKind() == Symbol::Kind::ConcreteType);
663+
assert(assocType.getProtocols().size() == 1);
664+
assert(assocType.getProtocols()[0] == concreteConformance.getProtocol());
665+
}
666+
667+
bool swift::rewriting::operator==(
668+
const RewriteSystem::ConcreteTypeWitness &lhs,
669+
const RewriteSystem::ConcreteTypeWitness &rhs) {
670+
return (lhs.ConcreteConformance == rhs.ConcreteConformance &&
671+
lhs.AssocType == rhs.AssocType &&
672+
lhs.ConcreteType == rhs.ConcreteType);
673+
}
674+
675+
unsigned RewriteSystem::recordConcreteTypeWitness(
676+
RewriteSystem::ConcreteTypeWitness witness) {
677+
auto key = std::make_pair(witness.ConcreteConformance,
678+
witness.AssocType);
679+
unsigned index = ConcreteTypeWitnesses.size();
680+
auto inserted = ConcreteTypeWitnessMap.insert(std::make_pair(key, index));
681+
682+
if (!inserted.second) {
683+
index = inserted.first->second;
684+
} else {
685+
ConcreteTypeWitnesses.push_back(witness);
686+
}
687+
688+
assert(ConcreteTypeWitnesses[index] == witness);
689+
return index;
690+
}
691+
692+
const RewriteSystem::ConcreteTypeWitness &
693+
RewriteSystem::getConcreteTypeWitness(unsigned index) const {
694+
return ConcreteTypeWitnesses[index];
695+
}
696+
653697
/// Given the key of a property bag known to have \p concreteType,
654698
/// together with a \p typeWitness from a conformance on that concrete
655699
/// type, return the right hand side of a rewrite rule to relate

lib/AST/RequirementMachine/RewriteSystem.h

Lines changed: 87 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -197,44 +197,6 @@ class RewriteSystem final {
197197
/// type is an index into the Rules array defined above.
198198
Trie<unsigned, MatchKind::Shortest> Trie;
199199

200-
/// Constructed from a rule of the form X.[P2:T] => X.[P1:T] by
201-
/// checkMergedAssociatedType().
202-
struct MergedAssociatedType {
203-
/// The *right* hand side of the original rule, X.[P1:T].
204-
Term rhs;
205-
206-
/// The associated type symbol appearing at the end of the *left*
207-
/// hand side of the original rule, [P2:T].
208-
Symbol lhsSymbol;
209-
210-
/// The merged associated type symbol, [P1&P2:T].
211-
Symbol mergedSymbol;
212-
};
213-
214-
/// A list of pending terms for the associated type merging completion
215-
/// heuristic. Entries are added by checkMergedAssociatedType(), and
216-
/// consumed in processMergedAssociatedTypes().
217-
std::vector<MergedAssociatedType> MergedAssociatedTypes;
218-
219-
/// Pairs of rules which have already been checked for overlap.
220-
llvm::DenseSet<std::pair<unsigned, unsigned>> CheckedOverlaps;
221-
222-
/// Homotopy generators for this rewrite system. These are the
223-
/// rewrite loops which rewrite a term back to itself.
224-
///
225-
/// In the category theory interpretation, a rewrite rule is a generating
226-
/// 2-cell, and a rewrite path is a 2-cell made from a composition of
227-
/// generating 2-cells.
228-
///
229-
/// Homotopy generators, in turn, are 3-cells. The special case of a
230-
/// 3-cell discovered during completion can be viewed as two parallel
231-
/// 2-cells; this is actually represented as a single 2-cell forming a
232-
/// loop around a base point.
233-
///
234-
/// This data is used by the homotopy reduction and generating conformances
235-
/// algorithms.
236-
std::vector<RewriteLoop> Loops;
237-
238200
DebugOptions Debug;
239201

240202
/// Whether we've initialized the rewrite system with a call to initialize().
@@ -288,10 +250,6 @@ class RewriteSystem final {
288250
return Rules[ruleID];
289251
}
290252

291-
ArrayRef<RewriteLoop> getLoops() const {
292-
return Loops;
293-
}
294-
295253
bool addRule(MutableTerm lhs, MutableTerm rhs,
296254
const RewritePath *path=nullptr);
297255

@@ -309,6 +267,9 @@ class RewriteSystem final {
309267
///
310268
//////////////////////////////////////////////////////////////////////////////
311269

270+
/// Pairs of rules which have already been checked for overlap.
271+
llvm::DenseSet<std::pair<unsigned, unsigned>> CheckedOverlaps;
272+
312273
std::pair<CompletionResult, unsigned>
313274
computeConfluentCompletion(unsigned maxIterations,
314275
unsigned maxDepth);
@@ -325,21 +286,6 @@ class RewriteSystem final {
325286
void verifyRewriteRules(ValidityPolicy policy) const;
326287

327288
private:
328-
void recordRewriteLoop(RewriteLoop loop) {
329-
if (!RecordLoops)
330-
return;
331-
332-
Loops.push_back(loop);
333-
}
334-
335-
void recordRewriteLoop(MutableTerm basepoint,
336-
RewritePath path) {
337-
if (!RecordLoops)
338-
return;
339-
340-
Loops.emplace_back(basepoint, path);
341-
}
342-
343289
bool
344290
computeCriticalPair(
345291
ArrayRef<Symbol>::const_iterator from,
@@ -348,16 +294,96 @@ class RewriteSystem final {
348294
std::vector<RewritePath> &paths,
349295
std::vector<RewriteLoop> &loops) const;
350296

297+
/// Constructed from a rule of the form X.[P2:T] => X.[P1:T] by
298+
/// checkMergedAssociatedType().
299+
struct MergedAssociatedType {
300+
/// The *right* hand side of the original rule, X.[P1:T].
301+
Term rhs;
302+
303+
/// The associated type symbol appearing at the end of the *left*
304+
/// hand side of the original rule, [P2:T].
305+
Symbol lhsSymbol;
306+
307+
/// The merged associated type symbol, [P1&P2:T].
308+
Symbol mergedSymbol;
309+
};
310+
311+
/// A list of pending terms for the associated type merging completion
312+
/// heuristic. Entries are added by checkMergedAssociatedType(), and
313+
/// consumed in processMergedAssociatedTypes().
314+
std::vector<MergedAssociatedType> MergedAssociatedTypes;
315+
351316
void processMergedAssociatedTypes();
352317

353318
void checkMergedAssociatedType(Term lhs, Term rhs);
354319

320+
//////////////////////////////////////////////////////////////////////////////
321+
///
322+
/// "Pseudo-rules" for the property map
323+
///
324+
//////////////////////////////////////////////////////////////////////////////
325+
326+
public:
327+
struct ConcreteTypeWitness {
328+
Symbol ConcreteConformance;
329+
Symbol AssocType;
330+
Symbol ConcreteType;
331+
332+
ConcreteTypeWitness(Symbol concreteConformance,
333+
Symbol assocType,
334+
Symbol concreteType);
335+
336+
friend bool operator==(const ConcreteTypeWitness &lhs,
337+
const ConcreteTypeWitness &rhs);
338+
};
339+
340+
private:
341+
/// Cache for concrete type witnesses. The value in the map is an index
342+
/// into the vector.
343+
llvm::DenseMap<std::pair<Symbol, Symbol>, unsigned> ConcreteTypeWitnessMap;
344+
std::vector<ConcreteTypeWitness> ConcreteTypeWitnesses;
345+
346+
public:
347+
unsigned recordConcreteTypeWitness(ConcreteTypeWitness witness);
348+
const ConcreteTypeWitness &getConcreteTypeWitness(unsigned index) const;
349+
355350
//////////////////////////////////////////////////////////////////////////////
356351
///
357352
/// Homotopy reduction
358353
///
359354
//////////////////////////////////////////////////////////////////////////////
360355

356+
/// Homotopy generators for this rewrite system. These are the
357+
/// rewrite loops which rewrite a term back to itself.
358+
///
359+
/// In the category theory interpretation, a rewrite rule is a generating
360+
/// 2-cell, and a rewrite path is a 2-cell made from a composition of
361+
/// generating 2-cells.
362+
///
363+
/// Homotopy generators, in turn, are 3-cells. The special case of a
364+
/// 3-cell discovered during completion can be viewed as two parallel
365+
/// 2-cells; this is actually represented as a single 2-cell forming a
366+
/// loop around a base point.
367+
///
368+
/// This data is used by the homotopy reduction and generating conformances
369+
/// algorithms.
370+
std::vector<RewriteLoop> Loops;
371+
372+
void recordRewriteLoop(RewriteLoop loop) {
373+
if (!RecordLoops)
374+
return;
375+
376+
Loops.push_back(loop);
377+
}
378+
379+
void recordRewriteLoop(MutableTerm basepoint,
380+
RewritePath path) {
381+
if (!RecordLoops)
382+
return;
383+
384+
Loops.emplace_back(basepoint, path);
385+
}
386+
361387
void propagateExplicitBits();
362388

363389
bool
@@ -377,6 +403,10 @@ class RewriteSystem final {
377403
llvm::DenseSet<unsigned> &redundantConformances);
378404

379405
public:
406+
ArrayRef<RewriteLoop> getLoops() const {
407+
return Loops;
408+
}
409+
380410
void minimizeRewriteSystem();
381411

382412
bool hadError() const;

0 commit comments

Comments
 (0)