@@ -1051,29 +1051,26 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
10511051 UNINTERESTING (Accessor) // Handled by the Var or Subscript.
10521052 UNINTERESTING (OpaqueType) // Handled by the Var or Subscript.
10531053
1054- // / If \p PBD declared stored instance properties in a fixed-contents struct,
1055- // / return said struct.
1056- static const StructDecl *
1057- getFixedLayoutStructContext (const PatternBindingDecl *PBD) {
1058- auto *parentStruct = dyn_cast<StructDecl>(PBD->getDeclContext ());
1059- if (!parentStruct)
1060- return nullptr ;
1061- if (!(parentStruct->getAttrs ().hasAttribute <FrozenAttr>() ||
1062- parentStruct->getAttrs ().hasAttribute <FixedLayoutAttr>()) ||
1063- PBD->isStatic () || !PBD->hasStorage ()) {
1064- return nullptr ;
1065- }
1066- // We don't check for "in resilient modules" because there's no reason to
1067- // write '@_fixedLayout' on a struct in a non-resilient module.
1068- return parentStruct;
1054+ // / If \p VD's layout is exposed by a @frozen struct or class, return said
1055+ // / struct or class.
1056+ // /
1057+ // / Stored instance properties in @frozen structs and classes must always use
1058+ // / public/@usableFromInline types. In these cases, check the access against
1059+ // / the struct instead of the VarDecl, and customize the diagnostics.
1060+ static const ValueDecl *
1061+ getFixedLayoutStructContext (const VarDecl *VD) {
1062+ if (VD->isLayoutExposedToClients ())
1063+ return dyn_cast<NominalTypeDecl>(VD->getDeclContext ());
1064+
1065+ return nullptr ;
10691066 }
10701067
10711068 // / \see visitPatternBindingDecl
10721069 void checkNamedPattern (const NamedPattern *NP,
1073- const ValueDecl *fixedLayoutStructContext,
10741070 bool isTypeContext,
10751071 const llvm::DenseSet<const VarDecl *> &seenVars) {
10761072 const VarDecl *theVar = NP->getDecl ();
1073+ auto *fixedLayoutStructContext = getFixedLayoutStructContext (theVar);
10771074 if (!fixedLayoutStructContext && shouldSkipChecking (theVar))
10781075 return ;
10791076 // Only check individual variables if we didn't check an enclosing
@@ -1101,7 +1098,6 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
11011098
11021099 // / \see visitPatternBindingDecl
11031100 void checkTypedPattern (const TypedPattern *TP,
1104- const ValueDecl *fixedLayoutStructContext,
11051101 bool isTypeContext,
11061102 llvm::DenseSet<const VarDecl *> &seenVars) {
11071103 // FIXME: We need an access level to check against, so we pull one out
@@ -1114,6 +1110,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
11141110 });
11151111 if (!anyVar)
11161112 return ;
1113+ auto *fixedLayoutStructContext = getFixedLayoutStructContext (anyVar);
11171114 if (!fixedLayoutStructContext && shouldSkipChecking (anyVar))
11181115 return ;
11191116
@@ -1154,27 +1151,18 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
11541151 void visitPatternBindingDecl (PatternBindingDecl *PBD) {
11551152 bool isTypeContext = PBD->getDeclContext ()->isTypeContext ();
11561153
1157- // Stored instance properties in public/@usableFromInline fixed-contents
1158- // structs in resilient modules must always use public/@usableFromInline
1159- // types. In these cases, check the access against the struct instead of the
1160- // VarDecl, and customize the diagnostics.
1161- const ValueDecl *fixedLayoutStructContext =
1162- getFixedLayoutStructContext (PBD);
1163-
11641154 llvm::DenseSet<const VarDecl *> seenVars;
11651155 for (auto idx : range (PBD->getNumPatternEntries ())) {
11661156 PBD->getPattern (idx)->forEachNode ([&](const Pattern *P) {
11671157 if (auto *NP = dyn_cast<NamedPattern>(P)) {
1168- checkNamedPattern (NP, fixedLayoutStructContext, isTypeContext,
1169- seenVars);
1158+ checkNamedPattern (NP, isTypeContext, seenVars);
11701159 return ;
11711160 }
11721161
11731162 auto *TP = dyn_cast<TypedPattern>(P);
11741163 if (!TP)
11751164 return ;
1176- checkTypedPattern (TP, fixedLayoutStructContext, isTypeContext,
1177- seenVars);
1165+ checkTypedPattern (TP, isTypeContext, seenVars);
11781166 });
11791167 seenVars.clear ();
11801168 }
0 commit comments