Civet icon indicating copy to clipboard operation
Civet copied to clipboard

Glob assignment of private fields fails

Open bbrk24 opened this issue 1 year ago • 4 comments
trafficstars

The following code attempts to incorrectly destructure this:

class Foo
  #x = 0
  #y = 0

  clone()
    return = new Foo
    return.value{#x,#y} = @
class Foo {
  #x = 0;
  #y = 0;

  clone() {
    let ret;
    ret = new Foo();
    ({ x: ret.#x, y: ret.#y } = this);
    return ret;
  }
}

I don't think it's possible to destructure private fields.

bbrk24 avatar Feb 09 '24 04:02 bbrk24

It looks like we'll need to do these manually. 😿

https://github.com/tc39/proposal-destructuring-private

STRd6 avatar Feb 14 '24 20:02 STRd6

Until then, we could rewrite this as follows:

return.value{#x,#y} = @
↓↓↓
({ x: ret.#x, y: ret.#y } = { x: this.#x, y: this.#y });

Of course, if we had something like return.value{x,#x} = this, we'd have to do some more renaming...

Maybe worth implementing a general form of the TC39 proposal-destructuring-private spec at the same time.

edemaine avatar Feb 17 '24 19:02 edemaine

We could always use quoted keys:

({ "#x": ret.#x, "#y": ret.#y } = { "#x": this.#x, "#y": this.#y });

I suppose it's still possible to collide with non-private fields but I don't imagine ret{#x,"#x"} = @ to be a very common situation...

bbrk24 avatar Feb 17 '24 21:02 bbrk24

I think we would instead do something like:

ret.#x = this.#x, ret.#y = this.#y;

Essentially pollyfilling without destructuring ourselves. We may need to consider what to do if there is an additional chained assignment but erroring in that case is probably fine.

STRd6 avatar Feb 17 '24 21:02 STRd6