@@ -1768,6 +1768,8 @@ bool ExtensionDecl::hasValidParent() const {
1768
1768
return getDeclContext ()->canBeParentOfExtension ();
1769
1769
}
1770
1770
1771
+ // / Does the extension's generic signature impose additional generic requirements
1772
+ // / not stated on the extended nominal type itself?
1771
1773
bool ExtensionDecl::isConstrainedExtension () const {
1772
1774
auto nominal = getExtendedNominal ();
1773
1775
if (!nominal)
@@ -1786,12 +1788,26 @@ bool ExtensionDecl::isConstrainedExtension() const {
1786
1788
return !typeSig->isEqual (extSig);
1787
1789
}
1788
1790
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
1789
1805
bool ExtensionDecl::isWrittenWithConstraints () const {
1790
1806
auto nominal = getExtendedNominal ();
1791
1807
if (!nominal)
1792
1808
return false ;
1793
1809
1794
- // If there's no generic signature, then it's written without constraints .
1810
+ // If there's no generic signature, then it's unconstrained .
1795
1811
CanGenericSignature extSig = getGenericSignature ().getCanonicalSignature ();
1796
1812
if (!extSig)
1797
1813
return false ;
@@ -1808,37 +1824,18 @@ bool ExtensionDecl::isWrittenWithConstraints() const {
1808
1824
SmallVector<InverseRequirement, 2 > typeInverseReqs;
1809
1825
typeSig->getRequirementsWithInverses (typeReqs, typeInverseReqs);
1810
1826
1811
- // If the ( non-inverse) requirements are different between the extension and
1827
+ // If the non-inverse requirements are different between the extension and
1812
1828
// the original type, it's written with constraints.
1813
- if (extReqs. size () != typeReqs. size ()) {
1829
+ if (extReqs != typeReqs)
1814
1830
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
- }
1826
1831
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 ;
1839
1836
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 ;
1842
1839
}
1843
1840
1844
1841
bool ExtensionDecl::isInSameDefiningModule () const {
0 commit comments