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

Fix grammar for variadic functions #781

Closed
wants to merge 2 commits into from
Closed

Conversation

First, variadic params can be named:

    extern "C" {
        fn f(_: *mut u8, _: ...);
    }

Second, variadic params can be followed by a comma

    extern "C" {
        fn f(_: *mut u8, ...,);
    }
@ehuss
Copy link
Contributor

ehuss commented Mar 13, 2020

Hm, I'm wondering if this was stabilized accidentally. This was added in rust-lang/rust#57760 (RFC 2137), see also rust-lang/rust#44930 and rust-lang/wg-grammar#45.

Is there any meaning to the identifier of a variadic parameter? Or is it just ignored? That should probably be documented.

(Or, if this was truely a mistake, maybe it should be reverted/fixed/made unstable?)

@matklad
Copy link
Member Author

matklad commented Mar 13, 2020

I don't know, I guess cc @Centril / @petrochenkov ?

But apparently people use this in the real world already, this was reported against rust-analyzer.

@Centril
Copy link
Contributor

Centril commented Mar 13, 2020

The function parameter grammar as implemented in rustc is as follows. I've invented new meta grammar notation here, but it should hopefully be understandable.

Let RN ("require name") be a function Edition -> Bool. Then the (higher order) grammar is:

FnParams<RN> = "(" head: FirstParam<RN> tail: { "," Param<RN> %% "," } ")" ;

FirstParam<RN> = SelfParam | Param<RN> ;
Param<RN> = CVariadicTy | AlwaysNamedParam | MaybeNamedParam<RN> ;

MaybeNamedParam<RN> if RN(edition(current_token)) = Pat ":" ParamTy ; // Named param.
MaybeNamedParam<RN> = ParamTy ; // Unnamed param.

// Ambiguous with ^-- but for precedence.
AlwaysNamedParam = NamedStart? Ident ":" ParamTy ;
NamedStart = NtPat | "&" | "&&" | "mut" ;

ParamTy = CVariadicTy | TyPlusAllowed ;
CVariadicTy = "..." ;

For:

  • function pointers, let RN = \_ -> False,
  • functions in traits, let RN = \edition -> edition > 2015,
  • otherwise, let RN = \_ -> True.

This is translated starting with parse_fn_params in the rustc parser.

Beyond this, AST validation imposes other semantic restrictions.

@Havvy
Copy link
Contributor

Havvy commented Jan 13, 2021

cc @ehuss did #927 do this

@ehuss
Copy link
Contributor

ehuss commented Jan 13, 2021

Ah, yes, this should now be resolved.

@ehuss ehuss closed this Jan 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants