Requirement Machine: Fix an issue with pack expansion + tuple type crashes

Support pack expansion types in term rewriting, maintaining shape invariants and not
throwing assertions unnecessarily.

Additional tests added for an inifinite case and a concrete case.
This commit is contained in:
Kathy Gray
2025-10-29 11:34:06 +00:00
parent fcb7d76e74
commit d68a7a7ef0
7 changed files with 36 additions and 16 deletions

View File

@@ -424,7 +424,12 @@ RewriteContext::getRelativeTermForType(CanType typeWitness,
// Get the substitution S corresponding to τ_0_n.
unsigned index = getGenericParamIndex(typeWitness->getRootGenericParam());
result = MutableTerm(substitutions[index]);
ASSERT(!result.hasShape());
bool hasShape = false;
if (result.hasShape()) {
hasShape = true;
result.removeShape();
}
// If the substitution is a term consisting of a single protocol symbol
// [P], save P for later.
@@ -463,6 +468,9 @@ RewriteContext::getRelativeTermForType(CanType typeWitness,
for (auto iter = symbols.rbegin(), end = symbols.rend(); iter != end; ++iter)
result.add(*iter);
if (hasShape)
result.add(Symbol::forShape(*this));
return result;
}
@@ -571,8 +579,6 @@ RewriteContext::getRelativeSubstitutionSchemaFromType(
//
// τ_0_0 := T
// τ_0_1 := U.[shape]
ASSERT(pos != TypePosition::Shape && "Not implemented");
unsigned index = result.size();
result.push_back(Term::get(term, *this));

View File

@@ -55,4 +55,14 @@ protocol TooManyDifferences {
associatedtype A2
associatedtype B
associatedtype C
}
}
struct G2<T> {
func f2<each A>()
// expected-error@-1 {{cannot build rewrite system for generic signature; concrete type nesting limit exceeded}}
// expected-note@-2 {{failed rewrite rule is }}
// expected-error@-3 {{generic parameter 'A' is not used in function signature}}
where (repeat each A, T) == T {}
// expected-error@-1 {{tuple with noncopyable element type 'repeat each A' is not supported}}
}

View File

@@ -126,3 +126,9 @@ func sameTypeMatch1<T: PP, each U: PP, each V: PP>(t: T, u: repeat each U, v: re
// CHECK-NEXT: <T, each U, each V where T : PP, repeat each U : PP, (repeat (each U, each V)) : Any, repeat each V : PP, T.[PP]A == (/* shape: each U */ repeat ())>
func sameTypeMatch2<T: PP, each U: PP, each V: PP>(t: T, u: repeat each U, v: repeat each V)
where T.A == Shape<repeat each U>, T.A == Shape<repeat each V> {}
// CHECK-LABEL: PackTupleNesting
// CHECK-NEXT: <T, U, V, each W where T == ((repeat each W), (repeat each W)), U == (repeat each W), V == (repeat each W)>
struct PackTupleNesting<T, U, V, each W>
where T == ((repeat each W), U),
T == (V, (repeat each W)) {} // expected-warning 3{{same-type requirement makes generic parameter}}

View File

@@ -1,5 +0,0 @@
// {"kind":"typecheck","signature":"swift::rewriting::RewriteContext::getRelativeTermForType(swift::CanType, llvm::ArrayRef<swift::rewriting::Term>)","signatureAssert":"Assertion failed: (result.back().getKind() != Symbol::Kind::Shape), function getRelativeTermForType"}
// RUN: not --crash %target-swift-frontend -typecheck %s
extension Result {
func a<each b>() where Success == (Result) -> (repeat each b)> {}
}

View File

@@ -1,7 +0,0 @@
// {"issueID":84490,"kind":"typecheck","signature":"swift::rewriting::RewriteContext::getRelativeTermForType(swift::CanType, llvm::ArrayRef<swift::rewriting::Term>)","signatureAssert":"Assertion failed: (result.back().getKind() != Symbol::Kind::Shape), function getRelativeTermForType"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// https://github.com/swiftlang/swift/issues/84490
struct a < b > {
func
c < each d where (repeat each d , b) == b>()
}

View File

@@ -0,0 +1,4 @@
// RUN: not %target-swift-frontend -typecheck %s
extension Result {
func a<each b>() where Success == (Result) -> (repeat each b)> {}
}

View File

@@ -0,0 +1,6 @@
// RUN: not %target-swift-frontend -typecheck %s
// https://github.com/swiftlang/swift/issues/84490
struct a < b > {
func
c < each d where (repeat each d , b) == b>()
}