mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
AST: Filter out some Obj-C overrides when MemberImportVisibility is enabled.
Unlike in Swift, Obj-C allows method overrides to be declared in extensions (categories), even outside of the module that defines the type that is being extended. When MemberImportVisibility is enabled, these overrides must be filtered out to prevent them from hijacking name lookup and causing the compiler to insist that the module that defines the extension be imported. Resolves rdar://145329988.
This commit is contained in:
@@ -2388,6 +2388,8 @@ static bool isAcceptableLookupResult(const DeclContext *dc, NLOptions options,
|
||||
ValueDecl *decl,
|
||||
bool onlyCompleteObjectInits,
|
||||
bool requireImport) {
|
||||
auto &ctx = dc->getASTContext();
|
||||
|
||||
// Filter out designated initializers, if requested.
|
||||
if (onlyCompleteObjectInits) {
|
||||
if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
|
||||
@@ -2405,19 +2407,43 @@ static bool isAcceptableLookupResult(const DeclContext *dc, NLOptions options,
|
||||
}
|
||||
|
||||
// Check access.
|
||||
if (!(options & NL_IgnoreAccessControl) &&
|
||||
!dc->getASTContext().isAccessControlDisabled()) {
|
||||
if (!(options & NL_IgnoreAccessControl) && !ctx.isAccessControlDisabled()) {
|
||||
bool allowUsableFromInline = options & NL_IncludeUsableFromInline;
|
||||
if (!decl->isAccessibleFrom(dc, /*forConformance*/ false,
|
||||
allowUsableFromInline))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that there is some import in the originating context that makes this
|
||||
// decl visible.
|
||||
if (requireImport && !(options & NL_IgnoreMissingImports))
|
||||
if (!dc->isDeclImported(decl))
|
||||
return false;
|
||||
if (requireImport) {
|
||||
// Check that there is some import in the originating context that makes
|
||||
// this decl visible.
|
||||
if (!(options & NL_IgnoreMissingImports)) {
|
||||
if (!dc->isDeclImported(decl))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unlike in Swift, Obj-C allows method overrides to be declared in
|
||||
// extensions (categories), even outside of the module that defines the
|
||||
// type that is being extended. When MemberImportVisibility is enabled,
|
||||
// if these overrides are not filtered out they can hijack name
|
||||
// lookup and cause the compiler to insist that the module that defines
|
||||
// the extension be imported, contrary to developer expectations.
|
||||
//
|
||||
// Filter results belonging to these extensions out, even when ignoring
|
||||
// missing imports, if we're in a context that requires imports to access
|
||||
// member declarations.
|
||||
if (decl->getOverriddenDecl()) {
|
||||
if (auto *extension = dyn_cast<ExtensionDecl>(decl->getDeclContext())) {
|
||||
if (auto *nominal = extension->getExtendedNominal()) {
|
||||
auto extensionMod = extension->getModuleContext();
|
||||
auto nominalMod = nominal->getModuleContext();
|
||||
if (!extensionMod->isSameModuleLookingThroughOverlays(nominalMod) &&
|
||||
!dc->isDeclImported(extension))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that it has the appropriate ABI role.
|
||||
if (!ABIRoleInfo(decl).matchesOptions(options))
|
||||
|
||||
Reference in New Issue
Block a user