Skip to content

Commit c810bd7

Browse files
committed
Remove implicit availability of Foundation from future manifest versions
This changes all imports of `Foundation` in the `PackageDescription` module to be implementation-only, making it so that it needs to be explicitly imported if being used. To avoid breaking existing packages, we inject an explicit import into manifests with tools-version 5.7 or earlier. In the next tools-version, `Foundation` will no longer be implicitly available. rdar://92879696
1 parent 18da7e0 commit c810bd7

19 files changed

+64
-16
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ Note: This is in reverse chronological order, so newer entries are added to the
33
Swift 5.8
44
-----------
55

6+
* [#5874]
7+
8+
In packages using tools version 5.8 or later, Foundation is no longer implicitly imported into package manifests. If Foundation APIs are used, the module needs to be imported explicitly.
9+
610
* [#5728]
711

812
In packages that specify resources using tools version 5.8 or later, the generated resource bundle accessor will import `Foundation.Bundle` for its own implementation only. _Clients_ of such packages therefore no longer silently import `Foundation`, preventing inadvertent use of Foundation extensions to standard library APIs, which helps to avoid unexpected code size increases.

Sources/PackageDescription/PackageDependency.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import Foundation
13+
@_implementationOnly import Foundation
1414

1515
// MARK: - file system
1616

Sources/PackageDescription/PackageDescription.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
@_implementationOnly import ucrt
1919
@_implementationOnly import struct WinSDK.HANDLE
2020
#endif
21-
import Foundation
21+
@_implementationOnly import Foundation
2222

2323
/// The configuration of a Swift package.
2424
///

Sources/PackageDescription/PackageDescriptionSerialization.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import Foundation
13+
@_implementationOnly import Foundation
1414
#if canImport(Glibc)
1515
@_implementationOnly import Glibc
1616
#elseif canImport(Darwin)

Sources/PackageDescription/Target.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import Foundation
13+
@_implementationOnly import Foundation
1414

1515
/// The basic building block of a Swift package.
1616
///

Sources/PackageLoading/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
add_library(PackageLoading
1010
ContextModel.swift
1111
Diagnostics.swift
12-
IdentityResolver.swift
1312
ManifestLoader.swift
1413
ManifestLoader+Validation.swift
1514
ModuleMapGenerator.swift

Sources/PackageLoading/ContextModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import Foundation
13+
@_implementationOnly import Foundation
1414

1515
struct ContextModel {
1616
let packageDirectory : String

Sources/PackageLoading/ManifestJSONParser.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14-
import Foundation
14+
@_implementationOnly import Foundation
1515
import PackageModel
1616
import TSCBasic
1717

Sources/PackageLoading/ManifestLoader+Validation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14-
import Foundation
14+
@_implementationOnly import Foundation
1515
import PackageModel
1616
import TSCBasic
1717

Sources/PackageLoading/ManifestLoader.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14-
import Foundation
14+
import Dispatch
15+
@_implementationOnly import Foundation
1516
import PackageModel
1617
import TSCBasic
1718
import enum TSCUtility.Diagnostics
@@ -435,10 +436,18 @@ public final class ManifestLoader: ManifestLoaderProtocol {
435436
callbackQueue: DispatchQueue,
436437
completion: @escaping (Result<EvaluationResult, Error>) -> Void
437438
) throws {
439+
let manifestPreamble: ByteString
440+
switch toolsVersion {
441+
case .vNext:
442+
manifestPreamble = ByteString()
443+
default:
444+
manifestPreamble = ByteString("import Foundation\n")
445+
}
446+
438447
do {
439448
try withTemporaryDirectory { tempDir, cleanupTempDir in
440449
let manifestTempFilePath = tempDir.appending(component: "manifest.swift")
441-
try localFileSystem.writeFileContents(manifestTempFilePath, bytes: ByteString(manifestContents))
450+
try localFileSystem.writeFileContents(manifestTempFilePath, bytes: ByteString(manifestPreamble.contents + manifestContents))
442451

443452
let vfsOverlayTempFilePath = tempDir.appending(component: "vfs.yaml")
444453
try VFSOverlay(roots: [

Sources/PackageLoading/ModuleMapGenerator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14-
import Foundation
14+
@_implementationOnly import Foundation
1515
import PackageModel
1616
import TSCBasic
1717

Sources/PackageLoading/PkgConfig.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14-
import Foundation
14+
@_implementationOnly import Foundation
1515
import TSCBasic
1616

1717
/// Information on an individual `pkg-config` supported package.

Sources/PackageLoading/TargetSourcesBuilder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14-
import Foundation
14+
@_implementationOnly import Foundation
1515
import PackageModel
1616
import TSCBasic
1717

Sources/PackageLoading/ToolsVersionParser.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14-
import Foundation
14+
@_implementationOnly import Foundation
1515
import PackageModel
1616
import TSCBasic
1717

Sources/PackageModel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ add_library(PackageModel
1313
BuildSettings.swift
1414
Destination.swift
1515
Diagnostics.swift
16+
IdentityResolver.swift
1617
Manifest.swift
1718
Manifest/PackageConditionDescription.swift
1819
Manifest/PackageDependencyDescription.swift

Sources/PackageLoading/IdentityResolver.swift renamed to Sources/PackageModel/IdentityResolver.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Foundation
14-
import PackageModel
1514
import TSCBasic
1615

1716
// TODO: refactor this when adding registry support

Tests/PackageLoadingTests/PD_5_7_LoadingTests .swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ class PackageDescription5_7LoadingTests: PackageDescriptionLoadingTests {
2222
.v5_7
2323
}
2424

25+
func testImplicitFoundationImportWorks() throws {
26+
let content = """
27+
import PackageDescription
28+
29+
_ = FileManager.default
30+
31+
let package = Package(name: "MyPackage")
32+
"""
33+
34+
let observability = ObservabilitySystem.makeForTesting()
35+
let (manifest, validationDiagnostics) = try loadAndValidateManifest(content, observabilityScope: observability.topScope)
36+
XCTAssertNoDiagnostics(observability.diagnostics)
37+
XCTAssertNoDiagnostics(validationDiagnostics)
38+
XCTAssertEqual(manifest.displayName, "MyPackage")
39+
}
40+
2541
func testRegistryDependencies() throws {
2642
let content = """
2743
import PackageDescription

Tests/PackageLoadingTests/PD_Next_LoadingTests.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14+
import PackageLoading
1415
import PackageModel
1516
import SPMTestSupport
1617
import XCTest
@@ -19,4 +20,23 @@ class PackageDescriptionNextLoadingTests: PackageDescriptionLoadingTests {
1920
override var toolsVersion: ToolsVersion {
2021
.vNext
2122
}
23+
24+
func testImplicitFoundationImportFails() throws {
25+
let content = """
26+
import PackageDescription
27+
28+
_ = FileManager.default
29+
30+
let package = Package(name: "MyPackage")
31+
"""
32+
33+
let observability = ObservabilitySystem.makeForTesting()
34+
XCTAssertThrowsError(try loadAndValidateManifest(content, observabilityScope: observability.topScope), "expected error") {
35+
if case ManifestParseError.invalidManifestFormat(let error, _) = $0 {
36+
XCTAssertMatch(error, .contains("cannot find 'FileManager' in scope"))
37+
} else {
38+
XCTFail("unexpected error: \($0)")
39+
}
40+
}
41+
}
2242
}

Tests/WorkspaceTests/WorkspaceTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ final class WorkspaceTests: XCTestCase {
215215
XCTAssert(rootManifests.count == 0, "\(rootManifests)")
216216

217217
testDiagnostics(observability.diagnostics) { result in
218-
let diagnostic = result.check(diagnostic: .prefix("invalid manifest\n\(path.appending(components: "MyPkg", "Package.swift")):3:8: error: An error in MyPkg"), severity: .error)
218+
let diagnostic = result.check(diagnostic: .prefix("invalid manifest\n\(path.appending(components: "MyPkg", "Package.swift")):4:8: error: An error in MyPkg"), severity: .error)
219219
XCTAssertEqual(diagnostic?.metadata?.packageIdentity, .init(path: pkgDir))
220220
XCTAssertEqual(diagnostic?.metadata?.packageKind, .root(pkgDir))
221221
}

0 commit comments

Comments
 (0)