Skip to content

Commit 54f42b5

Browse files
authored
Merge pull request #61445 from hborla/pack-shape-requirements
[RequirementMachine] Implement inference and minimization of same-shape requirements.
2 parents f66d5cd + be619c6 commit 54f42b5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+440
-150
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,6 +2545,10 @@ ERROR(requires_not_suitable_archetype,none,
25452545
"generic parameter or associated type",
25462546
(Type))
25472547

2548+
ERROR(invalid_shape_requirement,none,
2549+
"invalid same-shape requirement between %0 and %1",
2550+
(Type, Type))
2551+
25482552
ERROR(requires_generic_params_made_equal,none,
25492553
"same-type requirement makes generic parameters %0 and %1 equivalent",
25502554
(Type, Type))

include/swift/AST/GenericSignature.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,17 @@ 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+
429+
/// Returns \c true if the given type parameter packs are in
430+
/// the same shape equivalence class.
431+
bool haveSameShape(Type type1, Type type2) const;
432+
422433
/// Get the ordinal of a generic parameter in this generic signature.
423434
///
424435
/// For example, if you have a generic signature for a nested context like:

include/swift/AST/Requirement.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class Requirement
5858
Requirement subst(Args &&...args) const {
5959
auto newFirst = getFirstType().subst(std::forward<Args>(args)...);
6060
switch (getKind()) {
61-
case RequirementKind::SameCount:
61+
case RequirementKind::SameShape:
6262
case RequirementKind::Conformance:
6363
case RequirementKind::Superclass:
6464
case RequirementKind::SameType: {

include/swift/AST/RequirementBase.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ enum class RequirementKind : unsigned {
3636
/// A layout bound T : L, where T is a type that depends on a generic
3737
/// parameter and L is some layout specification that should bound T.
3838
Layout,
39-
/// A same-count requirement T.count == U.count, where T and U are pack
39+
/// A same-shape requirement shape(T) == shape(U), where T and U are pack
4040
/// parameters.
41-
SameCount
41+
SameShape
4242

4343
// Note: there is code that packs this enum in a 3-bit bitfield. Audit users
4444
// when adding enumerators.
@@ -105,7 +105,7 @@ class RequirementBase {
105105
hash_value(requirement.FirstTypeAndKind.getOpaqueValue());
106106
llvm::hash_code second;
107107
switch (requirement.getKind()) {
108-
case RequirementKind::SameCount:
108+
case RequirementKind::SameShape:
109109
case RequirementKind::Conformance:
110110
case RequirementKind::Superclass:
111111
case RequirementKind::SameType:
@@ -127,7 +127,7 @@ class RequirementBase {
127127
return false;
128128

129129
switch (lhs.getKind()) {
130-
case RequirementKind::SameCount:
130+
case RequirementKind::SameShape:
131131
case RequirementKind::Conformance:
132132
case RequirementKind::Superclass:
133133
case RequirementKind::SameType:

include/swift/SIL/SILWitnessVisitor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ template <class T> class SILWitnessVisitor : public ASTVisitor<T> {
5757
auto requirements = protocol->getRequirementSignature().getRequirements();
5858
for (const auto &reqt : requirements) {
5959
switch (reqt.getKind()) {
60-
case RequirementKind::SameCount:
61-
llvm_unreachable("Same-count requirement not supported here");
60+
case RequirementKind::SameShape:
61+
llvm_unreachable("Same-shape requirement not supported here");
6262

6363
// These requirements don't show up in the witness table.
6464
case RequirementKind::Superclass:

lib/AST/ASTContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5584,8 +5584,8 @@ ASTContext::getOpenedElementSignature(CanGenericSignature baseGenericSig) {
55845584

55855585
for (auto requirement : baseGenericSig.getRequirements()) {
55865586
switch (requirement.getKind()) {
5587-
case RequirementKind::SameCount:
5588-
// Drop same-length requirements from the element signature.
5587+
case RequirementKind::SameShape:
5588+
// Drop same-shape requirements from the element signature.
55895589
break;
55905590
case RequirementKind::Conformance:
55915591
case RequirementKind::Superclass:

lib/AST/ASTDemangler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,8 @@ Type ASTBuilder::createConstrainedExistentialType(
635635
llvm::SmallDenseMap<Identifier, Type> cmap;
636636
for (const auto &req : constraints) {
637637
switch (req.getKind()) {
638-
case RequirementKind::SameCount:
639-
llvm_unreachable("Same-count requirement not supported here");
638+
case RequirementKind::SameShape:
639+
llvm_unreachable("Same-shape requirement not supported here");
640640
case RequirementKind::Conformance:
641641
case RequirementKind::Superclass:
642642
case RequirementKind::Layout:

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4277,8 +4277,8 @@ void Requirement::dump() const {
42774277
}
42784278
void Requirement::dump(raw_ostream &out) const {
42794279
switch (getKind()) {
4280-
case RequirementKind::SameCount:
4281-
out << "same_count: ";
4280+
case RequirementKind::SameShape:
4281+
out << "same_shape: ";
42824282
break;
42834283
case RequirementKind::Conformance:
42844284
out << "conforms_to: ";

lib/AST/ASTMangler.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2868,8 +2868,8 @@ void ASTMangler::appendRequirement(const Requirement &reqt,
28682868
Type FirstTy = reqt.getFirstType()->getCanonicalType();
28692869

28702870
switch (reqt.getKind()) {
2871-
case RequirementKind::SameCount:
2872-
llvm_unreachable("Same-count requirement not supported here");
2871+
case RequirementKind::SameShape:
2872+
llvm_unreachable("Same-shape requirement not supported here");
28732873
case RequirementKind::Layout:
28742874
break;
28752875
case RequirementKind::Conformance: {
@@ -2891,8 +2891,8 @@ void ASTMangler::appendRequirement(const Requirement &reqt,
28912891
if (auto *DT = FirstTy->getAs<DependentMemberType>()) {
28922892
if (tryMangleTypeSubstitution(DT, sig)) {
28932893
switch (reqt.getKind()) {
2894-
case RequirementKind::SameCount:
2895-
llvm_unreachable("Same-count requirement not supported here");
2894+
case RequirementKind::SameShape:
2895+
llvm_unreachable("Same-shape requirement not supported here");
28962896
case RequirementKind::Conformance:
28972897
return appendOperator("RQ");
28982898
case RequirementKind::Layout:
@@ -2912,8 +2912,8 @@ void ASTMangler::appendRequirement(const Requirement &reqt,
29122912
addTypeSubstitution(DT, sig);
29132913
assert(gpBase);
29142914
switch (reqt.getKind()) {
2915-
case RequirementKind::SameCount:
2916-
llvm_unreachable("Same-count requirement not supported here");
2915+
case RequirementKind::SameShape:
2916+
llvm_unreachable("Same-shape requirement not supported here");
29172917
case RequirementKind::Conformance:
29182918
return appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RP" : "Rp",
29192919
gpBase, lhsBaseIsProtocolSelf);
@@ -2933,8 +2933,8 @@ void ASTMangler::appendRequirement(const Requirement &reqt,
29332933
}
29342934
GenericTypeParamType *gpBase = FirstTy->castTo<GenericTypeParamType>();
29352935
switch (reqt.getKind()) {
2936-
case RequirementKind::SameCount:
2937-
llvm_unreachable("Same-count requirement not supported here");
2936+
case RequirementKind::SameShape:
2937+
llvm_unreachable("Same-shape requirement not supported here");
29382938
case RequirementKind::Conformance:
29392939
return appendOpWithGenericParamIndex("R", gpBase);
29402940
case RequirementKind::Layout:
@@ -3494,8 +3494,8 @@ void ASTMangler::appendConcreteProtocolConformance(
34943494
bool firstRequirement = true;
34953495
for (const auto &conditionalReq : conformance->getConditionalRequirements()) {
34963496
switch (conditionalReq.getKind()) {
3497-
case RequirementKind::SameCount:
3498-
llvm_unreachable("Same-count requirement not supported here");
3497+
case RequirementKind::SameShape:
3498+
llvm_unreachable("Same-shape requirement not supported here");
34993499
case RequirementKind::Layout:
35003500
case RequirementKind::SameType:
35013501
case RequirementKind::Superclass:
@@ -3645,8 +3645,8 @@ void ASTMangler::appendConstrainedExistential(Type base, GenericSignature sig,
36453645
bool firstRequirement = true;
36463646
for (const auto &reqt : requirements) {
36473647
switch (reqt.getKind()) {
3648-
case RequirementKind::SameCount:
3649-
llvm_unreachable("Same-count requirement not supported here");
3648+
case RequirementKind::SameShape:
3649+
llvm_unreachable("Same-shape requirement not supported here");
36503650
case RequirementKind::Layout:
36513651
case RequirementKind::Conformance:
36523652
case RequirementKind::Superclass:

lib/AST/ASTPrinter.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
240240
if (!isPublicOrUsableFromInline(req.getSecondType()))
241241
return false;
242242
break;
243-
case RequirementKind::SameCount:
243+
case RequirementKind::SameShape:
244244
case RequirementKind::Layout:
245245
break;
246246
}
@@ -1415,8 +1415,8 @@ bestRequirementPrintLocation(ProtocolDecl *proto, const Requirement &req) {
14151415
bool inWhereClause;
14161416

14171417
switch (req.getKind()) {
1418-
case RequirementKind::SameCount:
1419-
llvm_unreachable("Same-count requirements not supported here");
1418+
case RequirementKind::SameShape:
1419+
llvm_unreachable("Same-shape requirements not supported here");
14201420
case RequirementKind::Layout:
14211421
case RequirementKind::Conformance:
14221422
case RequirementKind::Superclass: {
@@ -1510,7 +1510,7 @@ static unsigned getDepthOfRequirement(const Requirement &req) {
15101510

15111511
case RequirementKind::Superclass:
15121512
case RequirementKind::SameType:
1513-
case RequirementKind::SameCount: {
1513+
case RequirementKind::SameShape: {
15141514
// Return the max valid depth of firstType and secondType.
15151515
unsigned firstDepth = getDepthOfType(req.getFirstType());
15161516
unsigned secondDepth = getDepthOfType(req.getSecondType());
@@ -1757,8 +1757,8 @@ void PrintAST::printSingleDepthOfGenericSignature(
17571757
// We only print the second part of a requirement in the "inherited"
17581758
// clause.
17591759
switch (req.getKind()) {
1760-
case RequirementKind::SameCount:
1761-
llvm_unreachable("Same-count requirement not supported here");
1760+
case RequirementKind::SameShape:
1761+
llvm_unreachable("Same-shape requirement not supported here");
17621762

17631763
case RequirementKind::Layout:
17641764
req.getLayoutConstraint()->print(Printer, Options);
@@ -1788,10 +1788,10 @@ void PrintAST::printSingleDepthOfGenericSignature(
17881788
void PrintAST::printRequirement(const Requirement &req) {
17891789
printTransformedType(req.getFirstType());
17901790
switch (req.getKind()) {
1791-
case RequirementKind::SameCount:
1792-
Printer << ".count == ";
1791+
case RequirementKind::SameShape:
1792+
Printer << ".shape == ";
17931793
printTransformedType(req.getSecondType());
1794-
Printer << ".count";
1794+
Printer << ".shape";
17951795
return;
17961796
case RequirementKind::Layout:
17971797
Printer << " : ";

lib/AST/Decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4067,8 +4067,8 @@ findGenericParameterReferences(CanGenericSignature genericSig,
40674067
auto opaqueSig = opaque->getDecl()->getOpaqueInterfaceGenericSignature();
40684068
for (const auto &req : opaqueSig.getRequirements()) {
40694069
switch (req.getKind()) {
4070-
case RequirementKind::SameCount:
4071-
llvm_unreachable("Same-count requirement not supported here");
4070+
case RequirementKind::SameShape:
4071+
llvm_unreachable("Same-shape requirement not supported here");
40724072

40734073
case RequirementKind::Conformance:
40744074
case RequirementKind::Layout:

lib/AST/GenericSignature.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void GenericSignatureImpl::forEachParam(
131131
case RequirementKind::Superclass:
132132
case RequirementKind::Conformance:
133133
case RequirementKind::Layout:
134-
case RequirementKind::SameCount:
134+
case RequirementKind::SameShape:
135135
continue;
136136
}
137137

@@ -160,7 +160,7 @@ bool GenericSignatureImpl::areAllParamsConcrete() const {
160160
case RequirementKind::Conformance:
161161
case RequirementKind::Superclass:
162162
case RequirementKind::Layout:
163-
case RequirementKind::SameCount:
163+
case RequirementKind::SameShape:
164164
continue;
165165
}
166166
}
@@ -534,6 +534,16 @@ 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+
542+
bool
543+
GenericSignatureImpl::haveSameShape(Type type1, Type type2) const {
544+
return getRequirementMachine()->haveSameShape(type1, type2);
545+
}
546+
537547
unsigned GenericParamKey::findIndexIn(
538548
TypeArrayView<GenericTypeParamType> genericParams) const {
539549
// For depth 0, we have random access. We perform the extra checking so that
@@ -649,7 +659,7 @@ bool Requirement::isCanonical() const {
649659
return false;
650660

651661
switch (getKind()) {
652-
case RequirementKind::SameCount:
662+
case RequirementKind::SameShape:
653663
case RequirementKind::Conformance:
654664
case RequirementKind::SameType:
655665
case RequirementKind::Superclass:
@@ -669,7 +679,7 @@ Requirement Requirement::getCanonical() const {
669679
Type firstType = getFirstType()->getCanonicalType();
670680

671681
switch (getKind()) {
672-
case RequirementKind::SameCount:
682+
case RequirementKind::SameShape:
673683
case RequirementKind::Conformance:
674684
case RequirementKind::SameType:
675685
case RequirementKind::Superclass: {
@@ -692,8 +702,8 @@ bool
692702
Requirement::isSatisfied(ArrayRef<Requirement> &conditionalRequirements,
693703
bool allowMissing) const {
694704
switch (getKind()) {
695-
case RequirementKind::SameCount:
696-
llvm_unreachable("Same-count requirements not supported here");
705+
case RequirementKind::SameShape:
706+
llvm_unreachable("Same-shape requirements not supported here");
697707

698708
case RequirementKind::Conformance: {
699709
auto *proto = getProtocolDecl();
@@ -733,8 +743,8 @@ Requirement::isSatisfied(ArrayRef<Requirement> &conditionalRequirements,
733743

734744
bool Requirement::canBeSatisfied() const {
735745
switch (getKind()) {
736-
case RequirementKind::SameCount:
737-
llvm_unreachable("Same-count requirements not supported here");
746+
case RequirementKind::SameShape:
747+
llvm_unreachable("Same-shape requirements not supported here");
738748

739749
case RequirementKind::Conformance:
740750
return getFirstType()->is<ArchetypeType>();
@@ -763,7 +773,7 @@ bool Requirement::canBeSatisfied() const {
763773
/// Determine the canonical ordering of requirements.
764774
static unsigned getRequirementKindOrder(RequirementKind kind) {
765775
switch (kind) {
766-
case RequirementKind::SameCount: return 4;
776+
case RequirementKind::SameShape: return 4;
767777
case RequirementKind::Conformance: return 2;
768778
case RequirementKind::Superclass: return 0;
769779
case RequirementKind::SameType: return 3;
@@ -911,7 +921,7 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
911921

912922
// Check canonicalization of requirement itself.
913923
switch (reqt.getKind()) {
914-
case RequirementKind::SameCount:
924+
case RequirementKind::SameShape:
915925
if (!reqt.getFirstType()->is<GenericTypeParamType>()) {
916926
llvm::errs() << "Left hand side is not a generic parameter: ";
917927
reqt.dump(llvm::errs());
@@ -1109,8 +1119,8 @@ static Requirement stripBoundDependentMemberTypes(Requirement req) {
11091119
auto subjectType = stripBoundDependentMemberTypes(req.getFirstType());
11101120

11111121
switch (req.getKind()) {
1112-
case RequirementKind::SameCount:
1113-
// Same-count requirements do not involve dependent member types.
1122+
case RequirementKind::SameShape:
1123+
// Same-shape requirements do not involve dependent member types.
11141124
return req;
11151125

11161126
case RequirementKind::Conformance:

lib/AST/RequirementMachine/ConcreteContraction.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,8 @@ ConcreteContraction::substRequirement(const Requirement &req) const {
371371
auto firstType = req.getFirstType();
372372

373373
switch (req.getKind()) {
374-
case RequirementKind::SameCount:
375-
llvm_unreachable("Same-count requirement not supported here");
374+
case RequirementKind::SameShape:
375+
llvm_unreachable("Same-shape requirement not supported here");
376376

377377
case RequirementKind::Superclass:
378378
case RequirementKind::SameType: {
@@ -553,8 +553,9 @@ bool ConcreteContraction::performConcreteContraction(
553553

554554
auto kind = req.req.getKind();
555555
switch (kind) {
556-
case RequirementKind::SameCount:
557-
llvm_unreachable("Same-count requirement not supported here");
556+
case RequirementKind::SameShape:
557+
assert(req.req.getSecondType()->isTypeParameter());
558+
continue;
558559

559560
case RequirementKind::SameType: {
560561
auto constraintType = req.req.getSecondType();

0 commit comments

Comments
 (0)