Skip to content

Commit fab5b7d

Browse files
committed
[RequirementMachine] Add a generic signature query that returns the
reduced shape of a given type parameter pack.
1 parent 228f7f4 commit fab5b7d

File tree

4 files changed

+35
-0
lines changed

4 files changed

+35
-0
lines changed

include/swift/AST/GenericSignature.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,13 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
419419
/// Lookup a nested type with the given name within this type parameter.
420420
TypeDecl *lookupNestedType(Type type, Identifier name) const;
421421

422+
/// Returns the shape equivalence class of the given type parameter.
423+
///
424+
/// \param type The type parameter to compute the reduced shape for.
425+
/// Only type parameter packs have a shape, including dependent members
426+
/// whose root generic parameter is a pack.
427+
Type getReducedShape(Type type) const;
428+
422429
/// Get the ordinal of a generic parameter in this generic signature.
423430
///
424431
/// For example, if you have a generic signature for a nested context like:

lib/AST/GenericSignature.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,11 @@ GenericSignatureImpl::lookupNestedType(Type type, Identifier name) const {
534534
return getRequirementMachine()->lookupNestedType(type, name);
535535
}
536536

537+
Type
538+
GenericSignatureImpl::getReducedShape(Type type) const {
539+
return getRequirementMachine()->getReducedShape(type);
540+
}
541+
537542
unsigned GenericParamKey::findIndexIn(
538543
TypeArrayView<GenericTypeParamType> genericParams) const {
539544
// For depth 0, we have random access. We perform the extra checking so that

lib/AST/RequirementMachine/GenericSignatureQueries.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,27 @@ RequirementMachine::lookupNestedType(Type depType, Identifier name) const {
696696
return nullptr;
697697
}
698698

699+
Type RequirementMachine::getReducedShape(Type type) const {
700+
if (!type->isTypeSequenceParameter())
701+
return Type();
702+
703+
auto rootType = type->getRootGenericParam();
704+
auto term = Context.getMutableTermForType(rootType->getCanonicalType(),
705+
/*proto=*/nullptr);
706+
707+
// Append the 'shape' symbol to the term.
708+
term.add(Symbol::forShape(Context));
709+
710+
System.simplify(term);
711+
verify(term);
712+
713+
// Remove the 'shape' symbol from the term.
714+
assert(term.back().getKind() == Symbol::Kind::Shape);
715+
MutableTerm reducedTerm(term.begin(), term.end() - 1);
716+
717+
return Map.getTypeForTerm(reducedTerm, getGenericParams());
718+
}
719+
699720
void RequirementMachine::verify(const MutableTerm &term) const {
700721
#ifndef NDEBUG
701722
// If the term is in the generic parameter domain, ensure we have a valid

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ class RequirementMachine final {
160160
ConformancePath getConformancePath(Type type, ProtocolDecl *protocol);
161161
TypeDecl *lookupNestedType(Type depType, Identifier name) const;
162162

163+
Type getReducedShape(Type type) const;
164+
163165
llvm::DenseMap<const ProtocolDecl *, RequirementSignature>
164166
computeMinimalProtocolRequirements();
165167

0 commit comments

Comments
 (0)