@@ -137,26 +137,29 @@ class RewritePath {
137
137
// / When present, it indicates that the entire path will be rebased on
138
138
// / the given base generic parameter. This is required for describing
139
139
// / 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.
140
143
Optional<GenericParamKey> getBase () const { return base; }
141
144
142
145
// / Retrieve the sequence of associated type references that describes
143
146
// / the path.
144
147
ArrayRef<AssociatedTypeDecl *> getPath () const { return path; }
145
148
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
+
146
155
// / Decompose a type into a path.
147
156
// /
148
157
// / \returns the path, or None if it contained unresolved dependent member
149
158
// / types.
150
159
Optional<RewritePath> static createPath (Type type);
151
160
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 ;
160
163
161
164
// / Form a canonical, dependent type.
162
165
// /
@@ -262,9 +265,18 @@ class RewriteTreeNode {
262
265
// / \c matchPath that matched and \c rewrite is the path to which it can
263
266
// / be rewritten.
264
267
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:
268
280
269
281
// / Find the best rewrite rule to match the given path.
270
282
// /
@@ -314,7 +326,8 @@ struct GenericSignatureBuilder::Implementation {
314
326
std::vector<void *> FreeEquivalenceClasses;
315
327
316
328
// / The roots of the rewrite tree.
317
- DenseMap<const EquivalenceClass *, RewriteTreeNode *> RewriteTreeRoots;
329
+ DenseMap<const EquivalenceClass *, std::unique_ptr<RewriteTreeNode>>
330
+ RewriteTreeRoots;
318
331
319
332
// / The generation number, which is incremented whenever we successfully
320
333
// / introduce a new constraint.
@@ -362,9 +375,6 @@ struct GenericSignatureBuilder::Implementation {
362
375
GenericSignatureBuilder::Implementation::~Implementation () {
363
376
for (auto pa : PotentialArchetypes)
364
377
pa->~PotentialArchetype ();
365
-
366
- for (const auto &root : RewriteTreeRoots)
367
- delete root.second ;
368
378
}
369
379
370
380
EquivalenceClass *
@@ -3093,19 +3103,6 @@ RewritePath::RewritePath(Optional<GenericParamKey> base,
3093
3103
}
3094
3104
}
3095
3105
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
-
3109
3106
Optional<RewritePath> RewritePath::createPath (Type type) {
3110
3107
SmallVector<AssociatedTypeDecl *, 4 > path;
3111
3108
while (auto depMemTy = type->getAs <DependentMemberType>()) {
@@ -3122,10 +3119,10 @@ Optional<RewritePath> RewritePath::createPath(Type type) {
3122
3119
return RewritePath (GenericParamKey (genericParam), path, Reverse);
3123
3120
}
3124
3121
3125
- Optional< RewritePath> RewritePath::commonPath (const RewritePath &other) const {
3122
+ RewritePath RewritePath::commonPath (const RewritePath &other) const {
3126
3123
assert (getBase ().hasValue () && other.getBase ().hasValue ());
3127
3124
3128
- if (*getBase () != *other.getBase ()) return None ;
3125
+ if (*getBase () != *other.getBase ()) return RewritePath () ;
3129
3126
3130
3127
// Find the longest common prefix.
3131
3128
RelativeRewritePath path1 = getPath ();
@@ -3276,7 +3273,7 @@ void RewriteTreeNode::addRewriteRule(RelativeRewritePath matchPath,
3276
3273
(*childPos)->addRewriteRule (matchPath.slice (1 ), replacementPath);
3277
3274
}
3278
3275
3279
- void RewriteTreeNode::enumerateRewritePaths (
3276
+ void RewriteTreeNode::enumerateRewritePathsImpl (
3280
3277
RelativeRewritePath matchPath,
3281
3278
llvm::function_ref<void (unsigned , RewritePath)> callback,
3282
3279
unsigned depth) const {
@@ -3289,7 +3286,7 @@ void RewriteTreeNode::enumerateRewritePaths(
3289
3286
if (childPos != children.end () &&
3290
3287
(*childPos)->getMatch () == matchPath[depth]) {
3291
3288
// Try to match the rest of the path.
3292
- (*childPos)->enumerateRewritePaths (matchPath, callback, depth + 1 );
3289
+ (*childPos)->enumerateRewritePathsImpl (matchPath, callback, depth + 1 );
3293
3290
}
3294
3291
3295
3292
// If we have a rewrite rule at this position, invoke it.
@@ -3301,7 +3298,7 @@ void RewriteTreeNode::enumerateRewritePaths(
3301
3298
// Walk any children with NULL associated types; they might have more matches.
3302
3299
for (auto otherRewrite : children) {
3303
3300
if (otherRewrite->getMatch ()) break ;
3304
- otherRewrite->enumerateRewritePaths (matchPath, callback, depth);
3301
+ otherRewrite->enumerateRewritePathsImpl (matchPath, callback, depth);
3305
3302
}
3306
3303
}
3307
3304
@@ -3408,7 +3405,7 @@ RewriteTreeNode *
3408
3405
GenericSignatureBuilder::Implementation::getRewriteTreeRootIfPresent (
3409
3406
const EquivalenceClass *equivClass) {
3410
3407
auto known = RewriteTreeRoots.find (equivClass);
3411
- if (known != RewriteTreeRoots.end ()) return known->second ;
3408
+ if (known != RewriteTreeRoots.end ()) return known->second . get () ;
3412
3409
3413
3410
return nullptr ;
3414
3411
}
@@ -3417,11 +3414,11 @@ RewriteTreeNode *
3417
3414
GenericSignatureBuilder::Implementation::getOrCreateRewriteTreeRoot (
3418
3415
const EquivalenceClass *equivClass) {
3419
3416
auto known = RewriteTreeRoots.find (equivClass);
3420
- if (known != RewriteTreeRoots.end ()) return known->second ;
3417
+ if (known != RewriteTreeRoots.end ()) return known->second . get () ;
3421
3418
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 () ;
3425
3422
}
3426
3423
3427
3424
void GenericSignatureBuilder::addSameTypeRewriteRule (
@@ -3449,15 +3446,15 @@ void GenericSignatureBuilder::addSameTypeRewriteRule(
3449
3446
if (auto prefix = path1.commonPath (path2)) {
3450
3447
// Find the better relative rewrite path.
3451
3448
RelativeRewritePath relPath1
3452
- = path1.getPath ().slice (prefix-> getPath ().size ());
3449
+ = path1.getPath ().slice (prefix. getPath ().size ());
3453
3450
RelativeRewritePath relPath2
3454
- = path2.getPath ().slice (prefix-> getPath ().size ());
3451
+ = path2.getPath ().slice (prefix. getPath ().size ());
3455
3452
// Order the paths so that we go to the more-canonical path.
3456
3453
if (compareDependentPaths (relPath1, relPath2) < 0 )
3457
3454
std::swap (relPath1, relPath2);
3458
3455
3459
3456
// Find the equivalence class for the prefix.
3460
- CanType commonType = prefix-> formDependentType (getASTContext ());
3457
+ CanType commonType = prefix. formDependentType (getASTContext ());
3461
3458
auto equivClass =
3462
3459
resolveEquivalenceClass (commonType, ArchetypeResolutionKind::WellFormed);
3463
3460
assert (equivClass && " Prefix cannot be resolved?" );
@@ -4606,11 +4603,12 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4606
4603
// Merge the second rewrite tree into the first.
4607
4604
rewriteRoot2->mergeInto (rewriteRoot1);
4608
4605
Impl->RewriteTreeRoots .erase (equivClass2);
4609
- delete rewriteRoot2;
4610
4606
} else {
4611
4607
// 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)});
4614
4612
}
4615
4613
}
4616
4614
}
0 commit comments