00:01
<Justin Ridgewell>
There’s a transfer template
20:56
<shu>
YieldExpression and AwaitExpressions are disallowed in the Initializer of FieldDefinitions, right? where is that checked for? i think i'm missing something
20:56
<shu>
the grammar is passing along [?Yield, ?Await] and i don't see a special Early Error for it
21:10
<bakkot>
hmm
21:10
<bakkot>
yeah it should probably not be passed through to the rhs
21:10
<bakkot>
at least for non-static fields; not sure about static
21:59
<shu>
implementations don't accept either await or yield in both member and static AFAICT
22:18
<Richard Gibson>

heh, JSC allows it

$ eshost -h JavaScriptCore -sx '
  const iter = (function*(){ return (class { static foo = yield }).foo; })(); 
  iter.next();
  print(JSON.stringify(iter.next(42)));
'
#### JavaScriptCore
{"done":true}
22:19
<shu>
sick
22:19
<shu>
does it allow it for member fields?
22:19
<Richard Gibson>

yes:

eshost -h JavaScriptCore -sx '
  const iter = (function*(){ return (new class { foo = yield }).foo; })();
  iter.next();
  print(JSON.stringify(iter.next(42)));
'
#### JavaScriptCore
{"done":true}
22:19
<shu>
that's cursed
22:23
<kriskowal>
I really want to say I have production code that uses this behavior to detect JSC specifically.
22:28
<bakkot>
mm... allows it syntatically but doesn't appear to actually hit the yield
22:28
<Richard Gibson>
I know, right?
22:28
<bakkot>
the first iter.next() is already done: true
22:29
<kriskowal>
Aye, one would expect {value: 42, done: true} if it got into the class.
22:29
<kriskowal>
Very strange.
22:32
<shu>
classes are haunted
22:32
<shu>
i'll file an issue
22:32
<TabAtkins>
[loads pistol, climbs back in the compiler]
22:33
<bakkot>
there is no imaginable trace which prints x and z but not y here
22:37
<TabAtkins>
and yet
22:47
<shu>
and why is class static blocks +Await?
22:53
<rbuckton>
To treat await as a keyword and then ban it.
22:53
<bakkot>
that one does have an explicit error I am almost certain
22:53
<Richard Gibson>

I do think the spec may be messed up here, because |PrimaryExpression| propagates [?Yield, ?Await] to |ClassExpression|, which propagates them to |FieldDefinition|, which propagates them to |Initializer|, which propagates them to |AssignmentExpression|, which can expand to |YieldExpression| with [+Yield] and to |AwaitExpression| with [+Await] (and likewise |StatementList| to |ClassDeclaration|). The engines that reject source like function* f(){ class C { static foo = yield }; } are treating the initializer as containing an identifier that is reserved in strict mode code, rather than as containing a yield expression. It seems that only JSC parses per spec, although in evaluation it acts like the above (and engine262 dies with an assertion failure):

$ eshost -h JavaScriptCore,engine262 -sx '
  print("START");
  const iter = (function* f(){ return (class C { static foo = yield }).foo; })();
  try {
    print(JSON.stringify(iter.next("A")));
    print(JSON.stringify(iter.next("B")));
  } catch (err) { print(err); }
'
#### engine262

AssertError: genContext.Generator !== undefined

#### JavaScriptCore
START
{"done":true}
{"done":true}
22:55
<bakkot>
you need to propagate the flags through to FieldDefinition because the LHS can be a computed property name and it does get those flags
22:55
<bakkot>
but it shouldn't go through to the Initializer
22:57
<Richard Gibson>
I agree
22:57
<bakkot>
that one does have an explicit error I am almost certain

yeah https://tc39.es/ecma262/multipage/ecmascript-language-functions-and-classes.html#sec-class-definitions-static-semantics-early-errors

It is a Syntax Error if |ClassStaticBlockStatementList| Contains await is true.

22:57
<shu>
oh good
22:58
<shu>
whew
22:58
<Richard Gibson>
but that's only in static { … } blocks
22:58
<bakkot>
right
23:02
<shu>
https://github.com/tc39/ecma262/issues/3333
23:06
<Justin Ridgewell>
I know we discussed this in plenary, I remember going though a bunch of trouble to fix this in Babel’s transform
23:06
<Justin Ridgewell>
Did we just get the spec text wrong?
23:06
<bakkot>
oh hey https://github.com/tc39/ecma262/issues/2437
23:07
<shu>
dang
23:07
<shu>
2021!!
23:07
<shu>
I know we discussed this in plenary, I remember going though a bunch of trouble to fix this in Babel’s transform
there is a possible behavior for static fields. did we have consensus to disallow suspends in static field initializers as well? i don't recall
23:08
<Justin Ridgewell>
I can’t remember if it we discussed instance or static or both