Skip to content

Commit d6c9bd3

Browse files
authored
Merge pull request #38743 from slavapestov/requirement-machine-superclass-fixes
RequirementMachine: Fixes some bugs with superclass requirements
2 parents d66562c + 4f2aa5f commit d6c9bd3

13 files changed

+505
-101
lines changed

include/swift/AST/TypeMatcher.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,25 @@ class TypeMatcher {
195195
TRIVIAL_CASE(ModuleType)
196196
TRIVIAL_CASE(DynamicSelfType)
197197
TRIVIAL_CASE(ArchetypeType)
198-
TRIVIAL_CASE(DependentMemberType)
198+
199+
bool visitDependentMemberType(CanDependentMemberType firstType,
200+
Type secondType,
201+
Type sugaredFirstType) {
202+
/* If the types match, continue. */
203+
if (!Matcher.asDerived().alwaysMismatchTypeParameters() &&
204+
firstType->isEqual(secondType))
205+
return true;
206+
207+
/* Otherwise, let the derived class deal with the mismatch. */
208+
return mismatch(firstType.getPointer(), secondType,
209+
sugaredFirstType);
210+
}
199211

200212
bool visitGenericTypeParamType(CanGenericTypeParamType firstType,
201213
Type secondType,
202214
Type sugaredFirstType) {
203215
/* If the types match, continue. */
204-
if (!Matcher.asDerived().alwaysMismatchGenericParams() &&
216+
if (!Matcher.asDerived().alwaysMismatchTypeParameters() &&
205217
firstType->isEqual(secondType))
206218
return true;
207219

@@ -312,7 +324,7 @@ class TypeMatcher {
312324
#undef TRIVIAL_CASE
313325
};
314326

315-
bool alwaysMismatchGenericParams() const { return false; }
327+
bool alwaysMismatchTypeParameters() const { return false; }
316328

317329
ImplClass &asDerived() { return static_cast<ImplClass &>(*this); }
318330

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4494,7 +4494,7 @@ bool GenericSignatureBuilder::updateSuperclass(
44944494

44954495
auto layout =
44964496
LayoutConstraint::getLayoutConstraint(
4497-
superclass->getClassOrBoundGenericClass()->isObjC()
4497+
superclass->getClassOrBoundGenericClass()->usesObjCObjectModel()
44984498
? LayoutConstraintKind::Class
44994499
: LayoutConstraintKind::NativeClass,
45004500
getASTContext());

lib/AST/RequirementMachine/GenericSignatureQueries.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

159159
bool 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

189189
bool 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

Comments
 (0)