Skip to content

Commit b72eaad

Browse files
committed
Add support for -disable-upcoming-feature and -disable-experimental-feature.
Synchronize Options.swift with swiftlang/swift#77662 and update the driver to pass all feature related flags down to the frontend together, preserving the order the flags were specified.
1 parent a5f4c3a commit b72eaad

File tree

5 files changed

+62
-8
lines changed

5 files changed

+62
-8
lines changed

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

+15-8
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ extension Driver {
5252
case computed
5353
}
5454

55+
func checkFrontendSupportsOptionIfNecessary(_ option: Option) throws {
56+
if parsedOptions.hasArgument(option) && !isFrontendArgSupported(option) {
57+
diagnosticEngine.emit(.error_unsupported_opt_for_frontend(option: option))
58+
throw ErrorDiagnostics.emitted
59+
}
60+
}
61+
5562
/// Add frontend options that are common to different frontend invocations.
5663
mutating func addCommonFrontendOptions(
5764
commandLine: inout [Job.ArgTemplate],
@@ -154,6 +161,9 @@ extension Driver {
154161
throw ErrorDiagnostics.emitted
155162
}
156163

164+
try checkFrontendSupportsOptionIfNecessary(.disableUpcomingFeature)
165+
try checkFrontendSupportsOptionIfNecessary(.disableExperimentalFeature)
166+
157167
// Handle the CPU and its preferences.
158168
try commandLine.appendLast(.targetCpu, from: &parsedOptions)
159169

@@ -275,14 +285,11 @@ extension Driver {
275285
if isFrontendArgSupported(.compilerAssertions) {
276286
try commandLine.appendLast(.compilerAssertions, from: &parsedOptions)
277287
}
278-
if isFrontendArgSupported(.enableExperimentalFeature) {
279-
try commandLine.appendAll(
280-
.enableExperimentalFeature, from: &parsedOptions)
281-
}
282-
if isFrontendArgSupported(.enableUpcomingFeature) {
283-
try commandLine.appendAll(
284-
.enableUpcomingFeature, from: &parsedOptions)
285-
}
288+
try commandLine.appendAll(.enableExperimentalFeature,
289+
.disableExperimentalFeature,
290+
.enableUpcomingFeature,
291+
.disableUpcomingFeature,
292+
from: &parsedOptions)
286293
try commandLine.appendAll(.moduleAlias, from: &parsedOptions)
287294
if isFrontendArgSupported(.enableBareSlashRegex) {
288295
try commandLine.appendLast(.enableBareSlashRegex, from: &parsedOptions)

Sources/SwiftDriver/Utilities/Diagnostics.swift

+4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ extension Diagnostic.Message {
3535
.error("unsupported argument '\(argument)' to option '\(option.spelling)'")
3636
}
3737

38+
static func error_unsupported_opt_for_frontend(option: Option) -> Diagnostic.Message {
39+
.error("frontend does not support option '\(option.spelling)'")
40+
}
41+
3842
static func error_option_requires_sanitizer(option: Option) -> Diagnostic.Message {
3943
.error("option '\(option.spelling)' requires a sanitizer to be enabled. Use -sanitize= to enable a sanitizer")
4044
}

Sources/SwiftOptions/Options.swift

+4
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ extension Option {
184184
public static let disableDynamicActorIsolation: Option = Option("-disable-dynamic-actor-isolation", .flag, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Disable dynamic actor isolation checks")
185185
public static let disableEmitGenericClassRoTList: Option = Option("-disable-emit-generic-class-ro_t-list", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable emission of a section with references to class_ro_t of generic class patterns")
186186
public static let disableExperimentalClangImporterDiagnostics: Option = Option("-disable-experimental-clang-importer-diagnostics", .flag, attributes: [.helpHidden, .frontend, .noDriver, .moduleInterface], helpText: "Disable experimental diagnostics when importing C, C++, and Objective-C libraries")
187+
public static let disableExperimentalFeature: Option = Option("-disable-experimental-feature", .separate, attributes: [.frontend, .moduleInterface], helpText: "Disable an experimental feature")
187188
public static let disableExperimentalLifetimeDependenceInference: Option = Option("-disable-experimental-lifetime-dependence-inference", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable experimental lifetime dependence inference")
188189
public static let disableExperimentalOpenedExistentialTypes: Option = Option("-disable-experimental-opened-existential-types", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable experimental support for implicitly opened existentials")
189190
public static let disableExperimentalParserRoundTrip: Option = Option("-disable-experimental-parser-round-trip", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable round trip through the new swift parser")
@@ -263,6 +264,7 @@ extension Option {
263264
public static let disableThrowsPrediction: Option = Option("-disable-throws-prediction", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disables optimization assumption that functions rarely throw errors.")
264265
public static let disableTypeLayouts: Option = Option("-disable-type-layout", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable type layout based lowering")
265266
public static let disableTypoCorrection: Option = Option("-disable-typo-correction", .flag, attributes: [.frontend, .noDriver], helpText: "Disable typo correction")
267+
public static let disableUpcomingFeature: Option = Option("-disable-upcoming-feature", .separate, attributes: [.frontend, .moduleInterface], helpText: "Disable a feature that will be introduced in an upcoming language version")
266268
public static let disableVerifyExclusivity: Option = Option("-disable-verify-exclusivity", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable verification of access markers used to enforce exclusivity.")
267269
public static let disallowForwardingDriver: Option = Option("-disallow-use-new-driver", .flag, helpText: "Disable using new swift-driver")
268270
public static let downgradeTypecheckInterfaceError: Option = Option("-downgrade-typecheck-interface-error", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Downgrade error to warning when typechecking emitted module interfaces")
@@ -1087,6 +1089,7 @@ extension Option {
10871089
Option.disableDynamicActorIsolation,
10881090
Option.disableEmitGenericClassRoTList,
10891091
Option.disableExperimentalClangImporterDiagnostics,
1092+
Option.disableExperimentalFeature,
10901093
Option.disableExperimentalLifetimeDependenceInference,
10911094
Option.disableExperimentalOpenedExistentialTypes,
10921095
Option.disableExperimentalParserRoundTrip,
@@ -1166,6 +1169,7 @@ extension Option {
11661169
Option.disableThrowsPrediction,
11671170
Option.disableTypeLayouts,
11681171
Option.disableTypoCorrection,
1172+
Option.disableUpcomingFeature,
11691173
Option.disableVerifyExclusivity,
11701174
Option.disallowForwardingDriver,
11711175
Option.downgradeTypecheckInterfaceError,

Tests/SwiftDriverTests/SwiftDriverTests.swift

+39
Original file line numberDiff line numberDiff line change
@@ -8295,6 +8295,45 @@ final class SwiftDriverTests: XCTestCase {
82958295
XCTAssertTrue(!jobs[0].commandLine.contains("-emit-irgen"))
82968296
}
82978297
}
8298+
8299+
func testEnableFeatures() throws {
8300+
do {
8301+
let featureArgs = [
8302+
"-enable-upcoming-feature", "MemberImportVisibility",
8303+
"-enable-experimental-feature", "ParserValidation",
8304+
"-enable-upcoming-feature", "ConcisePoundFile",
8305+
]
8306+
var driver = try Driver(args: ["swiftc", "file.swift"] + featureArgs)
8307+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
8308+
XCTAssertEqual(jobs.count, 2)
8309+
8310+
// Verify that the order of both upcoming and experimental features is preserved.
8311+
XCTAssertTrue(jobs[0].commandLine.contains(subsequence: featureArgs.map { Job.ArgTemplate.flag($0) }))
8312+
}
8313+
}
8314+
8315+
func testDisableFeatures() throws {
8316+
let driver = try Driver(args: ["swiftc", "foo.swift"])
8317+
guard driver.isFrontendArgSupported(.disableUpcomingFeature) else {
8318+
throw XCTSkip("Skipping: compiler does not support '-disable-upcoming-feature'")
8319+
}
8320+
8321+
do {
8322+
let featureArgs = [
8323+
"-enable-upcoming-feature", "MemberImportVisibility",
8324+
"-disable-upcoming-feature", "MemberImportVisibility",
8325+
"-disable-experimental-feature", "ParserValidation",
8326+
"-enable-experimental-feature", "ParserValidation",
8327+
]
8328+
8329+
var driver = try Driver(args: ["swiftc", "file.swift"] + featureArgs)
8330+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
8331+
XCTAssertEqual(jobs.count, 2)
8332+
8333+
// Verify that the order of both upcoming and experimental features is preserved.
8334+
XCTAssertTrue(jobs[0].commandLine.contains(subsequence: featureArgs.map { Job.ArgTemplate.flag($0) }))
8335+
}
8336+
}
82988337
}
82998338

83008339
func assertString(

Tests/TestUtilities/JobExtensions.swift

Whitespace-only changes.

0 commit comments

Comments
 (0)