Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

await should be a keyword in a non-async local function inside an async method #25448

Open
gafter opened this issue Mar 13, 2018 · 7 comments
Open
Assignees
Milestone

Comments

@gafter
Copy link
Member

gafter commented Mar 13, 2018

From the spec:

Inside of an async function, await cannot be used as an identifier

A non-async local function that is inside an async method is still "inside" of an async function, and therefore await should be a keyword.

But the parser currently treats await as an ordinary identifier there.

The parser appears to handle lambdas properly.

@Neme12
Copy link
Contributor

Neme12 commented Mar 13, 2018

Just a note about VB: there the spec says

Await is a reserved word if the immediately enclosing method or lambda expression in which it appears has an Async modifier

and the implementation matches that.
Was it intentional to have a different handling of this between C# & VB?

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Mar 13, 2018

The question is how to interpret this:

Inside of an async function, await cannot be used as an identifier

If i have:

async void M() {
     Func<Task> f = () => { /*here*/ };
}

in 'here' am i inside an async function? I don't personally think so. I think i'm "inside a non-async function". it seems 'strange' to me that the modifiers of a much outer function reach 'into' a deeper function. I agree 'inside' is vague and can be interpreted either way. But it doesn't seem sensible to me to take teh current parser interpretation. instead, each function scope is 'fresh', with its own modifiers defining how it should parse.

Note: this is also how TS/JS view the world. I can check other languages later tonight.

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Mar 13, 2018

My point is this: i don't want to argue the meaning of the current phrasing. I think it's pretty vague and confusing (what does 'inside' mean) and can be rightfully interpreted in multiple ways.. Instead, i would just things to be explicit in the spec, i.e.:

  1. if the immediately containing function-like thing has the 'async' modifier, 'await' cannot be used as an identifier. Or:
  2. if *any lexically containing function-like thing has the 'async' modifier, 'await' cannot be used as an identifier.

i.e. the spec should be clearer what it uses words like 'contained' and 'inside'.

--

Note: i would go with '1'. It seems far more expected and consistent. I'm also ok with '2'. But we should still make the text clear.

@CyrusNajmabadi
Copy link
Member

Finally, if we go with '1' or '2', i think it goes without saying that we should apply this consistently to all function-like things that can have an async-modifier. Methods/Lambdas/Anon-Methods/Local-Functions should all behave uniformly here :)

@gafter
Copy link
Member Author

gafter commented Mar 13, 2018

@CyrusNajmabadi I have no problem with the spec being clarified. The spec already uses the phrase "immediately enclosing" when it means that (unlike here).

@CyrusNajmabadi
Copy link
Member

Thanks. Sounds good to me!

1 similar comment
@CyrusNajmabadi
Copy link
Member

Thanks. Sounds good to me!

@jinujoseph jinujoseph modified the milestones: 16.0, 16.3 Jun 9, 2019
@jcouv jcouv modified the milestones: 16.3, Compiler.Next Jul 16, 2019
@jaredpar jaredpar modified the milestones: Compiler.Next, Backlog Sep 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants