@@ -3284,8 +3284,6 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
32843284 // / anything needed by a client as unsafe as the client will reject reading
32853285 // / it, but at the same time keep the safety checks precise to avoid
32863286 // / XRef errors and such.
3287- // /
3288- // / \p decl should be either an \c ExtensionDecl or a \c ValueDecl.
32893287 static bool isDeserializationSafe (const Decl *decl) {
32903288 if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
32913289 // Consider extensions as safe as their extended type.
@@ -3308,8 +3306,11 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
33083306 // We can mark the extension unsafe only if it has no public
33093307 // conformances.
33103308 auto protocols = ext->getLocalProtocols (ConformanceLookupKind::All);
3311- bool hasSafeConformances = std::any_of (protocols.begin (), protocols.end (),
3312- isDeserializationSafe);
3309+ bool hasSafeConformances = std::any_of (
3310+ protocols.begin (), protocols.end (), [](ProtocolDecl *protocol) {
3311+ return isDeserializationSafe (protocol);
3312+ });
3313+
33133314 if (hasSafeConformances)
33143315 return true ;
33153316
@@ -3320,11 +3321,26 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
33203321 return false ;
33213322 }
33223323
3323- auto value = cast<ValueDecl>(decl);
3324+ if (auto pbd = dyn_cast<PatternBindingDecl>(decl)) {
3325+ // Pattern bindings are safe if any of their var decls are safe.
3326+ for (auto i : range (pbd->getNumPatternEntries ())) {
3327+ if (auto *varDecl = pbd->getAnchoringVarDecl (i)) {
3328+ if (isDeserializationSafe (varDecl))
3329+ return true ;
3330+ }
3331+ }
33243332
3333+ return false ;
3334+ }
3335+
3336+ return isDeserializationSafe (cast<ValueDecl>(decl));
3337+ }
3338+
3339+ static bool isDeserializationSafe (const ValueDecl *value) {
33253340 // A decl is safe if formally accessible publicly.
3326- auto accessScope = value->getFormalAccessScope (/* useDC=*/ nullptr ,
3327- /* treatUsableFromInlineAsPublic=*/ true );
3341+ auto accessScope =
3342+ value->getFormalAccessScope (/* useDC=*/ nullptr ,
3343+ /* treatUsableFromInlineAsPublic=*/ true );
33283344 if (accessScope.isPublic () || accessScope.isPackage ())
33293345 return true ;
33303346
@@ -3351,7 +3367,7 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
33513367 }
33523368
33533369 // Paramters don't have meaningful access control.
3354- if (isa<ParamDecl>(decl ) || isa<GenericTypeParamDecl>(decl ))
3370+ if (isa<ParamDecl>(value ) || isa<GenericTypeParamDecl>(value ))
33553371 return true ;
33563372
33573373 return false ;
@@ -3919,7 +3935,13 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
39193935 initContextIDs);
39203936
39213937 for (auto entryIdx : range (binding->getNumPatternEntries ())) {
3922- writePattern (binding->getPattern (entryIdx));
3938+ auto pattern = binding->getPattern (entryIdx);
3939+
3940+ // Force the entry to be typechecked before attempting to serialize.
3941+ if (!pattern->hasType ())
3942+ (void )binding->getCheckedPatternBindingEntry (entryIdx);
3943+
3944+ writePattern (pattern);
39233945 // Ignore initializer; external clients don't need to know about it.
39243946 }
39253947 }
0 commit comments