Eliminate use of the opaque type's generic environment from type matching.

Introduce a new primitive operation on opaque type archetypes that
canonicalizes a type within the environment of the opaque type
archetype without building the environment itself. Use it when matching
opaque archetype types in the solver.
This commit is contained in:
Doug Gregor
2022-01-05 09:55:01 -08:00
parent 52194b2c64
commit d49a20e9dd
3 changed files with 70 additions and 13 deletions

View File

@@ -2851,12 +2851,10 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,
auto arch2 = type2->castTo<ArchetypeType>();
auto opaque1 = cast<OpaqueTypeArchetypeType>(arch1->getRoot());
auto opaque2 = cast<OpaqueTypeArchetypeType>(arch2->getRoot());
assert(arch1->getInterfaceType()->getCanonicalType(
opaque1->getGenericEnvironment()->getGenericSignature())
== arch2->getInterfaceType()->getCanonicalType(
opaque2->getGenericEnvironment()->getGenericSignature()));
assert(opaque1->getDecl() == opaque2->getDecl());
assert(opaque1->getCanonicalInterfaceType(arch1->getInterfaceType())->isEqual(
opaque2->getCanonicalInterfaceType(arch2->getInterfaceType())));
auto args1 = opaque1->getSubstitutions().getReplacementTypes();
auto args2 = opaque2->getSubstitutions().getReplacementTypes();
@@ -5896,13 +5894,11 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
auto rootOpaque1 = dyn_cast<OpaqueTypeArchetypeType>(nested1->getRoot());
auto rootOpaque2 = dyn_cast<OpaqueTypeArchetypeType>(nested2->getRoot());
if (rootOpaque1 && rootOpaque2) {
auto interfaceTy1 = nested1->getInterfaceType()
->getCanonicalType(rootOpaque1->getGenericEnvironment()
->getGenericSignature());
auto interfaceTy2 = nested2->getInterfaceType()
->getCanonicalType(rootOpaque2->getGenericEnvironment()
->getGenericSignature());
if (interfaceTy1 == interfaceTy2
auto interfaceTy1 = rootOpaque1->getCanonicalInterfaceType(
nested1->getInterfaceType());
auto interfaceTy2 = rootOpaque2->getCanonicalInterfaceType(
nested2->getInterfaceType());
if (interfaceTy1->isEqual(interfaceTy2)
&& rootOpaque1->getDecl() == rootOpaque2->getDecl()) {
conversionsOrFixes.push_back(ConversionRestrictionKind::DeepEquality);
break;