Skip to content

Commit 888e9aa

Browse files
authored
Merge pull request swiftlang#14686 from DougGregor/gsb-term-rewriting-cleanup
2 parents cfebd83 + 04ec33c commit 888e9aa

File tree

2 files changed

+44
-49
lines changed

2 files changed

+44
-49
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -137,26 +137,29 @@ class RewritePath {
137137
/// When present, it indicates that the entire path will be rebased on
138138
/// the given base generic parameter. This is required for describing
139139
/// rewrites on type parameters themselves, e.g., T == U.
140+
///
141+
/// When absent, the path is relative to the root of the tree from which
142+
/// the search began.
140143
Optional<GenericParamKey> getBase() const { return base; }
141144

142145
/// Retrieve the sequence of associated type references that describes
143146
/// the path.
144147
ArrayRef<AssociatedTypeDecl *> getPath() const { return path; }
145148

149+
/// Whether this path is completely empty.
150+
bool isEmpty() const { return getBase() == None && getPath().empty(); }
151+
152+
/// whether this describes a valid path.
153+
explicit operator bool() const { return !isEmpty(); }
154+
146155
/// Decompose a type into a path.
147156
///
148157
/// \returns the path, or None if it contained unresolved dependent member
149158
/// types.
150159
Optional<RewritePath> static createPath(Type type);
151160

152-
/// Decompose a potential archetype into a patch.
153-
///
154-
/// \returns the path, or None if it contained potential archetypes
155-
/// with concrete declarations.
156-
Optional<RewritePath> static createPath(PotentialArchetype *pa);
157-
158-
/// Compute the common path between this path and \c other, if one exists.
159-
Optional<RewritePath> commonPath(const RewritePath &other) const;
161+
/// Compute the longer common prefix between this path and \c other.
162+
RewritePath commonPath(const RewritePath &other) const;
160163

161164
/// Form a canonical, dependent type.
162165
///
@@ -262,9 +265,18 @@ class RewriteTreeNode {
262265
/// \c matchPath that matched and \c rewrite is the path to which it can
263266
/// be rewritten.
264267
void enumerateRewritePaths(
265-
RelativeRewritePath matchPath,
266-
llvm::function_ref<void(unsigned, RewritePath)> callback,
267-
unsigned depth = 0) const;
268+
RelativeRewritePath matchPath,
269+
llvm::function_ref<void(unsigned, RewritePath)> callback) const {
270+
return enumerateRewritePathsImpl(matchPath, callback, /*depth=*/0);
271+
}
272+
273+
private:
274+
void enumerateRewritePathsImpl(
275+
RelativeRewritePath matchPath,
276+
llvm::function_ref<void(unsigned, RewritePath)> callback,
277+
unsigned depth) const;
278+
279+
public:
268280

269281
/// Find the best rewrite rule to match the given path.
270282
///
@@ -314,7 +326,8 @@ struct GenericSignatureBuilder::Implementation {
314326
std::vector<void *> FreeEquivalenceClasses;
315327

316328
/// The roots of the rewrite tree.
317-
DenseMap<const EquivalenceClass *, RewriteTreeNode *> RewriteTreeRoots;
329+
DenseMap<const EquivalenceClass *, std::unique_ptr<RewriteTreeNode>>
330+
RewriteTreeRoots;
318331

319332
/// The generation number, which is incremented whenever we successfully
320333
/// introduce a new constraint.
@@ -362,9 +375,6 @@ struct GenericSignatureBuilder::Implementation {
362375
GenericSignatureBuilder::Implementation::~Implementation() {
363376
for (auto pa : PotentialArchetypes)
364377
pa->~PotentialArchetype();
365-
366-
for (const auto &root : RewriteTreeRoots)
367-
delete root.second;
368378
}
369379

370380
EquivalenceClass *
@@ -3093,19 +3103,6 @@ RewritePath::RewritePath(Optional<GenericParamKey> base,
30933103
}
30943104
}
30953105

3096-
Optional<RewritePath> RewritePath::createPath(PotentialArchetype *pa) {
3097-
SmallVector<AssociatedTypeDecl *, 4> path;
3098-
while (auto parent = pa->getParent()) {
3099-
auto assocType = pa->getResolvedAssociatedType();
3100-
if (!assocType) return None;
3101-
3102-
path.push_back(assocType);
3103-
pa = parent;
3104-
}
3105-
3106-
return RewritePath(pa->getGenericParamKey(), path, Reverse);
3107-
}
3108-
31093106
Optional<RewritePath> RewritePath::createPath(Type type) {
31103107
SmallVector<AssociatedTypeDecl *, 4> path;
31113108
while (auto depMemTy = type->getAs<DependentMemberType>()) {
@@ -3122,10 +3119,10 @@ Optional<RewritePath> RewritePath::createPath(Type type) {
31223119
return RewritePath(GenericParamKey(genericParam), path, Reverse);
31233120
}
31243121

3125-
Optional<RewritePath> RewritePath::commonPath(const RewritePath &other) const {
3122+
RewritePath RewritePath::commonPath(const RewritePath &other) const {
31263123
assert(getBase().hasValue() && other.getBase().hasValue());
31273124

3128-
if (*getBase() != *other.getBase()) return None;
3125+
if (*getBase() != *other.getBase()) return RewritePath();
31293126

31303127
// Find the longest common prefix.
31313128
RelativeRewritePath path1 = getPath();
@@ -3276,7 +3273,7 @@ void RewriteTreeNode::addRewriteRule(RelativeRewritePath matchPath,
32763273
(*childPos)->addRewriteRule(matchPath.slice(1), replacementPath);
32773274
}
32783275

3279-
void RewriteTreeNode::enumerateRewritePaths(
3276+
void RewriteTreeNode::enumerateRewritePathsImpl(
32803277
RelativeRewritePath matchPath,
32813278
llvm::function_ref<void(unsigned, RewritePath)> callback,
32823279
unsigned depth) const {
@@ -3289,7 +3286,7 @@ void RewriteTreeNode::enumerateRewritePaths(
32893286
if (childPos != children.end() &&
32903287
(*childPos)->getMatch() == matchPath[depth]) {
32913288
// Try to match the rest of the path.
3292-
(*childPos)->enumerateRewritePaths(matchPath, callback, depth + 1);
3289+
(*childPos)->enumerateRewritePathsImpl(matchPath, callback, depth + 1);
32933290
}
32943291

32953292
// If we have a rewrite rule at this position, invoke it.
@@ -3301,7 +3298,7 @@ void RewriteTreeNode::enumerateRewritePaths(
33013298
// Walk any children with NULL associated types; they might have more matches.
33023299
for (auto otherRewrite : children) {
33033300
if (otherRewrite->getMatch()) break;
3304-
otherRewrite->enumerateRewritePaths(matchPath, callback, depth);
3301+
otherRewrite->enumerateRewritePathsImpl(matchPath, callback, depth);
33053302
}
33063303
}
33073304

@@ -3408,7 +3405,7 @@ RewriteTreeNode *
34083405
GenericSignatureBuilder::Implementation::getRewriteTreeRootIfPresent(
34093406
const EquivalenceClass *equivClass) {
34103407
auto known = RewriteTreeRoots.find(equivClass);
3411-
if (known != RewriteTreeRoots.end()) return known->second;
3408+
if (known != RewriteTreeRoots.end()) return known->second.get();
34123409

34133410
return nullptr;
34143411
}
@@ -3417,11 +3414,11 @@ RewriteTreeNode *
34173414
GenericSignatureBuilder::Implementation::getOrCreateRewriteTreeRoot(
34183415
const EquivalenceClass *equivClass) {
34193416
auto known = RewriteTreeRoots.find(equivClass);
3420-
if (known != RewriteTreeRoots.end()) return known->second;
3417+
if (known != RewriteTreeRoots.end()) return known->second.get();
34213418

3422-
auto root = new RewriteTreeNode(nullptr);
3423-
RewriteTreeRoots[equivClass] = root;
3424-
return root;
3419+
auto &root = RewriteTreeRoots[equivClass];
3420+
root = std::unique_ptr<RewriteTreeNode>(new RewriteTreeNode(nullptr));
3421+
return root.get();
34253422
}
34263423

34273424
void GenericSignatureBuilder::addSameTypeRewriteRule(
@@ -3449,15 +3446,15 @@ void GenericSignatureBuilder::addSameTypeRewriteRule(
34493446
if (auto prefix = path1.commonPath(path2)) {
34503447
// Find the better relative rewrite path.
34513448
RelativeRewritePath relPath1
3452-
= path1.getPath().slice(prefix->getPath().size());
3449+
= path1.getPath().slice(prefix.getPath().size());
34533450
RelativeRewritePath relPath2
3454-
= path2.getPath().slice(prefix->getPath().size());
3451+
= path2.getPath().slice(prefix.getPath().size());
34553452
// Order the paths so that we go to the more-canonical path.
34563453
if (compareDependentPaths(relPath1, relPath2) < 0)
34573454
std::swap(relPath1, relPath2);
34583455

34593456
// Find the equivalence class for the prefix.
3460-
CanType commonType = prefix->formDependentType(getASTContext());
3457+
CanType commonType = prefix.formDependentType(getASTContext());
34613458
auto equivClass =
34623459
resolveEquivalenceClass(commonType, ArchetypeResolutionKind::WellFormed);
34633460
assert(equivClass && "Prefix cannot be resolved?");
@@ -4606,11 +4603,12 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
46064603
// Merge the second rewrite tree into the first.
46074604
rewriteRoot2->mergeInto(rewriteRoot1);
46084605
Impl->RewriteTreeRoots.erase(equivClass2);
4609-
delete rewriteRoot2;
46104606
} else {
46114607
// Take the second rewrite tree and make it the first.
4612-
Impl->RewriteTreeRoots.erase(equivClass2);
4613-
(void)Impl->RewriteTreeRoots.insert({equivClass, rewriteRoot2});
4608+
auto root2Entry = Impl->RewriteTreeRoots.find(equivClass2);
4609+
auto root2Ptr = std::move(root2Entry->second);
4610+
Impl->RewriteTreeRoots.erase(root2Entry);
4611+
(void)Impl->RewriteTreeRoots.insert({equivClass, std::move(root2Ptr)});
46144612
}
46154613
}
46164614
}

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,11 +1236,8 @@ void AssociatedTypeInference::findSolutionsRec(
12361236

12371237
// If we've seen this solution already, bail out; there's no point in
12381238
// checking further.
1239-
if (std::find_if(solutions.begin(), solutions.end(), matchesSolution)
1240-
!= solutions.end() ||
1241-
std::find_if(nonViableSolutions.begin(), nonViableSolutions.end(),
1242-
matchesSolution)
1243-
!= nonViableSolutions.end()) {
1239+
if (llvm::any_of(solutions, matchesSolution) ||
1240+
llvm::any_of(nonViableSolutions, matchesSolution)) {
12441241
++NumDuplicateSolutionStates;
12451242
return;
12461243
}

0 commit comments

Comments
 (0)