Skip to content

Commit c1d350a

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 1c53ef5 commit c1d350a

18 files changed

+62
-15
lines changed

CHANGELOG.md

+4
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

+1-1
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

+1-1
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

+1-1
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

+1-1
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

-1
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

+1-1
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

+1-1
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

+1-1
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

+10-2
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
import enum TSCUtility.Diagnostics
@@ -431,10 +431,18 @@ public final class ManifestLoader: ManifestLoaderProtocol {
431431
callbackQueue: DispatchQueue,
432432
completion: @escaping (Result<EvaluationResult, Error>) -> Void
433433
) throws {
434+
let manifestPreamble: ByteString
435+
switch toolsVersion {
436+
case .vNext:
437+
manifestPreamble = ByteString()
438+
default:
439+
manifestPreamble = ByteString("import Foundation\n")
440+
}
441+
434442
do {
435443
try withTemporaryDirectory { tempDir, cleanupTempDir in
436444
let manifestTempFilePath = tempDir.appending(component: "manifest.swift")
437-
try localFileSystem.writeFileContents(manifestTempFilePath, bytes: ByteString(manifestContents))
445+
try localFileSystem.writeFileContents(manifestTempFilePath, bytes: ByteString(manifestPreamble.contents + manifestContents))
438446

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

Sources/PackageLoading/ModuleMapGenerator.swift

+1-1
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

+1-1
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

+1-1
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

+1-1
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

+1
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 Sources/PackageModel/IdentityResolver.swift

-1
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

+16
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

+20
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
}

0 commit comments

Comments
 (0)