@@ -4930,6 +4930,25 @@ SourceLoc Decl::getAttributeInsertionLoc(bool forModifier) const {
49304930 return resultLoc;
49314931}
49324932
4933+ bool ValueDecl::hasAttributeWithInlinableSemantics () const {
4934+ if (getAttrs ().hasAttribute <InlinableAttr>())
4935+ return true ;
4936+
4937+ // @inline(always) implies @inlinable on "public" (open, public, package)
4938+ // declarations.
4939+ AccessScope access =
4940+ getFormalAccessScope (nullptr , /* treatUsableFromInlineAsPublic*/ false );
4941+ if (!access.isPublicOrPackage ())
4942+ return false ;
4943+
4944+ if (auto *inlineAttr = getAttrs ().getAttribute <InlineAttr>()) {
4945+ if (inlineAttr && inlineAttr->getKind () == InlineKind::Always)
4946+ return true ;
4947+ }
4948+
4949+ return false ;
4950+ }
4951+
49334952// / Returns true if \p VD needs to be treated as publicly-accessible
49344953// / at the SIL, LLVM, and machine levels due to being @usableFromInline.
49354954bool ValueDecl::isUsableFromInline () const {
@@ -4942,22 +4961,22 @@ bool ValueDecl::isUsableFromInline() const {
49424961
49434962 if (getAttrs ().hasAttribute <UsableFromInlineAttr>() ||
49444963 getAttrs ().hasAttribute <AlwaysEmitIntoClientAttr>() ||
4945- getAttrs (). hasAttribute <InlinableAttr> ())
4964+ hasAttributeWithInlinableSemantics ())
49464965 return true ;
49474966
49484967 if (auto *accessor = dyn_cast<AccessorDecl>(this )) {
49494968 auto *storage = accessor->getStorage ();
49504969 if (storage->getAttrs ().hasAttribute <UsableFromInlineAttr>() ||
49514970 storage->getAttrs ().hasAttribute <AlwaysEmitIntoClientAttr>() ||
4952- storage->getAttrs (). hasAttribute <InlinableAttr> ())
4971+ storage->hasAttributeWithInlinableSemantics ())
49534972 return true ;
49544973 }
49554974
49564975 if (auto *opaqueType = dyn_cast<OpaqueTypeDecl>(this )) {
49574976 if (auto *namingDecl = opaqueType->getNamingDecl ()) {
49584977 if (namingDecl->getAttrs ().hasAttribute <UsableFromInlineAttr>() ||
49594978 namingDecl->getAttrs ().hasAttribute <AlwaysEmitIntoClientAttr>() ||
4960- namingDecl->getAttrs (). hasAttribute <InlinableAttr> ())
4979+ namingDecl->hasAttributeWithInlinableSemantics ())
49614980 return true ;
49624981 }
49634982 }
@@ -5576,7 +5595,7 @@ void ValueDecl::copyFormalAccessFrom(const ValueDecl *source,
55765595 // Inherit the @usableFromInline attribute.
55775596 if (source->getAttrs ().hasAttribute <UsableFromInlineAttr>() &&
55785597 !getAttrs ().hasAttribute <UsableFromInlineAttr>() &&
5579- !getAttrs (). hasAttribute <InlinableAttr> () &&
5598+ !hasAttributeWithInlinableSemantics () &&
55805599 DeclAttribute::canAttributeAppearOnDecl (DeclAttrKind::UsableFromInline,
55815600 this )) {
55825601 auto &ctx = getASTContext ();
@@ -10712,7 +10731,7 @@ bool AbstractFunctionDecl::isValidKeyPathComponent() const {
1071210731
1071310732bool AbstractFunctionDecl::isResilient () const {
1071410733 // Check for attributes that makes functions non-resilient.
10715- if (getAttrs (). hasAttribute <InlinableAttr> () &&
10734+ if (hasAttributeWithInlinableSemantics () &&
1071610735 getAttrs ().hasAttribute <UsableFromInlineAttr>())
1071710736 return false ;
1071810737
0 commit comments