Source Location in Literals and Result Builders

One issue I've come across recently is the fact that you cannot access the source location of the literal triggering a call to ExpressibleByFooLiteral, as init(fooLiteral value: Foo, file: StaticString = #file) would fail to fulfill the protocol requirement. There was a pitch quite some time ago to allow functions with default arguments to satisfy protocol requirements, but not much seems to have happened as a result. Result builders might have a similar problem, as it seems one cannot write static func buildExpression(..., file: StaticString = #file), though since this particular method participates on overload resolution it may just work.

So, a couple questions:

  1. Will static func buildExpression(..., file: StaticString = #file) work with result builders?
  2. Do folks have any opinions on the more general solution of allowing functions with default parameters to satisfy protocol requirements? How hard would this be to implement (I haven't contributed functionality to Swift yet, but could put some time in)?
  3. Would this be simpler to solve this only for the narrow case of "magic" default arguments like #file? A very conservative rule could be "if there is no exact match for a protocol function requirement, and exactly one function exists that would match in the presence of default arguments, and all of those default arguments are #magic, it can fulfill the requirement."
  4. An even simpler solution could be to introduce a new function attribute @transparentSourceLocation (pardon the naming), which would effectively treat the entire function body as though it was at the source location of the caller (This would also enable easier propagation of these values). This way, one could write:
init(_ value: String, file: StaticString = #file) { }
@transparentSourceLocation
init(stringLiteral value: Value) {
  self.init(value)
}

It should already, yeah (unless I'm mistaken...). The various build* functions aren't modeled via protocol requirements so it's a bit more permissive as to what is allowed. @beccadax wrote a nifty result builder which uses #file and #line to dump information about the builder transform.

This has definitely been discussed before. It has a mention in @suyashsrijan's Witness Matching Mini-manifesto, though I'm not sure if there's been any recent developments on that front.

1 Like