From b94bc3677646de31938d07c9889f2e06334f2cfe Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Sat, 13 Dec 2025 11:33:11 -0500 Subject: [PATCH] Start adoption of `@section` and `@used`. This PR begins our migration to `@section` and `@used`. Because of a bug in the Swift compiler (https://github.com/swiftlang/swift/issues/85411), we still need to rely on an unsupported/experimental language feature (CompileTimeValuesPreview). When that bug is resolved, we can remove checks for CompileTimeValuesPreview and fully "activate" this new code path. Note that because of that bug, this PR does _not_ resolve #1371. --- Package.swift | 20 ++++++++++++++----- Sources/TestingMacros/ConditionMacro.swift | 4 ++-- .../TestingMacros/SuiteDeclarationMacro.swift | 4 ++-- .../Support/TestContentGeneration.swift | 18 ++++++++++++++++- .../TestingMacros/TestDeclarationMacro.swift | 4 ++-- .../TestDeclarationMacroTests.swift | 4 +++- Tests/TestingTests/DiscoveryTests.swift | 17 ++++++++++++++-- 7 files changed, 56 insertions(+), 15 deletions(-) diff --git a/Package.swift b/Package.swift index a82241527..d37754a1a 100644 --- a/Package.swift +++ b/Package.swift @@ -385,11 +385,6 @@ extension Array where Element == PackageDescription.SwiftSetting { .enableUpcomingFeature("MemberImportVisibility"), - // This setting is enabled in the package, but not in the toolchain build - // (via CMake). Enabling it is dependent on acceptance of the @section - // proposal via Swift Evolution. - .enableExperimentalFeature("SymbolLinkageMarkers"), - .enableUpcomingFeature("InferIsolatedConformances"), // When building as a package, the macro plugin always builds as an @@ -410,6 +405,21 @@ extension Array where Element == PackageDescription.SwiftSetting { .define("SWT_NO_LIBDISPATCH", .whenEmbedded()), ] +#if compiler(>=6.3) +#if !SWT_FIXED_85411 + // Work around https://github.com/swiftlang/swift/issues/85411 + result += [ + .enableExperimentalFeature("CompileTimeValuesPreview"), + ] +#endif +#else + // This setting is enabled in the package, but not in the toolchain build + // (via CMake). The @section attribute is formally supported in Swift 6.3. + result += [ + .enableExperimentalFeature("SymbolLinkageMarkers"), + ] +#endif + return result } diff --git a/Sources/TestingMacros/ConditionMacro.swift b/Sources/TestingMacros/ConditionMacro.swift index 6ba8ff124..2c3d16cbe 100644 --- a/Sources/TestingMacros/ConditionMacro.swift +++ b/Sources/TestingMacros/ConditionMacro.swift @@ -13,8 +13,8 @@ public import SwiftSyntax import SwiftSyntaxBuilder public import SwiftSyntaxMacros -#if !hasFeature(SymbolLinkageMarkers) && SWT_NO_LEGACY_TEST_DISCOVERY -#error("Platform-specific misconfiguration: either SymbolLinkageMarkers or legacy test discovery is required to expand #expect(processExitsWith:)") +#if !((compiler(>=6.3) && hasFeature(CompileTimeValuesPreview)) || hasFeature(SymbolLinkageMarkers)) && SWT_NO_LEGACY_TEST_DISCOVERY +#error("Platform-specific misconfiguration: either CompileTimeValuesPreview, SymbolLinkageMarkers, or legacy test discovery is required to expand #expect(processExitsWith:)") #endif /// A protocol containing the common implementation for the expansions of the diff --git a/Sources/TestingMacros/SuiteDeclarationMacro.swift b/Sources/TestingMacros/SuiteDeclarationMacro.swift index 4bee4c30f..80458c04f 100644 --- a/Sources/TestingMacros/SuiteDeclarationMacro.swift +++ b/Sources/TestingMacros/SuiteDeclarationMacro.swift @@ -13,8 +13,8 @@ public import SwiftSyntax import SwiftSyntaxBuilder public import SwiftSyntaxMacros -#if !hasFeature(SymbolLinkageMarkers) && SWT_NO_LEGACY_TEST_DISCOVERY -#error("Platform-specific misconfiguration: either SymbolLinkageMarkers or legacy test discovery is required to expand @Suite") +#if !((compiler(>=6.3) && hasFeature(CompileTimeValuesPreview)) || hasFeature(SymbolLinkageMarkers)) && SWT_NO_LEGACY_TEST_DISCOVERY +#error("Platform-specific misconfiguration: either CompileTimeValuesPreview, SymbolLinkageMarkers, or legacy test discovery is required to expand @Suite") #endif /// A type describing the expansion of the `@Suite` attribute macro. diff --git a/Sources/TestingMacros/Support/TestContentGeneration.swift b/Sources/TestingMacros/Support/TestContentGeneration.swift index 05214d1b8..90471cf8b 100644 --- a/Sources/TestingMacros/Support/TestContentGeneration.swift +++ b/Sources/TestingMacros/Support/TestContentGeneration.swift @@ -74,7 +74,23 @@ func makeTestContentRecordDecl(named name: TokenSyntax, in typeName: TypeSyntax? ) """ -#if hasFeature(SymbolLinkageMarkers) +#if compiler(>=6.3) && hasFeature(CompileTimeValuesPreview) + result = """ + #if compiler(>=6.3) && hasFeature(CompileTimeValuesPreview) + #if objectFormat(MachO) + @section("__DATA_CONST,__swift5_tests") + #elseif objectFormat(ELF) || objectFormat(Wasm) + @section("swift5_tests") + #elseif objectFormat(COFF) + @section(".sw5test$B") + #else + @Testing.__testing(warning: "Platform-specific implementation missing: object format unknown") + #endif + @used + #endif + \(result) + """ +#elseif hasFeature(SymbolLinkageMarkers) result = """ #if hasFeature(SymbolLinkageMarkers) #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS) diff --git a/Sources/TestingMacros/TestDeclarationMacro.swift b/Sources/TestingMacros/TestDeclarationMacro.swift index 8007c3aaf..77f4b1b5a 100644 --- a/Sources/TestingMacros/TestDeclarationMacro.swift +++ b/Sources/TestingMacros/TestDeclarationMacro.swift @@ -13,8 +13,8 @@ public import SwiftSyntax import SwiftSyntaxBuilder public import SwiftSyntaxMacros -#if !hasFeature(SymbolLinkageMarkers) && SWT_NO_LEGACY_TEST_DISCOVERY -#error("Platform-specific misconfiguration: either SymbolLinkageMarkers or legacy test discovery is required to expand @Test") +#if !((compiler(>=6.3) && hasFeature(CompileTimeValuesPreview)) || hasFeature(SymbolLinkageMarkers)) && SWT_NO_LEGACY_TEST_DISCOVERY +#error("Platform-specific misconfiguration: either CompileTimeValuesPreview, SymbolLinkageMarkers, or legacy test discovery is required to expand @Test") #endif /// A type describing the expansion of the `@Test` attribute macro. diff --git a/Tests/TestingMacrosTests/TestDeclarationMacroTests.swift b/Tests/TestingMacrosTests/TestDeclarationMacroTests.swift index aec6d2c10..226757733 100644 --- a/Tests/TestingMacrosTests/TestDeclarationMacroTests.swift +++ b/Tests/TestingMacrosTests/TestDeclarationMacroTests.swift @@ -472,7 +472,9 @@ struct TestDeclarationMacroTests { func differentFunctionTypes(input: String, expectedTypeName: String?, otherCode: String?) throws { let (output, _) = try parse(input) -#if hasFeature(SymbolLinkageMarkers) +#if compiler(>=6.3) && hasFeature(CompileTimeValuesPreview) + #expect(output.contains("@section")) +#elseif hasFeature(SymbolLinkageMarkers) #expect(output.contains("@_section")) #endif #if !SWT_NO_LEGACY_TEST_DISCOVERY diff --git a/Tests/TestingTests/DiscoveryTests.swift b/Tests/TestingTests/DiscoveryTests.swift index 24d2eecfa..42e5170f2 100644 --- a/Tests/TestingTests/DiscoveryTests.swift +++ b/Tests/TestingTests/DiscoveryTests.swift @@ -58,7 +58,7 @@ struct DiscoveryTests { } #endif -#if !SWT_NO_DYNAMIC_LINKING && hasFeature(SymbolLinkageMarkers) +#if !SWT_NO_DYNAMIC_LINKING && ((compiler(>=6.3) && hasFeature(CompileTimeValuesPreview)) || hasFeature(SymbolLinkageMarkers)) struct MyTestContent: DiscoverableAsTestContent { typealias TestContentAccessorHint = UInt32 @@ -80,6 +80,18 @@ struct DiscoveryTests { record.context } +#if compiler(>=6.3) && hasFeature(CompileTimeValuesPreview) +#if objectFormat(MachO) + @section("__DATA_CONST,__swift5_tests") +#elseif objectFormat(ELF) || objectFormat(Wasm) + @section("swift5_tests") +#elseif objectFormat(COFF) + @section(".sw5test$B") +#else + @__testing(warning: "Platform-specific implementation missing: object format unknown") +#endif + @used +#else #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS) @_section("__DATA_CONST,__swift5_tests") #elseif os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android) || os(WASI) @@ -90,6 +102,7 @@ struct DiscoveryTests { @__testing(warning: "Platform-specific implementation missing: test content section name unavailable") #endif @_used +#endif private static let record: __TestContentRecord = ( 0xABCD1234, 0, @@ -144,7 +157,7 @@ struct DiscoveryTests { } #endif -#if !SWT_NO_LEGACY_TEST_DISCOVERY && hasFeature(SymbolLinkageMarkers) +#if !SWT_NO_LEGACY_TEST_DISCOVERY && ((compiler(>=6.3) && hasFeature(CompileTimeValuesPreview)) || hasFeature(SymbolLinkageMarkers)) @Test("Legacy test discovery finds the same number of tests") func discoveredTestCount() async { let oldFlag = Environment.variable(named: "SWT_USE_LEGACY_TEST_DISCOVERY") defer {