1414
1515#include " swift/AST/Decl.h"
1616#include " swift/AST/ExistentialLayout.h"
17- #include " swift/AST/InverseMarking .h"
17+ #include " swift/AST/NameLookup .h"
1818#include " swift/AST/ParameterList.h"
1919#include " swift/AST/Pattern.h"
2020#include " clang/AST/DeclObjC.h"
@@ -33,62 +33,6 @@ static bool usesTypeMatching(Decl *decl, llvm::function_ref<bool(Type)> fn) {
3333 return false ;
3434}
3535
36- // / \param isRelevantInverse the function used to inspect a mark corresponding
37- // / to an inverse to determine whether it "has" an inverse that we care about.
38- static bool hasInverse (
39- Decl *decl, InvertibleProtocolKind ip,
40- std::function<bool (InverseMarking::Mark const &)> isRelevantInverse) {
41-
42- auto getTypeDecl = [](Type type) -> TypeDecl * {
43- if (auto genericTy = type->getAnyGeneric ())
44- return genericTy;
45- if (auto gtpt = dyn_cast<GenericTypeParamType>(type))
46- return gtpt->getDecl ();
47- return nullptr ;
48- };
49-
50- if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
51- if (auto *nominal = extension->getSelfNominalTypeDecl ())
52- return hasInverse (nominal, ip, isRelevantInverse);
53- return false ;
54- }
55-
56- auto hasInverseInType = [&](Type type) {
57- return type.findIf ([&](Type type) -> bool {
58- if (auto *typeDecl = getTypeDecl (type))
59- return hasInverse (typeDecl, ip, isRelevantInverse);
60- return false ;
61- });
62- };
63-
64- if (auto *TD = dyn_cast<TypeDecl>(decl)) {
65- if (auto *alias = dyn_cast<TypeAliasDecl>(TD))
66- return hasInverseInType (alias->getUnderlyingType ());
67-
68- if (auto *NTD = dyn_cast<NominalTypeDecl>(TD)) {
69- if (isRelevantInverse (NTD->hasInverseMarking (ip)))
70- return true ;
71- }
72-
73- if (auto *P = dyn_cast<ProtocolDecl>(TD)) {
74- // Check the protocol's associated types too.
75- return llvm::any_of (
76- P->getAssociatedTypeMembers (), [&](AssociatedTypeDecl *ATD) {
77- return isRelevantInverse (ATD->hasInverseMarking (ip));
78- });
79- }
80-
81- return false ;
82- }
83-
84- if (auto *VD = dyn_cast<ValueDecl>(decl)) {
85- if (VD->hasInterfaceType ())
86- return hasInverseInType (VD->getInterfaceType ());
87- }
88-
89- return false ;
90- }
91-
9236// ----------------------------------------------------------------------------
9337// MARK: - Standard Features
9438// ----------------------------------------------------------------------------
@@ -255,10 +199,39 @@ static bool usesFeatureExtensionMacros(Decl *decl) {
255199}
256200
257201static bool usesFeatureMoveOnly (Decl *decl) {
258- return hasInverse (decl, InvertibleProtocolKind::Copyable,
259- [](auto &marking) -> bool {
260- return marking.is (InverseMarking::Kind::LegacyExplicit);
261- });
202+ if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
203+ if (auto *nominal = extension->getExtendedNominal ())
204+ return usesFeatureMoveOnly (nominal);
205+ return false ;
206+ }
207+
208+ auto hasInverseInType = [&](Type type) {
209+ return type.findIf ([&](Type type) -> bool {
210+ if (auto *NTD = type->getAnyNominal ()) {
211+ if (NTD->getAttrs ().hasAttribute <MoveOnlyAttr>())
212+ return true ;
213+ }
214+ return false ;
215+ });
216+ };
217+
218+ if (auto *TD = dyn_cast<TypeDecl>(decl)) {
219+ if (auto *alias = dyn_cast<TypeAliasDecl>(TD))
220+ return hasInverseInType (alias->getUnderlyingType ());
221+
222+ if (auto *NTD = dyn_cast<NominalTypeDecl>(TD)) {
223+ if (NTD->getAttrs ().hasAttribute <MoveOnlyAttr>())
224+ return true ;
225+ }
226+
227+ return false ;
228+ }
229+
230+ if (auto *VD = dyn_cast<ValueDecl>(decl)) {
231+ return hasInverseInType (VD->getInterfaceType ());
232+ }
233+
234+ return false ;
262235}
263236
264237static bool usesFeatureMoveOnlyResilientTypes (Decl *decl) {
@@ -525,22 +498,49 @@ static bool usesFeatureRawLayout(Decl *decl) {
525498UNINTERESTING_FEATURE (Embedded)
526499
527500static bool usesFeatureNoncopyableGenerics(Decl *decl) {
528- auto checkInverseMarking = [](auto &marking) -> bool {
529- switch (marking.getKind ()) {
530- case InverseMarking::Kind::None:
531- case InverseMarking::Kind::LegacyExplicit: // covered by other checks.
532- return false ;
501+ if (auto *valueDecl = dyn_cast<ValueDecl>(decl)) {
502+ if (isa<StructDecl, EnumDecl, ClassDecl>(decl)) {
503+ auto *nominalDecl = cast<NominalTypeDecl>(valueDecl);
533504
534- case InverseMarking::Kind::Explicit:
535- case InverseMarking::Kind::Inferred:
536- return true ;
505+ InvertibleProtocolSet inverses;
506+ bool anyObject = false ;
507+ getDirectlyInheritedNominalTypeDecls (nominalDecl, inverses, anyObject);
508+ if (!inverses.empty ())
509+ return true ;
537510 }
538- };
539511
540- return hasInverse (decl, InvertibleProtocolKind::Copyable,
541- checkInverseMarking) ||
542- hasInverse (decl, InvertibleProtocolKind::Escapable,
543- checkInverseMarking);
512+ if (isa<AbstractFunctionDecl>(valueDecl) ||
513+ isa<AbstractStorageDecl>(valueDecl)) {
514+ if (valueDecl->getInterfaceType ().findIf ([&](Type type) -> bool {
515+ if (auto *nominalDecl = type->getAnyNominal ()) {
516+ if (isa<StructDecl, EnumDecl, ClassDecl>(nominalDecl))
517+ return usesFeatureNoncopyableGenerics (nominalDecl);
518+ }
519+ return false ;
520+ })) {
521+ return true ;
522+ }
523+ }
524+ }
525+
526+ if (auto *ext = dyn_cast<ExtensionDecl>(decl)) {
527+ if (auto *nominal = ext->getExtendedNominal ())
528+ if (usesFeatureNoncopyableGenerics (nominal))
529+ return true ;
530+ }
531+
532+ SmallVector<Requirement, 2 > reqs;
533+ SmallVector<InverseRequirement, 2 > inverseReqs;
534+
535+ if (auto *proto = dyn_cast<ProtocolDecl>(decl)) {
536+ proto->getRequirementSignature ().getRequirementsWithInverses (
537+ proto, reqs, inverseReqs);
538+ } else if (auto *genCtx = decl->getAsGenericContext ()) {
539+ if (auto genericSig = genCtx->getGenericSignature ())
540+ genericSig->getRequirementsWithInverses (reqs, inverseReqs);
541+ }
542+
543+ return !inverseReqs.empty ();
544544}
545545
546546static bool usesFeatureStructLetDestructuring (Decl *decl) {
0 commit comments