Skip to content

Commit 22cce0e

Browse files
authored
Merge pull request #74390 from kavon/6.0-rdar125659789
[6.0🍒] AST: fix `isWrittenWithConstraints`
2 parents 31dd4e5 + d446e06 commit 22cce0e

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

lib/AST/Decl.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,18 +1809,25 @@ bool ExtensionDecl::isWrittenWithConstraints() const {
18091809
typeSig->getRequirementsWithInverses(typeReqs, typeInverseReqs);
18101810

18111811
// If the (non-inverse) requirements are different between the extension and
1812-
// the original type, it's written with constraints. Note that
1813-
// the extension can only add requirements, so we need only check the size
1814-
// (not the specific requirements).
1815-
if (extReqs.size() > typeReqs.size()) {
1812+
// the original type, it's written with constraints.
1813+
if (extReqs.size() != typeReqs.size()) {
18161814
return true;
18171815
}
18181816

1819-
assert(extReqs.size() == typeReqs.size());
1817+
// In case of equal number of constraints, we have to check the specific
1818+
// requirements. Extensions can end up with fewer requirements than the type
1819+
// extended, due to a same-type requirement in the extension.
1820+
//
1821+
// This mirrors the 'same' check in `ASTMangler::gatherGenericSignatureParts`
1822+
for (size_t i = 0; i < extReqs.size(); i++) {
1823+
if (extReqs[i] != typeReqs[i])
1824+
return true;
1825+
}
18201826

18211827
// If the type has no inverse requirements, there are no extra constraints
18221828
// to write.
18231829
if (typeInverseReqs.empty()) {
1830+
assert(extInverseReqs.empty() && "extension retroactively added inverse?");
18241831
return false;
18251832
}
18261833

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend -emit-ir -g %s > /dev/null
2+
3+
// https://github.com/apple/swift/issues/72719
4+
5+
protocol D {}
6+
struct U: D, Equatable {}
7+
class Q<T> {}
8+
class R<V, E: D & Equatable> {}
9+
extension R where E == U {
10+
struct S<X> {}
11+
static func a<T>(_: T) -> R {
12+
let x = Q<S<T>>()
13+
fatalError()
14+
}
15+
}

0 commit comments

Comments
 (0)