Skip to content

Commit 76668ce

Browse files
committed
Enable assertions in release builds
This overrides the standard `assert` function from the stdlib with a version also checks the condition in CI if a conditional compilation flag is passed.
1 parent f5da24b commit 76668ce

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ if ProcessInfo.processInfo.environment["SWIFT_BUILD_SCRIPT_ENVIRONMENT"] != nil
1212
.appendingPathComponent("utils")
1313
.appendingPathComponent("group.json")
1414
swiftSyntaxSwiftSettings = [
15+
.define("SWIFTSYNTAX_ENABLE_ASSERTIONS"),
1516
.unsafeFlags([
1617
"-Xfrontend", "-group-info-path",
1718
"-Xfrontend", groupFile.path,

Sources/SwiftSyntax/Assert.swift

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
/// How to choose `assert` vs. `precondition`:
14+
/// - Wherever possible, it is preferrable to emit a diagnostic instead of
15+
/// using `precondition`. This way the parser won't crash if the condition is
16+
/// violated.
17+
/// - If you think the diagnostic added above should never be emitted, it is
18+
/// fine to also emit an `assertionFailure` in debug builds to make it easier
19+
/// to debug the unexpected diagnostic.
20+
/// - If in doubt always use `precondition`
21+
/// - `assert` should only be used if checking the assertion has a non-trivial
22+
/// cost and provides little benefit in terms of safety in release builds.
23+
24+
// MARK: - Precondition
25+
26+
/// Behaves exactly like `Swift.precondition` but also prints the failure message in release builds.
27+
/// Remove once rdar://19671016 has been addressed.
28+
@_transparent
29+
public func precondition(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line) {
30+
if !_fastPath(condition()) {
31+
fatalError(message(), file: file, line: line)
32+
}
33+
}
34+
35+
/// Behaves exactly like `Swift.preconditionFailure` but also prints the failure message in release builds.
36+
/// Remove once rdar://19671016 has been addressed.
37+
@_transparent
38+
public func preconditionFailure(_ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line) -> Never {
39+
fatalError(message(), file: file, line: line)
40+
}
41+
42+
// MARK: - Assert
43+
44+
/// An assertion that is active in DEBUG builds, just like `Swift.assert` and
45+
/// additionally if assertions are explicitly requested by setting the
46+
/// `SWIFTSYNTAX_ENABLE_ASSERTIONS` conditional compilation flag.
47+
/// Use this instead of `precondition` in places where the assertion has a
48+
/// non-trivial cost but provides little value in release builds.
49+
@_transparent
50+
public func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line) {
51+
#if SWIFTSYNTAX_ENABLE_ASSERTIONS
52+
precondition(condition(), message(), file: file, line: line)
53+
#else
54+
Swift.assert(condition(), message(), file: file, line: line)
55+
#endif
56+
}
57+
58+
/// An assertion that is active in DEBUG builds, just like
59+
/// `Swift.assertionFailure` and additionally if assertions are explicitly
60+
/// requested by setting the `SWIFTSYNTAX_ENABLE_ASSERTIONS` conditional
61+
/// compilation flag.
62+
@_transparent
63+
public func assertionFailure(_ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line) {
64+
#if SWIFTSYNTAX_ENABLE_ASSERTIONS
65+
preconditionFailure(message(), file: file, line: line)
66+
#else
67+
Swift.assertionFailure(message(), file: file, line: line)
68+
#endif
69+
}

0 commit comments

Comments
 (0)