Skip to content

Commit 568320c

Browse files
committed
GSB: Move guts of getCanonicalTypeInContext() from GenericSignature to the GSB
1 parent 4921e06 commit 568320c

File tree

4 files changed

+53
-44
lines changed

4 files changed

+53
-44
lines changed

include/swift/AST/GenericSignature.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,6 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
362362
/// Return the canonical version of the given type under this generic
363363
/// signature.
364364
CanType getCanonicalTypeInContext(Type type) const;
365-
CanType getCanonicalTypeInContext(Type type,
366-
GenericSignatureBuilder &builder) const;
367365

368366
bool isCanonicalTypeInContext(Type type) const;
369367
bool isCanonicalTypeInContext(Type type,

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,13 @@ class GenericSignatureBuilder {
794794
/// Simplify the given dependent type down to its canonical representation.
795795
Type getCanonicalTypeParameter(Type type);
796796

797+
/// Replace any non-canonical dependent types in the given type with their
798+
/// canonical representation. This is not a canonical type in the AST sense;
799+
/// type sugar is preserved. The GenericSignature::getCanonicalTypeInContext()
800+
/// method combines this with a subsequent getCanonicalType() call.
801+
Type getCanonicalTypeInContext(Type type,
802+
TypeArrayView<GenericTypeParamType> genericParams);
803+
797804
/// Verify the correctness of the given generic signature.
798805
///
799806
/// This routine will test that the given generic signature is both minimal

lib/AST/GenericSignature.cpp

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -557,47 +557,6 @@ bool GenericSignatureImpl::isCanonicalTypeInContext(
557557
});
558558
}
559559

560-
CanType GenericSignatureImpl::getCanonicalTypeInContext(
561-
Type type, GenericSignatureBuilder &builder) const {
562-
type = type->getCanonicalType();
563-
564-
// All the contextual canonicality rules apply to type parameters, so if the
565-
// type doesn't involve any type parameters, it's already canonical.
566-
if (!type->hasTypeParameter())
567-
return CanType(type);
568-
569-
// Replace non-canonical type parameters.
570-
type = type.transformRec([&](TypeBase *component) -> Optional<Type> {
571-
if (!isa<GenericTypeParamType>(component) &&
572-
!isa<DependentMemberType>(component))
573-
return None;
574-
575-
// Find the equivalence class for this dependent type.
576-
auto resolved = builder.maybeResolveEquivalenceClass(
577-
Type(component),
578-
ArchetypeResolutionKind::CompleteWellFormed,
579-
/*wantExactPotentialArchetype=*/false);
580-
if (!resolved) return None;
581-
582-
if (auto concrete = resolved.getAsConcreteType())
583-
return getCanonicalTypeInContext(concrete, builder);
584-
585-
auto equivClass = resolved.getEquivalenceClass(builder);
586-
if (!equivClass) return None;
587-
588-
if (equivClass->concreteType) {
589-
return getCanonicalTypeInContext(equivClass->concreteType, builder);
590-
}
591-
592-
return equivClass->getAnchor(builder, getGenericParams());
593-
});
594-
595-
auto result = type->getCanonicalType();
596-
597-
assert(isCanonicalTypeInContext(result, builder));
598-
return result;
599-
}
600-
601560
CanType GenericSignatureImpl::getCanonicalTypeInContext(Type type) const {
602561
type = type->getCanonicalType();
603562

@@ -607,7 +566,7 @@ CanType GenericSignatureImpl::getCanonicalTypeInContext(Type type) const {
607566
return CanType(type);
608567

609568
auto &builder = *getGenericSignatureBuilder();
610-
return getCanonicalTypeInContext(type, builder);
569+
return builder.getCanonicalTypeInContext(type, { })->getCanonicalType();
611570
}
612571

613572
ArrayRef<CanTypeWrapper<GenericTypeParamType>>

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4030,6 +4030,51 @@ bool GenericSignatureBuilder::areInSameEquivalenceClass(Type type1,
40304030
== resolveEquivalenceClass(type2, ArchetypeResolutionKind::WellFormed);
40314031
}
40324032

4033+
Type GenericSignatureBuilder::getCanonicalTypeInContext(Type type,
4034+
TypeArrayView<GenericTypeParamType> genericParams) {
4035+
// All the contextual canonicality rules apply to type parameters, so if the
4036+
// type doesn't involve any type parameters, it's already canonical.
4037+
if (!type->hasTypeParameter())
4038+
return type;
4039+
4040+
// Replace non-canonical type parameters.
4041+
return type.transformRec([&](TypeBase *component) -> Optional<Type> {
4042+
if (!isa<GenericTypeParamType>(component) &&
4043+
!isa<DependentMemberType>(component))
4044+
return None;
4045+
4046+
// Find the equivalence class for this dependent type.
4047+
auto resolved = maybeResolveEquivalenceClass(
4048+
Type(component),
4049+
ArchetypeResolutionKind::CompleteWellFormed,
4050+
/*wantExactPotentialArchetype=*/false);
4051+
if (!resolved) return None;
4052+
4053+
if (auto concrete = resolved.getAsConcreteType())
4054+
return getCanonicalTypeInContext(concrete, genericParams);
4055+
4056+
auto equivClass = resolved.getEquivalenceClass(*this);
4057+
if (!equivClass) return None;
4058+
4059+
// If there is a concrete type in this equivalence class, use that.
4060+
if (auto concrete = equivClass->concreteType) {
4061+
// .. unless it's recursive.
4062+
if (equivClass->recursiveConcreteType)
4063+
return ErrorType::get(Type(type));
4064+
4065+
// Prevent recursive substitution.
4066+
equivClass->recursiveConcreteType = true;
4067+
SWIFT_DEFER {
4068+
equivClass->recursiveConcreteType = false;
4069+
};
4070+
4071+
return getCanonicalTypeInContext(concrete, genericParams);
4072+
}
4073+
4074+
return equivClass->getAnchor(*this, genericParams);
4075+
});
4076+
}
4077+
40334078
TypeArrayView<GenericTypeParamType>
40344079
GenericSignatureBuilder::getGenericParams() const {
40354080
return TypeArrayView<GenericTypeParamType>(Impl->GenericParams);

0 commit comments

Comments
 (0)