From 7e1eac7f08d4b43cc31caf9f60a455f752e438e6 Mon Sep 17 00:00:00 2001 From: Allan Shortlidge Date: Wed, 7 Aug 2024 16:43:05 -0700 Subject: [PATCH] Sema: Avoid emitting superfluous resilience diagnostics with `MemberImportVisibility`. When `MemberImportVisibility` is enabled, if the import that would bring a member declaration into scope is missing it is diagnosed as an error. The existing resilience diagnostics that would also diagnose the same problem in contexts that are visible in the module interface are therefore superflous with the feature enabled. --- include/swift/AST/SourceFile.h | 5 +++++ lib/Sema/ResilienceDiagnostics.cpp | 13 ++++++++----- .../members_transitive_multifile_access_level.swift | 6 ------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/include/swift/AST/SourceFile.h b/include/swift/AST/SourceFile.h index 280e09c181f9..079a75c4da4c 100644 --- a/include/swift/AST/SourceFile.h +++ b/include/swift/AST/SourceFile.h @@ -507,6 +507,11 @@ class SourceFile final : public FileUnit { MissingImportForMemberDiagnostics[decl].push_back(loc); } + /// Returns true if there is a pending missing import diagnostic for \p decl. + bool hasDelayedMissingImportForMemberDiagnostic(const ValueDecl *decl) const { + return MissingImportForMemberDiagnostics.contains(decl); + } + DelayedMissingImportForMemberDiags takeDelayedMissingImportForMemberDiagnostics() { DelayedMissingImportForMemberDiags diags; diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp index a83026cf69b8..276e5b64ff86 100644 --- a/lib/Sema/ResilienceDiagnostics.cpp +++ b/lib/Sema/ResilienceDiagnostics.cpp @@ -236,6 +236,7 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D, auto reason = where.getExportabilityReason(); auto DC = where.getDeclContext(); + auto SF = DC->getParentSourceFile(); ASTContext &ctx = DC->getASTContext(); auto originKind = getDisallowedOriginKind(D, where, downgradeToWarning); @@ -275,16 +276,18 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D, if (originKind == DisallowedOriginKind::None) return false; - auto diagName = D->getName(); + // Some diagnostics emitted with the `MemberImportVisibility` feature enabled + // subsume these diagnostics. + if (originKind == DisallowedOriginKind::MissingImport && + ctx.LangOpts.hasFeature(Feature::MemberImportVisibility) && SF && + SF->hasDelayedMissingImportForMemberDiagnostic(D)) + return false; + if (auto accessor = dyn_cast(D)) { // Only diagnose accessors if their disallowed origin kind differs from // that of their storage. if (getDisallowedOriginKind(accessor->getStorage(), where) == originKind) return false; - - // For accessors, diagnose with the name of the storage instead of the - // implicit '_'. - diagName = accessor->getStorage()->getName(); } auto fragileKind = where.getFragileFunctionKind(); diff --git a/test/NameLookup/members_transitive_multifile_access_level.swift b/test/NameLookup/members_transitive_multifile_access_level.swift index 179a68a4f002..e3e0fcc1c9f4 100644 --- a/test/NameLookup/members_transitive_multifile_access_level.swift +++ b/test/NameLookup/members_transitive_multifile_access_level.swift @@ -60,9 +60,7 @@ extension Int { internal func usesTypealiasInInternalUsesOnly(x: TypealiasInInternalUsesOnly) {} // expected-error {{type alias 'TypealiasInInternalUsesOnly' is not available due to missing import of defining module 'InternalUsesOnly'}} package func usesTypealiasInPackageUsesOnly(x: TypealiasInPackageUsesOnly) {} // expected-error {{type alias 'TypealiasInPackageUsesOnly' is not available due to missing import of defining module 'PackageUsesOnly'}} public func usesTypealiasInPublicUsesOnly(x: TypealiasInPublicUsesOnly) {} // expected-error {{type alias 'TypealiasInPublicUsesOnly' is not available due to missing import of defining module 'PublicUsesOnly'}} - // expected-warning@-1 {{cannot use type alias 'TypealiasInPublicUsesOnly' here; 'PublicUsesOnly' was not imported by this file}} public func usesTypealiasInMixedUses(x: TypealiasInMixedUses) {} // expected-error {{type alias 'TypealiasInMixedUses' is not available due to missing import of defining module 'MixedUses'}} - // expected-warning@-1 {{cannot use type alias 'TypealiasInMixedUses' here; 'MixedUses' was not imported by this file}} internal func usesTypealiasInMixedUses_Internal(x: TypealiasInMixedUses) {} // expected-error {{type alias 'TypealiasInMixedUses' is not available due to missing import of defining module 'MixedUses'}} } @@ -78,9 +76,7 @@ private func usesTypealiasInInternalUsesOnly_Private(x: Int.TypealiasInInternalU internal func usesTypealiasInInternalUsesOnly(x: Int.TypealiasInInternalUsesOnly) {} // expected-error {{type alias 'TypealiasInInternalUsesOnly' is not available due to missing import of defining module 'InternalUsesOnly'}} package func usesTypealiasInPackageUsesOnly(x: Int.TypealiasInPackageUsesOnly) {} // expected-error {{type alias 'TypealiasInPackageUsesOnly' is not available due to missing import of defining module 'PackageUsesOnly'}} public func usesTypealiasInPublicUsesOnly(x: Int.TypealiasInPublicUsesOnly) {} // expected-error {{type alias 'TypealiasInPublicUsesOnly' is not available due to missing import of defining module 'PublicUsesOnly'}} -// expected-warning@-1 {{cannot use type alias 'TypealiasInPublicUsesOnly' here; 'PublicUsesOnly' was not imported by this file}} public func usesTypealiasInMixedUses(x: Int.TypealiasInMixedUses) {} // expected-error {{type alias 'TypealiasInMixedUses' is not available due to missing import of defining module 'MixedUses'}} -// expected-warning@-1 {{cannot use type alias 'TypealiasInMixedUses' here; 'MixedUses' was not imported by this file}} internal func usesTypealiasInMixedUses_Internal(x: Int.TypealiasInMixedUses) {} // expected-error {{type alias 'TypealiasInMixedUses' is not available due to missing import of defining module 'MixedUses'}} //--- extensions.swift @@ -104,12 +100,10 @@ extension Int.NestedInPackageUsesOnly { // expected-error {{struct 'NestedInPack } extension Int.NestedInPublicUsesOnly { // expected-error {{struct 'NestedInPublicUsesOnly' is not available due to missing import of defining module 'PublicUsesOnly'}} - // expected-warning@-1 {{cannot use struct 'NestedInPublicUsesOnly' in an extension with public or '@usableFromInline' members; 'PublicUsesOnly' was not imported by this file}} public func publicMethod() {} } extension Int.NestedInMixedUses { // expected-error {{struct 'NestedInMixedUses' is not available due to missing import of defining module 'MixedUses'}} - // expected-warning@-1 {{cannot use struct 'NestedInMixedUses' in an extension with public or '@usableFromInline' members; 'MixedUses' was not imported by this file}} public func publicMethod() {} }