Skip to content

GSB: Introduce a list of explicit as-written requirements #36577

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
merged 9 commits into from
Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions include/swift/AST/GenericSignature.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,6 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
/// Return the canonical version of the given type under this generic
/// signature.
CanType getCanonicalTypeInContext(Type type) const;
CanType getCanonicalTypeInContext(Type type,
GenericSignatureBuilder &builder) const;

bool isCanonicalTypeInContext(Type type) const;
bool isCanonicalTypeInContext(Type type,
Expand Down
8 changes: 8 additions & 0 deletions include/swift/AST/GenericSignatureBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ class GenericSignatureBuilder {
struct CachedNestedType {
unsigned numConformancesPresent;
CanType superclassPresent;
CanType concreteTypePresent;
llvm::TinyPtrVector<TypeDecl *> types;
};

Expand Down Expand Up @@ -793,6 +794,13 @@ class GenericSignatureBuilder {
/// Simplify the given dependent type down to its canonical representation.
Type getCanonicalTypeParameter(Type type);

/// Replace any non-canonical dependent types in the given type with their
/// canonical representation. This is not a canonical type in the AST sense;
/// type sugar is preserved. The GenericSignature::getCanonicalTypeInContext()
/// method combines this with a subsequent getCanonicalType() call.
Type getCanonicalTypeInContext(Type type,
TypeArrayView<GenericTypeParamType> genericParams);

/// Verify the correctness of the given generic signature.
///
/// This routine will test that the given generic signature is both minimal
Expand Down
43 changes: 1 addition & 42 deletions lib/AST/GenericSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,47 +557,6 @@ bool GenericSignatureImpl::isCanonicalTypeInContext(
});
}

CanType GenericSignatureImpl::getCanonicalTypeInContext(
Type type, GenericSignatureBuilder &builder) const {
type = type->getCanonicalType();

// All the contextual canonicality rules apply to type parameters, so if the
// type doesn't involve any type parameters, it's already canonical.
if (!type->hasTypeParameter())
return CanType(type);

// Replace non-canonical type parameters.
type = type.transformRec([&](TypeBase *component) -> Optional<Type> {
if (!isa<GenericTypeParamType>(component) &&
!isa<DependentMemberType>(component))
return None;

// Find the equivalence class for this dependent type.
auto resolved = builder.maybeResolveEquivalenceClass(
Type(component),
ArchetypeResolutionKind::CompleteWellFormed,
/*wantExactPotentialArchetype=*/false);
if (!resolved) return None;

if (auto concrete = resolved.getAsConcreteType())
return getCanonicalTypeInContext(concrete, builder);

auto equivClass = resolved.getEquivalenceClass(builder);
if (!equivClass) return None;

if (equivClass->concreteType) {
return getCanonicalTypeInContext(equivClass->concreteType, builder);
}

return equivClass->getAnchor(builder, getGenericParams());
});

auto result = type->getCanonicalType();

assert(isCanonicalTypeInContext(result, builder));
return result;
}

CanType GenericSignatureImpl::getCanonicalTypeInContext(Type type) const {
type = type->getCanonicalType();

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

auto &builder = *getGenericSignatureBuilder();
return getCanonicalTypeInContext(type, builder);
return builder.getCanonicalTypeInContext(type, { })->getCanonicalType();
}

ArrayRef<CanTypeWrapper<GenericTypeParamType>>
Expand Down
Loading