Skip to content

Commit ad6423f

Browse files
authored
Merge pull request #67979 from jckarter/narrow-nominal-type-decl-is-resilient-originally-defined-in-check
Narrow `@_originallyDefinedIn` check in NominalTypeDecl::isResilient to protocols.
2 parents cb4aeef + 448bb42 commit ad6423f

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

lib/AST/Decl.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4783,11 +4783,31 @@ bool NominalTypeDecl::isResilient(ModuleDecl *M,
47834783
case ResilienceExpansion::Minimal:
47844784
return isResilient();
47854785
case ResilienceExpansion::Maximal:
4786-
// We consider this decl belongs to the module either it's currently
4787-
// defined in this module or it's originally defined in this module, which
4788-
// is specified by @_originallyDefinedIn
4789-
return M != getModuleContext() && !isOriginallyDefinedIn(this, M) &&
4790-
isResilient();
4786+
// We can access declarations from the same module
4787+
// non-resiliently in a maximal context.
4788+
if (M == getModuleContext()) {
4789+
return false;
4790+
}
4791+
// If a protocol is originally declared in the current module, then we
4792+
// directly expose protocol witness tables and their contents for any
4793+
// conformances in the same module as symbols. If the protocol later
4794+
// moves, then we need to preserve those extra symbols from the home
4795+
// module by treating the protocol as if it was still defined in the same
4796+
// module.
4797+
//
4798+
// This logic does not and should not generally extend to other kinds of
4799+
// declaration. If a declaration moves to a new module with library
4800+
// evolution enabled, then even the original module has to access it
4801+
// according to the library evolution ABI. This is an ABI compatibility
4802+
// hack only for protocols. If you see other variations of `isResilient`
4803+
// that don't check `isOriginallyDefinedIn`, they are probably correct.
4804+
if (isa<ProtocolDecl>(this)
4805+
&& isOriginallyDefinedIn(this, M)) {
4806+
return false;
4807+
}
4808+
// Otherwise, we have to access the declaration resiliently if it's
4809+
// resilient anywhere.
4810+
return isResilient();
47914811
}
47924812
llvm_unreachable("bad resilience expansion");
47934813
}

0 commit comments

Comments
 (0)