[swift-evolution] [Pitch] Expose assert configuration functions in standard library

Brent Royal-Gordon brent at architechies.com
Wed Jun 1 00:21:15 CDT 2016

> My pitch: I want to promote these three helper functions to the standard library and remove their underscore prefixes.

These functions currently have implementations like this:

	public // @testable
	func _isDebugAssertConfiguration() -> Bool {
	  // The values for the assert_configuration call are:
	  // 0: Debug
	  // 1: Release
	  // 2: Fast
	  return Int32(Builtin.assert_configuration()) == 0

I think how this works is:

* @_transparent makes sure these functions are always inlined at the call site.
* Most things in the standard library are *also* @_transparent.
* Therefore, after both (or more!) inlinings happen, you get the `Builtin.assert_configuration()` of the code calling into the standard library.

Needless to say, this is *extremely* weird and magical, and I'm skeptical of the idea that we should expose it as a normal function call.

I think a better design which would accurately convey its magic is to add a type to the standard library:

	enum BuildKind: Int32 { case debug, release, unchecked }

(Note: the names in this could use some bikeshedding. Put that aside.)

And then add a `#buildKind` compiler substitution which is equivalent to:

	BuildKind(rawValue: Int32(Builtin.assert_configuration()))

Now you can surround your debug-only code with `#buildKind == .debug`. Or you can capture the *call site's* build kind with a default parameter:

	func log(_ message: String, level: LogLevel = .info, buildKind: BuildKind = #buildKind)

Even the standard library might be able to do this if it wanted to, allowing your code to enable or disable asserts based on whether your caller's code is in debug mode or not:

	func assert(@autoclosure condition: () -> Bool, @autoclosure _ message: () -> String = default, file: StaticString= #file, line: UInt = #line, buildKind: BuildKind = #buildKind)

(I wouldn't suggest that every stdlib member add such a default parameter; most should continue to rely on `@_transparent`. But I think that could be useful for calls like `assert()` and `precondition()`.

Brent Royal-Gordon

More information about the swift-evolution mailing list