Wait, empty subscripts are legal?

Continuing the discussion from SE-0287: Extend implicit member syntax to cover chains of member references:

Saw this in example code from the proposal document referenced in the original thread:

struct Foo {
    static var foo = Foo()
    
    var anotherFoo: Foo { Foo() }
    func getFoo() -> Foo { Foo() }
    var optionalFoo: Foo? { Foo() }
    var fooFunc: () -> Foo { { Foo() } }
    var optionalFooFunc: () -> Foo? { { Foo() } }
    var fooFuncOptional: (() -> Foo)? { { Foo() } }
    subscript() -> Foo { Foo() }
}

//...

let _: Foo = .foo[]

I've read over the language grammar part of the Swift PL book several times. The production rules made it seem that, while declaring a subscript method with zero parameters was legal, calling a subscript with zero arguments was not legal. Have I been misinterpreting the SPL the whole time? Or has the grammar changed at some point to allow this?!

(The example worked for me on Xcode 12 beta 4 on Big Sur public beta.)

2 Likes

Heh, although I wrote that example into the proposal several months ago, I had since forgotten that it was actually legal syntax, so I had to go back and check I didn't make a mistake when I saw this post!

FWIW, I agree with your analysis of the Language Reference—subscript calls appear to require at least one argument based on the grammar.

In general I wouldn't take the grammar as an authoritative reference about what is and isn't allowed. Small omissions occasionally crop up as the language evolves (e.g., AFAICT there's nothing that allows compound names like foo(bar:baz:) to appear in primary-expression position). I wish there were a way to submit PRs for TSPL. :disappointed:

2 Likes
Offtopic

I wish the lexer was code-gen'd from the grammar rules (or the other way around, I suppose) so that stuff like this literally couldn't happen. "One source of truth", and all that.

3 Likes

I used to use this as a hack, years before we got callAsFunction.

Nowadays, it's probably nearly useless, but you'll see it crop up more as an autogenerated-by-default-argument overload as subscripts gain popularity.