Skip to content

Commit 8582828

Browse files
authored
Merge pull request #74445 from slavapestov/fix-failure-type-witness
Concurrency: Fix default type witness for AsyncSequence.Failure
2 parents 03b0f0c + 61d00ca commit 8582828

File tree

2 files changed

+26
-29
lines changed

2 files changed

+26
-29
lines changed

lib/AST/Decl.cpp

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,8 @@ bool ExtensionDecl::hasValidParent() const {
17681768
return getDeclContext()->canBeParentOfExtension();
17691769
}
17701770

1771+
/// Does the extension's generic signature impose additional generic requirements
1772+
/// not stated on the extended nominal type itself?
17711773
bool ExtensionDecl::isConstrainedExtension() const {
17721774
auto nominal = getExtendedNominal();
17731775
if (!nominal)
@@ -1786,12 +1788,26 @@ bool ExtensionDecl::isConstrainedExtension() const {
17861788
return !typeSig->isEqual(extSig);
17871789
}
17881790

1791+
/// Is the extension written as an unconstrained extension? This is not the same
1792+
/// as isConstrainedExtension() in the case where the extended nominal type has
1793+
/// inverse requirements, because an extension of such a type introduces default
1794+
/// conformance requirements unless they're suppressed on the extension.
1795+
///
1796+
/// enum Optional<Wrapped> where Wrapped: ~Copyable {}
1797+
///
1798+
/// extension Optional {}
1799+
/// --> isConstrainedExtension(): true
1800+
/// --> isWrittenWithConstraints(): false
1801+
///
1802+
/// extension Optional where Wrapped: ~Copyable {}
1803+
/// --> isConstrainedExtension(): false
1804+
/// --> isWrittenWithConstraints(): true
17891805
bool ExtensionDecl::isWrittenWithConstraints() const {
17901806
auto nominal = getExtendedNominal();
17911807
if (!nominal)
17921808
return false;
17931809

1794-
// If there's no generic signature, then it's written without constraints.
1810+
// If there's no generic signature, then it's unconstrained.
17951811
CanGenericSignature extSig = getGenericSignature().getCanonicalSignature();
17961812
if (!extSig)
17971813
return false;
@@ -1808,37 +1824,18 @@ bool ExtensionDecl::isWrittenWithConstraints() const {
18081824
SmallVector<InverseRequirement, 2> typeInverseReqs;
18091825
typeSig->getRequirementsWithInverses(typeReqs, typeInverseReqs);
18101826

1811-
// If the (non-inverse) requirements are different between the extension and
1827+
// If the non-inverse requirements are different between the extension and
18121828
// the original type, it's written with constraints.
1813-
if (extReqs.size() != typeReqs.size()) {
1829+
if (extReqs != typeReqs)
18141830
return true;
1815-
}
1816-
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-
}
18261831

1827-
// If the type has no inverse requirements, there are no extra constraints
1828-
// to write.
1829-
if (typeInverseReqs.empty()) {
1830-
assert(extInverseReqs.empty() && "extension retroactively added inverse?");
1831-
return false;
1832-
}
1833-
1834-
// If the extension has no inverse requirements, then there are no constraints
1835-
// that need to be written down.
1836-
if (extInverseReqs.empty()) {
1837-
return false;
1838-
}
1832+
// If the extension has inverse requirements, then it's written with
1833+
// constraints.
1834+
if (!extInverseReqs.empty())
1835+
return true;
18391836

1840-
// We have inverses that need to be written out.
1841-
return true;
1837+
// Otherwise, the extension is written as an unconstrained extension.
1838+
return false;
18421839
}
18431840

18441841
bool ExtensionDecl::isInSameDefiningModule() const {

stdlib/public/Concurrency/AsyncSequence.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public protocol AsyncSequence<Element, Failure> {
8181

8282
/// The type of errors produced when iteration over the sequence fails.
8383
@available(SwiftStdlib 6.0, *)
84-
associatedtype Failure: Error = AsyncIterator.Failure
84+
associatedtype Failure: Error = any Error
8585
where AsyncIterator.Failure == Failure
8686

8787
/// Creates the asynchronous iterator that produces elements of this

0 commit comments

Comments
 (0)