@@ -43,6 +43,7 @@ struct ConnectedComponent {
43
43
Type ConcreteType;
44
44
45
45
void buildRequirements (Type subjectType,
46
+ RequirementKind kind,
46
47
std::vector<Requirement> &reqs,
47
48
std::vector<ProtocolTypeAlias> &aliases);
48
49
};
@@ -68,6 +69,7 @@ struct ConnectedComponent {
68
69
// /
69
70
// / A == X, B == X, C == X, D == X
70
71
void ConnectedComponent::buildRequirements (Type subjectType,
72
+ RequirementKind kind,
71
73
std::vector<Requirement> &reqs,
72
74
std::vector<ProtocolTypeAlias> &aliases) {
73
75
std::sort (Members.begin (), Members.end (),
@@ -81,12 +83,14 @@ void ConnectedComponent::buildRequirements(Type subjectType,
81
83
}
82
84
83
85
for (auto constraintType : Members) {
84
- reqs.emplace_back (RequirementKind::SameType,
85
- subjectType, constraintType);
86
+ reqs.emplace_back (kind, subjectType, constraintType);
86
87
subjectType = constraintType;
87
88
}
88
89
89
90
} else {
91
+ // Shape requirements cannot be concrete.
92
+ assert (kind == RequirementKind::SameType);
93
+
90
94
// If there are multiple protocol typealiases in the connected component,
91
95
// lower them all to a series of identical concrete-type aliases.
92
96
for (auto name : Aliases) {
@@ -135,7 +139,7 @@ class RequirementBuilder {
135
139
136
140
// Temporary state populated by addRequirementRules() and
137
141
// addTypeAliasRules().
138
- llvm::SmallDenseMap<TypeBase * , ConnectedComponent> Components;
142
+ llvm::SmallDenseMap<Term , ConnectedComponent> Components;
139
143
140
144
public:
141
145
// Results.
@@ -229,7 +233,7 @@ void RequirementBuilder::addRequirementRules(ArrayRef<unsigned> rules) {
229
233
if (ReconstituteSugar)
230
234
concreteType = concreteType->reconstituteSugar (/* recursive=*/ true );
231
235
232
- auto &component = Components[subjectType. getPointer ()];
236
+ auto &component = Components[rule. getRHS ()];
233
237
assert (!component.ConcreteType );
234
238
component.ConcreteType = concreteType;
235
239
return ;
@@ -250,28 +254,18 @@ void RequirementBuilder::addRequirementRules(ArrayRef<unsigned> rules) {
250
254
llvm_unreachable (" Invalid symbol kind" );
251
255
}
252
256
253
- if (rule.getLHS ().back ().getKind () == Symbol::Kind::Shape) {
254
- assert (rule.getRHS ().back ().getKind () == Symbol::Kind::Shape);
257
+ assert (rule.getLHS ().back ().getKind () != Symbol::Kind::Protocol);
255
258
256
- // Strip off the shape symbols from either side of the rule.
257
- MutableTerm lhsTerm (rule.getLHS ().begin (),
258
- rule.getLHS ().end () - 1 );
259
- MutableTerm rhsTerm (rule.getRHS ().begin (),
260
- rule.getRHS ().end () - 1 );
261
-
262
- // Add a SameCount requirement between the two parameter packs.
263
- auto constraintType = Map.getTypeForTerm (lhsTerm, GenericParams);
264
- auto subjectType = Map.getTypeForTerm (rhsTerm, GenericParams);
265
- Reqs.emplace_back (RequirementKind::SameCount,
266
- subjectType, constraintType);
267
- return ;
259
+ MutableTerm constraintTerm (rule.getLHS ());
260
+ if (constraintTerm.back ().getKind () == Symbol::Kind::Shape) {
261
+ assert (rule.getRHS ().back ().getKind () == Symbol::Kind::Shape);
262
+ // Strip off the shape symbol from the constraint term.
263
+ constraintTerm = MutableTerm (constraintTerm.begin (),
264
+ constraintTerm.end () - 1 );
268
265
}
269
266
270
- assert (rule.getLHS ().back ().getKind () != Symbol::Kind::Protocol);
271
- auto constraintType = Map.getTypeForTerm (rule.getLHS (), GenericParams);
272
- auto subjectType = Map.getTypeForTerm (rule.getRHS (), GenericParams);
273
-
274
- Components[subjectType.getPointer ()].Members .push_back (constraintType);
267
+ auto constraintType = Map.getTypeForTerm (constraintTerm, GenericParams);
268
+ Components[rule.getRHS ()].Members .push_back (constraintType);
275
269
};
276
270
277
271
if (Debug) {
@@ -319,11 +313,11 @@ void RequirementBuilder::addTypeAliasRules(ArrayRef<unsigned> rules) {
319
313
if (ReconstituteSugar)
320
314
concreteType = concreteType->reconstituteSugar (/* recursive=*/ true );
321
315
322
- auto &component = Components[subjectType. getPointer ()];
316
+ auto &component = Components[rule. getRHS ()];
323
317
assert (!component.ConcreteType );
324
- Components[subjectType. getPointer ()].ConcreteType = concreteType;
318
+ Components[rule. getRHS ()].ConcreteType = concreteType;
325
319
} else {
326
- Components[subjectType. getPointer ()].Aliases .push_back (name);
320
+ Components[rule. getRHS ()].Aliases .push_back (name);
327
321
}
328
322
}
329
323
}
@@ -332,7 +326,18 @@ void RequirementBuilder::processConnectedComponents() {
332
326
// Now, convert each connected component into a series of same-type
333
327
// requirements.
334
328
for (auto &pair : Components) {
335
- pair.second .buildRequirements (pair.first , Reqs, Aliases);
329
+ MutableTerm subjectTerm (pair.first );
330
+ RequirementKind kind;
331
+ if (subjectTerm.back ().getKind () == Symbol::Kind::Shape) {
332
+ kind = RequirementKind::SameCount;
333
+ // Strip off the shape symbol from the subject term.
334
+ subjectTerm = MutableTerm{subjectTerm.begin (), subjectTerm.end () - 1 };
335
+ } else {
336
+ kind = RequirementKind::SameType;
337
+ }
338
+
339
+ auto subjectType = Map.getTypeForTerm (subjectTerm, GenericParams);
340
+ pair.second .buildRequirements (subjectType, kind, Reqs, Aliases);
336
341
}
337
342
}
338
343
0 commit comments