From fbf0f5a8e26adc9a8edda1747d12e4caf54a1eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Thu, 23 Jun 2022 17:45:16 -0700 Subject: [PATCH 1/7] [OSLog] Add missing imports for implicit uses of NSObject --- stdlib/private/OSLog/OSLogFloatingPointTypes.swift | 2 ++ stdlib/private/OSLog/OSLogIntegerTypes.swift | 2 ++ stdlib/private/OSLog/OSLogStringTypes.swift | 2 ++ 3 files changed, 6 insertions(+) diff --git a/stdlib/private/OSLog/OSLogFloatingPointTypes.swift b/stdlib/private/OSLog/OSLogFloatingPointTypes.swift index 37efbe6d5a7..e68a2717806 100644 --- a/stdlib/private/OSLog/OSLogFloatingPointTypes.swift +++ b/stdlib/private/OSLog/OSLogFloatingPointTypes.swift @@ -20,6 +20,8 @@ // // "\(x, format: .fixed(precision: 10), privacy: .private\)" +import ObjectiveC + extension OSLogInterpolation { /// Defines interpolation for expressions of type Float. diff --git a/stdlib/private/OSLog/OSLogIntegerTypes.swift b/stdlib/private/OSLog/OSLogIntegerTypes.swift index 306e6230b83..ed5985d8c8b 100644 --- a/stdlib/private/OSLog/OSLogIntegerTypes.swift +++ b/stdlib/private/OSLog/OSLogIntegerTypes.swift @@ -22,6 +22,8 @@ // 1. "\(x, format: .hex, privacy: .private, align: .right\)" // 2. "\(x, format: .hex(minDigits: 10), align: .right(columns: 10)\)" +import ObjectiveC + extension OSLogInterpolation { /// Defines interpolation for expressions of type Int. diff --git a/stdlib/private/OSLog/OSLogStringTypes.swift b/stdlib/private/OSLog/OSLogStringTypes.swift index 6aea1834045..caad2794729 100644 --- a/stdlib/private/OSLog/OSLogStringTypes.swift +++ b/stdlib/private/OSLog/OSLogStringTypes.swift @@ -22,6 +22,8 @@ // 1. "\(x, privacy: .private, align: .right\)" // 2. "\(x, align: .right(columns: 10)\)" +import ObjectiveC + extension OSLogInterpolation { /// Defines interpolation for expressions of type String. From 4c995a3a87894f32b1477c4110ddf3e25df8f6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Thu, 23 Jun 2022 16:29:08 -0700 Subject: [PATCH 2/7] [Sema] Generalize isImplementationOnlyImported Renaming isImportedImplementationOnly to getRestrictedImportKind will allow us to support different kind of restrictive imports in the next commits. --- include/swift/AST/SourceFile.h | 12 +++++++++++- lib/AST/Module.cpp | 14 ++++++-------- lib/Sema/TypeCheckAccess.cpp | 7 +++++-- lib/Sema/TypeCheckDeclOverride.cpp | 2 +- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/include/swift/AST/SourceFile.h b/include/swift/AST/SourceFile.h index bfd778355e8..9e73ca4a65b 100644 --- a/include/swift/AST/SourceFile.h +++ b/include/swift/AST/SourceFile.h @@ -25,6 +25,15 @@ namespace swift { class PersistentParserState; +/// Kind of import affecting how a decl can be reexported. +/// This is a subset of \c DisallowedOriginKind. +/// +/// \sa getRestrictedImportKind +enum class RestrictedImportKind { + ImplementationOnly, + None // No restriction, i.e. the module is imported publicly. +}; + /// A file containing Swift source code. /// /// This is a .swift or .sil file (or a virtual file, such as the contents of @@ -336,7 +345,8 @@ public: /// If not, we can fast-path module checks. bool hasImplementationOnlyImports() const; - bool isImportedImplementationOnly(const ModuleDecl *module) const; + /// Get the most permissive restriction applied to the imports of \p module. + RestrictedImportKind getRestrictedImportKind(const ModuleDecl *module) const; /// Find all SPI names imported from \p importedModule by this file, /// collecting the identifiers in \p spiGroups. diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index 556ca5432fa..daaa4256bf1 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -2438,12 +2438,7 @@ bool SourceFile::hasTestableOrPrivateImport( }); } -bool SourceFile::isImportedImplementationOnly(const ModuleDecl *module) const { - // Implementation-only imports are (currently) always source-file-specific, - // so if we don't have any, we know the search is complete. - if (!hasImplementationOnlyImports()) - return false; - +RestrictedImportKind SourceFile::getRestrictedImportKind(const ModuleDecl *module) const { auto &imports = getASTContext().getImportCache(); // Look at the imports of this source file. @@ -2455,11 +2450,14 @@ bool SourceFile::isImportedImplementationOnly(const ModuleDecl *module) const { // If the module is imported this way, it's not imported // implementation-only. if (imports.isImportedBy(module, desc.module.importedModule)) - return false; + return RestrictedImportKind::None; } // Now check this file's enclosing module in case there are re-exports. - return !imports.isImportedBy(module, getParentModule()); + if (imports.isImportedBy(module, getParentModule())) + return RestrictedImportKind::None; + + return RestrictedImportKind::ImplementationOnly; } bool ModuleDecl::isImportedImplementationOnly(const ModuleDecl *module) const { diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index 64e537f3b40..cf072d1fa32 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -1503,7 +1503,9 @@ swift::getDisallowedOriginKind(const Decl *decl, downgradeToWarning = DowngradeToWarning::No; ModuleDecl *M = decl->getModuleContext(); auto *SF = where.getDeclContext()->getParentSourceFile(); - if (SF->isImportedImplementationOnly(M)) { + + RestrictedImportKind howImported = SF->getRestrictedImportKind(M); + if (howImported != RestrictedImportKind::None) { // Temporarily downgrade implementation-only exportability in SPI to // a warning. if (where.isSPI()) @@ -1883,7 +1885,8 @@ public: const SourceFile *SF = refDecl->getDeclContext()->getParentSourceFile(); ModuleDecl *M = PGD->getModuleContext(); - if (!SF->isImportedImplementationOnly(M)) + RestrictedImportKind howImported = SF->getRestrictedImportKind(M); + if (howImported == RestrictedImportKind::None) return; auto &DE = PGD->getASTContext().Diags; diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index 1335590fdc9..52efd1d10dd 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -2332,7 +2332,7 @@ void swift::checkImplementationOnlyOverride(const ValueDecl *VD) { assert(SF && "checking a non-source declaration?"); ModuleDecl *M = overridden->getModuleContext(); - if (SF->isImportedImplementationOnly(M)) { + if (SF->getRestrictedImportKind(M) == RestrictedImportKind::ImplementationOnly) { VD->diagnose(diag::implementation_only_override_import_without_attr, overridden->getDescriptiveKind()) .fixItInsert(VD->getAttributeInsertionLoc(false), From 4d9c8ee5eb1d085513943a38e09984cfc1e69d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Fri, 24 Jun 2022 09:36:30 -0700 Subject: [PATCH 3/7] [Sema] Generalize the downgraded warning for exportability check This warning will be used more generally so let's make bring back the diagnostic in line with the error version. --- include/swift/AST/DiagnosticsSema.def | 4 ++-- .../SPI/implementation_only_spi_import_exposability.swift | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index c84a36abca8..bcd723dfaa2 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2906,8 +2906,8 @@ ERROR(decl_from_hidden_module,none, "it is SPI}4", (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) WARNING(decl_from_hidden_module_warn,none, - "cannot use %0 %1 %select{in SPI|as property wrapper in SPI|" - "as result builder in SPI|" + "cannot use %0 %1 %select{here|as property wrapper here|" + "as result builder here|" "in an extension with public or '@usableFromInline' members|" "in an extension with conditional conformances}2; " "%select{%3 has been imported as implementation-only}4", diff --git a/test/SPI/implementation_only_spi_import_exposability.swift b/test/SPI/implementation_only_spi_import_exposability.swift index c9e37b82d3a..fbdeab72aa3 100644 --- a/test/SPI/implementation_only_spi_import_exposability.swift +++ b/test/SPI/implementation_only_spi_import_exposability.swift @@ -26,8 +26,8 @@ public protocol IOIProtocol {} @_spi(A) @_implementationOnly import Lib -@_spi(B) public func leakSPIStruct(_ a: SPIStruct) -> SPIStruct { fatalError() } // expected-warning 2 {{cannot use struct 'SPIStruct' in SPI; 'Lib' has been imported as implementation-only}} -@_spi(B) public func leakIOIStruct(_ a: IOIStruct) -> IOIStruct { fatalError() } // expected-warning 2 {{cannot use struct 'IOIStruct' in SPI; 'Lib' has been imported as implementation-only}} +@_spi(B) public func leakSPIStruct(_ a: SPIStruct) -> SPIStruct { fatalError() } // expected-warning 2 {{cannot use struct 'SPIStruct' here; 'Lib' has been imported as implementation-only}} +@_spi(B) public func leakIOIStruct(_ a: IOIStruct) -> IOIStruct { fatalError() } // expected-warning 2 {{cannot use struct 'IOIStruct' here; 'Lib' has been imported as implementation-only}} public struct PublicStruct : IOIProtocol, SPIProtocol { // expected-error {{cannot use protocol 'IOIProtocol' here; 'Lib' has been imported as implementation-only}} // expected-error @-1 {{cannot use protocol 'SPIProtocol' here; 'Lib' has been imported as implementation-only}} @@ -46,8 +46,8 @@ public struct PublicStruct : IOIProtocol, SPIProtocol { // expected-error {{cann } @_spi(B) -public struct LocalSPIStruct : IOIProtocol, SPIProtocol { // expected-warning {{cannot use protocol 'IOIProtocol' in SPI; 'Lib' has been imported as implementation-only}} -// expected-warning @-1 {{cannot use protocol 'SPIProtocol' in SPI; 'Lib' has been imported as implementation-only}} +public struct LocalSPIStruct : IOIProtocol, SPIProtocol { // expected-warning {{cannot use protocol 'IOIProtocol' here; 'Lib' has been imported as implementation-only}} +// expected-warning @-1 {{cannot use protocol 'SPIProtocol' here; 'Lib' has been imported as implementation-only}} } #endif From 9127f90d8d73e3031fc53a43e61337e2e2c45413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Thu, 23 Jun 2022 16:43:02 -0700 Subject: [PATCH 4/7] [Sema] Report uses of implicitly imported decls in inlinable code Implicitly imported decls may end up in inlinable code and break the module API. This have been known to lead to deserialization crash and could in theory break the generated swiftinterfaces files. Let's explicitly check for such a case, keeping it to a warning until Swift 6 where we can make it an error. rdar://95816286 --- include/swift/AST/DiagnosticsSema.def | 17 ++++- include/swift/AST/SourceFile.h | 1 + lib/AST/Module.cpp | 10 ++- lib/Sema/ResilienceDiagnostics.cpp | 11 ++- lib/Sema/TypeCheckAccess.cpp | 14 +++- lib/Sema/TypeCheckAccess.h | 2 + .../implicit-import-in-inlinable-code.swift | 74 +++++++++++++++++++ 7 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 test/Sema/implicit-import-in-inlinable-code.swift diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index bcd723dfaa2..ae4512c4349 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2903,14 +2903,17 @@ ERROR(decl_from_hidden_module,none, "in an extension with conditional conformances}2; " "%select{%3 has been imported as implementation-only|" "it is an SPI imported from %3|" - "it is SPI}4", + "it is SPI|" + "%3 was implicitly imported}4", (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) WARNING(decl_from_hidden_module_warn,none, "cannot use %0 %1 %select{here|as property wrapper here|" "as result builder here|" "in an extension with public or '@usableFromInline' members|" "in an extension with conditional conformances}2; " - "%select{%3 has been imported as implementation-only}4", + "%select{%3 has been imported as implementation-only|" + "<>|<>|" + "%3 was implicitly imported}4", (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) ERROR(conformance_from_implementation_only_module,none, "cannot use conformance of %0 to %1 %select{here|as property wrapper here|" @@ -5781,7 +5784,15 @@ ERROR(inlinable_decl_ref_from_hidden_module, none, "%0 %1 cannot be used in " FRAGILE_FUNC_KIND "2 " "because %select{%3 was imported implementation-only|" "it is an SPI imported from %3|" - "it is SPI}4", + "it is SPI|" + "%3 was implicitly imported}4", + (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) + +WARNING(inlinable_decl_ref_from_hidden_module_warn, + none, "%0 %1 cannot be used in " FRAGILE_FUNC_KIND "2 " + "because %select{<>|<>|<>|" + "%3 was implicitly imported}4" + "; this is an error in Swift 6", (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) ERROR(availability_macro_in_inlinable, none, diff --git a/include/swift/AST/SourceFile.h b/include/swift/AST/SourceFile.h index 9e73ca4a65b..3133f3dde7d 100644 --- a/include/swift/AST/SourceFile.h +++ b/include/swift/AST/SourceFile.h @@ -31,6 +31,7 @@ class PersistentParserState; /// \sa getRestrictedImportKind enum class RestrictedImportKind { ImplementationOnly, + Implicit, None // No restriction, i.e. the module is imported publicly. }; diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index daaa4256bf1..522a11e248a 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -2440,14 +2440,18 @@ bool SourceFile::hasTestableOrPrivateImport( RestrictedImportKind SourceFile::getRestrictedImportKind(const ModuleDecl *module) const { auto &imports = getASTContext().getImportCache(); + RestrictedImportKind importKind = RestrictedImportKind::Implicit; // Look at the imports of this source file. for (auto &desc : *Imports) { // Ignore implementation-only imports. - if (desc.options.contains(ImportFlags::ImplementationOnly)) + if (desc.options.contains(ImportFlags::ImplementationOnly)) { + if (imports.isImportedBy(module, desc.module.importedModule)) + importKind = RestrictedImportKind::ImplementationOnly; continue; + } - // If the module is imported this way, it's not imported + // If the module is imported publicly, it's not imported // implementation-only. if (imports.isImportedBy(module, desc.module.importedModule)) return RestrictedImportKind::None; @@ -2457,7 +2461,7 @@ RestrictedImportKind SourceFile::getRestrictedImportKind(const ModuleDecl *modul if (imports.isImportedBy(module, getParentModule())) return RestrictedImportKind::None; - return RestrictedImportKind::ImplementationOnly; + return importKind; } bool ModuleDecl::isImportedImplementationOnly(const ModuleDecl *module) const { diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp index 80dbe4fc63d..48fae1829ab 100644 --- a/lib/Sema/ResilienceDiagnostics.cpp +++ b/lib/Sema/ResilienceDiagnostics.cpp @@ -146,7 +146,16 @@ TypeChecker::diagnoseDeclRefExportability(SourceLoc loc, D->diagnose(diag::kind_declared_here, DescriptiveDeclKind::Type); } else { - ctx.Diags.diagnose(loc, diag::inlinable_decl_ref_from_hidden_module, + // Only implicitly imported decls should be reported as a warning, + // and only for language versions below Swift 6. + assert(downgradeToWarning == DowngradeToWarning::No || + originKind == DisallowedOriginKind::ImplicitlyImported && + "Only implicitly imported decls should be reported as a warning."); + auto errorOrWarning = downgradeToWarning == DowngradeToWarning::Yes? + diag::inlinable_decl_ref_from_hidden_module_warn: + diag::inlinable_decl_ref_from_hidden_module; + + ctx.Diags.diagnose(loc, errorOrWarning, D->getDescriptiveKind(), D->getName(), fragileKind.getSelector(), definingModule->getName(), static_cast(originKind)); diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index cf072d1fa32..c6cc63c0ec7 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -1511,6 +1511,15 @@ swift::getDisallowedOriginKind(const Decl *decl, if (where.isSPI()) downgradeToWarning = DowngradeToWarning::Yes; + // Before Swift 6, implicit imports were not reported unless an + // implementation-only import was also present. Downgrade to a warning + // just in this case. + if (howImported == RestrictedImportKind::Implicit && + !SF->getASTContext().isSwiftVersionAtLeast(6) && + !SF->hasImplementationOnlyImports()) { + downgradeToWarning = DowngradeToWarning::Yes; + } + // Even if the current module is @_implementationOnly, Swift should // not report an error in the cases where the decl is also exported from // a non @_implementationOnly module. Thus, we check to see if there is @@ -1545,7 +1554,10 @@ swift::getDisallowedOriginKind(const Decl *decl, } } } - // Implementation-only imported, cannot be reexported. + + // Restrictively imported, cannot be reexported. + if (howImported == RestrictedImportKind::Implicit) + return DisallowedOriginKind::ImplicitlyImported; return DisallowedOriginKind::ImplementationOnly; } else if ((decl->isSPI() || decl->isAvailableAsSPI()) && !where.isSPI()) { if (decl->isAvailableAsSPI() && !decl->isSPI()) { diff --git a/lib/Sema/TypeCheckAccess.h b/lib/Sema/TypeCheckAccess.h index d5ff2e97d7e..a18d15d1db8 100644 --- a/lib/Sema/TypeCheckAccess.h +++ b/lib/Sema/TypeCheckAccess.h @@ -35,12 +35,14 @@ void checkAccessControl(Decl *D); // Problematic origin of an exported type. // // This enum must be kept in sync with +// diag::inlinable_decl_ref_from_hidden_module, // diag::decl_from_hidden_module and // diag::conformance_from_implementation_only_module. enum class DisallowedOriginKind : uint8_t { ImplementationOnly, SPIImported, SPILocal, + ImplicitlyImported, None }; diff --git a/test/Sema/implicit-import-in-inlinable-code.swift b/test/Sema/implicit-import-in-inlinable-code.swift new file mode 100644 index 00000000000..746cef88d96 --- /dev/null +++ b/test/Sema/implicit-import-in-inlinable-code.swift @@ -0,0 +1,74 @@ +/// Report the use in API of indirectly or implicitly imported decls. + +// RUN: %empty-directory(%t) +// RUN: %{python} %utils/split_file.py -o %t %s + +// RUN: %target-swift-frontend -emit-module %t/empty.swift -module-name empty -o %t/empty.swiftmodule +// RUN: %target-swift-frontend -emit-module %t/libA.swift -module-name libA -o %t/libA.swiftmodule +// RUN: %target-swift-frontend -emit-module %t/libB.swift -module-name libB -o %t/libB.swiftmodule -I %t + +/// In pre-Swift 6, this is a warning where there's no implementation-only import present. +// RUN: %target-swift-frontend -emit-module %t/clientFileA-Swift5.swift %t/clientFileB.swift -module-name client -o %t/client.swiftmodule -I %t -verify + +/// In pre-Swift 6, this remains an error when there's an implementation-only import present. +// RUN: %target-swift-frontend -emit-module %t/clientFileA-OldCheck.swift %t/clientFileB.swift -module-name client -o %t/client.swiftmodule -I %t -verify + +/// In Swift 6, it's an error. +// RUN: %target-swift-frontend -emit-module %t/clientFileA-Swift6.swift %t/clientFileB.swift -module-name client -o %t/client.swiftmodule -I %t -verify -swift-version 6 + +// BEGIN empty.swift + +// BEGIN libA.swift +public struct ImportedType { + public init() {} +} + +// BEGIN libB.swift +import libA + +extension ImportedType { + public func implicitlyImportedMethod() {} +} + +/// Client module +// BEGIN clientFileA-Swift5.swift +import libA + +@inlinable public func bar() { + let a = ImportedType() + a.implicitlyImportedMethod() // expected-warning {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was implicitly imported; this is an error in Swift 6}} + + // Expected implicit imports are still fine + a.localModuleMethod() +} + +// BEGIN clientFileA-OldCheck.swift +import libA +@_implementationOnly import empty + +@inlinable public func bar() { + let a = ImportedType() + a.implicitlyImportedMethod() // expected-error {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was implicitly imported}} + + // Expected implicit imports are still fine + a.localModuleMethod() +} + +// BEGIN clientFileA-Swift6.swift +import libA + +@inlinable public func bar() { + let a = ImportedType() + a.implicitlyImportedMethod() // expected-error {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was implicitly imported}} + + // Expected implicit imports are still fine + a.localModuleMethod() +} + +// BEGIN clientFileB.swift +@_implementationOnly import libB +import libA +extension ImportedType { + public func localModuleMethod() {} +} + From 8fc80f96d5fa5e3e24b1aa179f9f3319d7ca100d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Thu, 30 Jun 2022 08:54:23 -0700 Subject: [PATCH 5/7] [Sema] Make "not-imported" diagnostic more direct --- include/swift/AST/DiagnosticsSema.def | 8 ++++---- test/Sema/implicit-import-in-inlinable-code.swift | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index ae4512c4349..8850924e4b4 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2904,7 +2904,7 @@ ERROR(decl_from_hidden_module,none, "%select{%3 has been imported as implementation-only|" "it is an SPI imported from %3|" "it is SPI|" - "%3 was implicitly imported}4", + "%3 was not imported by this file}4", (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) WARNING(decl_from_hidden_module_warn,none, "cannot use %0 %1 %select{here|as property wrapper here|" @@ -2913,7 +2913,7 @@ WARNING(decl_from_hidden_module_warn,none, "in an extension with conditional conformances}2; " "%select{%3 has been imported as implementation-only|" "<>|<>|" - "%3 was implicitly imported}4", + "%3 was not imported by this file}4", (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) ERROR(conformance_from_implementation_only_module,none, "cannot use conformance of %0 to %1 %select{here|as property wrapper here|" @@ -5785,13 +5785,13 @@ ERROR(inlinable_decl_ref_from_hidden_module, "because %select{%3 was imported implementation-only|" "it is an SPI imported from %3|" "it is SPI|" - "%3 was implicitly imported}4", + "%3 was not imported by this file}4", (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) WARNING(inlinable_decl_ref_from_hidden_module_warn, none, "%0 %1 cannot be used in " FRAGILE_FUNC_KIND "2 " "because %select{<>|<>|<>|" - "%3 was implicitly imported}4" + "%3 was not imported by this file}4" "; this is an error in Swift 6", (DescriptiveDeclKind, DeclName, unsigned, Identifier, unsigned)) diff --git a/test/Sema/implicit-import-in-inlinable-code.swift b/test/Sema/implicit-import-in-inlinable-code.swift index 746cef88d96..06b6fb977e9 100644 --- a/test/Sema/implicit-import-in-inlinable-code.swift +++ b/test/Sema/implicit-import-in-inlinable-code.swift @@ -36,7 +36,7 @@ import libA @inlinable public func bar() { let a = ImportedType() - a.implicitlyImportedMethod() // expected-warning {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was implicitly imported; this is an error in Swift 6}} + a.implicitlyImportedMethod() // expected-warning {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was not imported by this file; this is an error in Swift 6}} // Expected implicit imports are still fine a.localModuleMethod() @@ -48,7 +48,7 @@ import libA @inlinable public func bar() { let a = ImportedType() - a.implicitlyImportedMethod() // expected-error {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was implicitly imported}} + a.implicitlyImportedMethod() // expected-error {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was not imported by this file}} // Expected implicit imports are still fine a.localModuleMethod() @@ -59,7 +59,7 @@ import libA @inlinable public func bar() { let a = ImportedType() - a.implicitlyImportedMethod() // expected-error {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was implicitly imported}} + a.implicitlyImportedMethod() // expected-error {{instance method 'implicitlyImportedMethod()' cannot be used in an '@inlinable' function because 'libB' was not imported by this file}} // Expected implicit imports are still fine a.localModuleMethod() From e7b1434ed2ea1512e290f8a7bd0908776384fee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Thu, 30 Jun 2022 11:17:37 -0700 Subject: [PATCH 6/7] [SwiftCompilerSources] Add missing import --- SwiftCompilerSources/Sources/Basic/SourceLoc.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SwiftCompilerSources/Sources/Basic/SourceLoc.swift b/SwiftCompilerSources/Sources/Basic/SourceLoc.swift index 08426f512ec..796813aad83 100644 --- a/SwiftCompilerSources/Sources/Basic/SourceLoc.swift +++ b/SwiftCompilerSources/Sources/Basic/SourceLoc.swift @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +import ASTBridging + public struct SourceLoc { /// Points into a source file. let locationInFile: UnsafePointer From a89b71d64a110dc9311931e23a3bf24f458c3af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Laferri=C3=A8re?= Date: Fri, 1 Jul 2022 07:33:05 -0700 Subject: [PATCH 7/7] [Sema] Skip decls without a owning module in workaround for dupe definitions The test swift-class-instantiation-module-interface triggered crashes in this logic because some decls don't have a owning module. It appears to be the synthesized templates that are at cause here. --- lib/Sema/TypeCheckAccess.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index c6cc63c0ec7..f3595e58227 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -1540,9 +1540,12 @@ swift::getDisallowedOriginKind(const Decl *decl, continue; } } + auto owningModule = redecl->getOwningModule(); + if (!owningModule) + continue; auto moduleWrapper = decl->getASTContext().getClangModuleLoader()->getWrapperForModule( - redecl->getOwningModule()); + owningModule); auto visibleAccessPath = find_if(sfImportedModules, [&moduleWrapper](auto importedModule) { return importedModule.importedModule == moduleWrapper ||