@@ -47,12 +47,12 @@ RequirementMachine::getLocalRequirements(
4747 return result;
4848
4949 if (props->isConcreteType ()) {
50- result.concreteType = props->getConcreteType ({}, protos, Context);
50+ result.concreteType = props->getConcreteType ({}, term, protos, Context);
5151 return result;
5252 }
5353
5454 if (props->hasSuperclassBound ()) {
55- result.superclass = props->getSuperclassBound ({}, protos, Context);
55+ result.superclass = props->getSuperclassBound ({}, term, protos, Context);
5656 }
5757
5858 for (const auto *proto : props->getConformsToExcludingSuperclassConformances ())
@@ -153,7 +153,7 @@ Type RequirementMachine::getSuperclassBound(Type depType) const {
153153 return Type ();
154154
155155 auto &protos = System.getProtocols ();
156- return props->getSuperclassBound ({ }, protos, Context);
156+ return props->getSuperclassBound ({ }, term, protos, Context);
157157}
158158
159159bool RequirementMachine::isConcreteType (Type depType) const {
@@ -183,7 +183,7 @@ Type RequirementMachine::getConcreteType(Type depType) const {
183183 return Type ();
184184
185185 auto &protos = System.getProtocols ();
186- return props->getConcreteType ({ }, protos, Context);
186+ return props->getConcreteType ({ }, term, protos, Context);
187187}
188188
189189bool RequirementMachine::areSameTypeParameterInContext (Type depType1,
@@ -346,14 +346,33 @@ Type RequirementMachine::getCanonicalTypeInContext(
346346 verify (prefix);
347347
348348 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+ }
357376 }
358377
359378 return Context.getTypeForTerm (prefix, genericParams, protos);
0 commit comments