@@ -47,12 +47,12 @@ RequirementMachine::getLocalRequirements(
47
47
return result;
48
48
49
49
if (props->isConcreteType ()) {
50
- result.concreteType = props->getConcreteType ({}, protos, Context);
50
+ result.concreteType = props->getConcreteType ({}, term, protos, Context);
51
51
return result;
52
52
}
53
53
54
54
if (props->hasSuperclassBound ()) {
55
- result.superclass = props->getSuperclassBound ({}, protos, Context);
55
+ result.superclass = props->getSuperclassBound ({}, term, protos, Context);
56
56
}
57
57
58
58
for (const auto *proto : props->getConformsToExcludingSuperclassConformances ())
@@ -153,7 +153,7 @@ Type RequirementMachine::getSuperclassBound(Type depType) const {
153
153
return Type ();
154
154
155
155
auto &protos = System.getProtocols ();
156
- return props->getSuperclassBound ({ }, protos, Context);
156
+ return props->getSuperclassBound ({ }, term, protos, Context);
157
157
}
158
158
159
159
bool RequirementMachine::isConcreteType (Type depType) const {
@@ -183,7 +183,7 @@ Type RequirementMachine::getConcreteType(Type depType) const {
183
183
return Type ();
184
184
185
185
auto &protos = System.getProtocols ();
186
- return props->getConcreteType ({ }, protos, Context);
186
+ return props->getConcreteType ({ }, term, protos, Context);
187
187
}
188
188
189
189
bool RequirementMachine::areSameTypeParameterInContext (Type depType1,
@@ -346,14 +346,33 @@ Type RequirementMachine::getCanonicalTypeInContext(
346
346
verify (prefix);
347
347
348
348
auto *props = Map.lookUpProperties (prefix);
349
- if (props && props->isConcreteType ()) {
350
- auto concreteType = props->getConcreteType (genericParams,
351
- protos, Context);
352
- if (!concreteType->hasTypeParameter ())
353
- return concreteType;
354
-
355
- // FIXME: Recursion guard is needed here
356
- return getCanonicalTypeInContext (concreteType, genericParams);
349
+ if (props) {
350
+ if (props->isConcreteType ()) {
351
+ auto concreteType = props->getConcreteType (genericParams,
352
+ prefix, protos,
353
+ Context);
354
+ if (!concreteType->hasTypeParameter ())
355
+ return concreteType;
356
+
357
+ // FIXME: Recursion guard is needed here
358
+ return getCanonicalTypeInContext (concreteType, genericParams);
359
+ }
360
+
361
+ // Skip this part if the entire input term is valid, because in that
362
+ // case we don't want to replace the term with its superclass bound;
363
+ // unlike a fixed concrete type, the superclass bound only comes into
364
+ // play when looking up a member type.
365
+ if (props->hasSuperclassBound () &&
366
+ prefix.size () != term.size ()) {
367
+ auto superclass = props->getSuperclassBound (genericParams,
368
+ prefix, protos,
369
+ Context);
370
+ if (!superclass->hasTypeParameter ())
371
+ return superclass;
372
+
373
+ // FIXME: Recursion guard is needed here
374
+ return getCanonicalTypeInContext (superclass, genericParams);
375
+ }
357
376
}
358
377
359
378
return Context.getTypeForTerm (prefix, genericParams, protos);
0 commit comments