[swift-dev] Why doesn't CaptureListExpr hold a ClosureExpr?

John McCall rjmccall at apple.com
Wed Feb 8 00:19:47 CST 2017


> On Feb 8, 2017, at 12:33 AM, Slava Pestov <spestov at apple.com> wrote:
>> On Feb 7, 2017, at 9:30 PM, Jacob Bandes-Storch <jtbandes at gmail.com <mailto:jtbandes at gmail.com>> wrote:
>> 
>> Thanks to the magic of git blame:
>> 
>>   https://github.com/apple/swift/commit/f3ed7e93e142b802171bfe0dd08b88aa0d8b320b <https://github.com/apple/swift/commit/f3ed7e93e142b802171bfe0dd08b88aa0d8b320b>
>> 
>> 
>> > Unless you think there’s something to be gained, I’m not sure it’s worth it…
>> 
>> I was going for idiot-proof-ness of the AST types. I'd never heard of CaptureListExpr before and would've just assumed it was part of ClosureExpr. But it looks like the change was pretty intentional. (Maybe someone can share what rdar://19146761 <rdar://19146761> was?)
> 
> "This crashes the compiler, we’re not setting up declcontext’s right:
> 
> func f(a : () -> ()) {}
> 
> class C {
>   var i = 42
> 
>   func g() {
>     f({ [myI = {i}] in () })
>   }
> }"

Well that certainly doesn't seem like a good enough reason to complicate the expression.

...are we really emitting this as a let-binding in the outer function that we just capture normally?  Er, alright, I guess it works.

John.

> 
>> 
>> On Tue, Feb 7, 2017 at 9:27 PM, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
>>> On Feb 8, 2017, at 12:18 AM, Jacob Bandes-Storch via swift-dev <swift-dev at swift.org <mailto:swift-dev at swift.org>> wrote:
>>> I don't think it would be a very big parser change to invert the relationship. Maybe I'll try it out and put up another PR.
>>> 
>>> On the other hand, noticed the header comment says:
>>> 
>>> /// ...Because the capture list is evaluated outside of the closure, this
>>> /// CaptureList wraps the ClosureExpr.  The dynamic semantics are that evaluates
>>> /// the variable bindings from the capture list, then evaluates the
>>> /// subexpression (the closure itself) and returns the result.
>> 
>> I think the original representation just made the captures part of the ClosureExpr, and IIRC Chris changed it to this intentionally.  I don't remember why; maybe it was causing problems for some tooling that wanted to walk the expression tree and find uses of the variable?  It's certainly kindof weird for IRGen.
>> 
>> John.
>> 
>>> 
>>> 🤷‍
>>> 
>>> On Tue, Feb 7, 2017 at 9:10 PM, Slava Pestov <spestov at apple.com <mailto:spestov at apple.com>> wrote:
>>> 
>>>> On Feb 7, 2017, at 9:09 PM, Jacob Bandes-Storch <jtbandes at gmail.com <mailto:jtbandes at gmail.com>> wrote:
>>>> 
>>>> PR'd:  https://github.com/apple/swift/pull/7326 <https://github.com/apple/swift/pull/7326>
>>>> 
>>>> Although I would also ask: why is CaptureListExpr a parent of ClosureExpr and not a child?
>>> 
>>> I think it’s kind of arbitrary. You could also argue that they should be one and the same AST node. I think right now it’s just a property of how the parser works, the capture list comes first, before the closure body?
>>> 
>>> Slava
>>> 
>>>> 
>>>> Jacob
>>>> 
>>>> On Tue, Feb 7, 2017 at 7:56 PM, Slava Pestov <spestov at apple.com <mailto:spestov at apple.com>> wrote:
>>>> 
>>>>> On Feb 7, 2017, at 7:30 PM, Jacob Bandes-Storch via swift-dev <swift-dev at swift.org <mailto:swift-dev at swift.org>> wrote:
>>>>> 
>>>>> I just learned about CaptureListExpr when working on some diagnostics. Is there a particular reason that its member "closureBody" is an Expr* and not a ClosureExpr*? There seems to be only one place it's built <https://github.com/apple/swift/blob/1e46f13184d7256c991b2ba9424af9efe3cd860f/lib/Parse/ParseExpr.cpp#L2425>, and the body is always a ClosureExpr.
>>>>> 
>>>>> I can see one minor place <https://github.com/apple/swift/blob/1e46f13184d7256c991b2ba9424af9efe3cd860f/lib/AST/ASTWalker.cpp#L663-L665> where it might be less convenient to have a ClosureExpr, but otherwise there doesn't seem to be much of a reason to keep it generalized to Expr*.
>>>> 
>>>> Since autoclosures cannot have capture lists, I think the change you’re suggesting makes sense.
>>>> 
>>>> Slava
>>>> 
>>>>> 
>>>>> Jacob
>>>>> _______________________________________________
>>>>> swift-dev mailing list
>>>>> swift-dev at swift.org <mailto:swift-dev at swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-dev <https://lists.swift.org/mailman/listinfo/swift-dev>
>>>> 
>>>> 
>>> 
>>> 
>>> _______________________________________________
>>> swift-dev mailing list
>>> swift-dev at swift.org <mailto:swift-dev at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-dev <https://lists.swift.org/mailman/listinfo/swift-dev>
>> 
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20170208/19181cfb/attachment-0001.html>


More information about the swift-dev mailing list