Skip to content

RequirementMachine: Fixes some bugs with superclass requirements #38743

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
18 changes: 15 additions & 3 deletions include/swift/AST/TypeMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,25 @@ class TypeMatcher {
TRIVIAL_CASE(ModuleType)
TRIVIAL_CASE(DynamicSelfType)
TRIVIAL_CASE(ArchetypeType)
TRIVIAL_CASE(DependentMemberType)

bool visitDependentMemberType(CanDependentMemberType firstType,
Type secondType,
Type sugaredFirstType) {
/* If the types match, continue. */
if (!Matcher.asDerived().alwaysMismatchTypeParameters() &&
firstType->isEqual(secondType))
return true;

/* Otherwise, let the derived class deal with the mismatch. */
return mismatch(firstType.getPointer(), secondType,
sugaredFirstType);
}

bool visitGenericTypeParamType(CanGenericTypeParamType firstType,
Type secondType,
Type sugaredFirstType) {
/* If the types match, continue. */
if (!Matcher.asDerived().alwaysMismatchGenericParams() &&
if (!Matcher.asDerived().alwaysMismatchTypeParameters() &&
firstType->isEqual(secondType))
return true;

Expand Down Expand Up @@ -312,7 +324,7 @@ class TypeMatcher {
#undef TRIVIAL_CASE
};

bool alwaysMismatchGenericParams() const { return false; }
bool alwaysMismatchTypeParameters() const { return false; }

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

Expand Down
2 changes: 1 addition & 1 deletion lib/AST/GenericSignatureBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4494,7 +4494,7 @@ bool GenericSignatureBuilder::updateSuperclass(

auto layout =
LayoutConstraint::getLayoutConstraint(
superclass->getClassOrBoundGenericClass()->isObjC()
superclass->getClassOrBoundGenericClass()->usesObjCObjectModel()
? LayoutConstraintKind::Class
: LayoutConstraintKind::NativeClass,
getASTContext());
Expand Down
43 changes: 31 additions & 12 deletions lib/AST/RequirementMachine/GenericSignatureQueries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ RequirementMachine::getLocalRequirements(
return result;

if (props->isConcreteType()) {
result.concreteType = props->getConcreteType({}, protos, Context);
result.concreteType = props->getConcreteType({}, term, protos, Context);
return result;
}

if (props->hasSuperclassBound()) {
result.superclass = props->getSuperclassBound({}, protos, Context);
result.superclass = props->getSuperclassBound({}, term, protos, Context);
}

for (const auto *proto : props->getConformsToExcludingSuperclassConformances())
Expand Down Expand Up @@ -153,7 +153,7 @@ Type RequirementMachine::getSuperclassBound(Type depType) const {
return Type();

auto &protos = System.getProtocols();
return props->getSuperclassBound({ }, protos, Context);
return props->getSuperclassBound({ }, term, protos, Context);
}

bool RequirementMachine::isConcreteType(Type depType) const {
Expand Down Expand Up @@ -183,7 +183,7 @@ Type RequirementMachine::getConcreteType(Type depType) const {
return Type();

auto &protos = System.getProtocols();
return props->getConcreteType({ }, protos, Context);
return props->getConcreteType({ }, term, protos, Context);
}

bool RequirementMachine::areSameTypeParameterInContext(Type depType1,
Expand Down Expand Up @@ -346,14 +346,33 @@ Type RequirementMachine::getCanonicalTypeInContext(
verify(prefix);

auto *props = Map.lookUpProperties(prefix);
if (props && props->isConcreteType()) {
auto concreteType = props->getConcreteType(genericParams,
protos, Context);
if (!concreteType->hasTypeParameter())
return concreteType;

// FIXME: Recursion guard is needed here
return getCanonicalTypeInContext(concreteType, genericParams);
if (props) {
if (props->isConcreteType()) {
auto concreteType = props->getConcreteType(genericParams,
prefix, protos,
Context);
if (!concreteType->hasTypeParameter())
return concreteType;

// FIXME: Recursion guard is needed here
return getCanonicalTypeInContext(concreteType, genericParams);
}

// Skip this part if the entire input term is valid, because in that
// case we don't want to replace the term with its superclass bound;
// unlike a fixed concrete type, the superclass bound only comes into
// play when looking up a member type.
if (props->hasSuperclassBound() &&
prefix.size() != term.size()) {
auto superclass = props->getSuperclassBound(genericParams,
prefix, protos,
Context);
if (!superclass->hasTypeParameter())
return superclass;

// FIXME: Recursion guard is needed here
return getCanonicalTypeInContext(superclass, genericParams);
}
}

return Context.getTypeForTerm(prefix, genericParams, protos);
Expand Down
Loading