SE-0269, string interpolations, and @autoclosure

My work to type-check interpolations via conjunctions to improve code completion ([WIP] Migrate the remaining completion kinds to solver-based + rework type-checking of string interpolations by ahoppen · Pull Request #63717 · apple/swift · GitHub) uncovered a hole in self capture checking.

Consider the following example:

func capture<T>(_: @escaping @autoclosure () -> T) {} 

class Test { var value: Int = 0 func test() { 
  capture(value) } 
}

Because Test is a reference type we don't actually allow value to be used without explicit self. in an escaping autoclosure:

error: reference to property 'value' in closure requires explicit use of 'self' to make capture semantics explicit
  capture(value) }
          ^
note: reference 'self.' explicitly
  capture(value) }
          ^
          self.

But if I wrap value in string interpolation like this:

capture("\(value)")

Expression type-checks successfully.

This is due to the fact that string interpolations are currently type-checked separately from context (just like multi-statement closured used to be) which means that MiscDiagnostics doesn't see synthesized "AutoClosureExpr" that wraps TapExpr.

Type-checking interpolations together with the context would actually result in an error just like capture(value) does which is a source compatibility regression.

So the question I want to raise here is whether this is an acceptable break, or I'd need to run a proposal clarification through evolution?

6 Likes

/cc @Jumhyn

It seems like the most conservative answer would be to start warning ”now” and error in Swift 6 mode. (Assuming the code generation is correct, that is.)

5 Likes

I’d say this is a clear bug and it shouldn’t require an evolution proposal to fix. However, I suspect examples of this source break will be relatively common in the wild, which means we probably need to do as Jordan says and make it a warning in Swift 5 mode.

5 Likes

The Language Steering Group talked about this, and we agree that this should be treated as a bug that should be fixed as aggressively as possible given our source-compatibility constraints.

2 Likes

I think it should be possible to downgrade to warning until Swift 6.

2 Likes

You should do a source-compatibility investigation, and if the impact appears to be minimal, you have the LSG's blessing to pursue doing it as an error if you'd like. But it would also be fine to skip that and just do it as a warning.

4 Likes

Limited investigation via source compat suite didn't turn up anything but I'll keep checking!

4 Likes