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

Lifetimes in procedural macros aren't being parsed correctly #50942

Closed
alexcrichton opened this issue May 21, 2018 · 7 comments · Fixed by #50946
Closed

Lifetimes in procedural macros aren't being parsed correctly #50942

alexcrichton opened this issue May 21, 2018 · 7 comments · Fixed by #50946
Labels
A-macros-2.0 Area: Declarative macros 2.0 (#39412)

Comments

@alexcrichton
Copy link
Member

Given this procedural macro:

#![crate_type = "proc-macro"]
#![feature(proc_macro)]

extern crate proc_macro;

use proc_macro::*;

#[proc_macro]
pub fn bar(_input: TokenStream) -> TokenStream {
    let mut ret = Vec::<TokenTree>::new();
    ret.push(Ident::new("static", Span::call_site()).into());
    ret.push(Ident::new("FOO", Span::call_site()).into());
    ret.push(Punct::new(':', Spacing::Alone).into());
    ret.push(Punct::new('&', Spacing::Alone).into());
    ret.push(Punct::new('\'', Spacing::Joint).into());
    ret.push(Ident::new("static", Span::call_site()).into());
    ret.push(Ident::new("i32", Span::call_site()).into());
    ret.push(Punct::new('=', Spacing::Alone).into());
    ret.push(Punct::new('&', Spacing::Alone).into());
    ret.push(Literal::i32_unsuffixed(1).into());
    ret.push(Punct::new(';', Spacing::Alone).into());
    return ret.into_iter().collect()
}

and this invocation:

#![crate_type = "rlib"]
#![feature(proc_macro)]

extern crate bar;

bar::bar!();

we get:

$ rustc +nightly bar.rs
$ rustc +nightly foo.rs -L .
error: lifetimes cannot use keyword names
 --> foo.rs:6:1
  |
6 | bar::bar!();
  | ^^^^^^^^^^^^

error[E0261]: use of undeclared lifetime name `static`
 --> foo.rs:6:1
  |
6 | bar::bar!();
  | ^^^^^^^^^^^^ undeclared lifetime

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0261`.
@alexcrichton alexcrichton added the A-macros-2.0 Area: Declarative macros 2.0 (#39412) label May 21, 2018
@petrochenkov
Copy link
Contributor

Note the missing ' in "undeclared lifetime name static", that's why it's undeclared.

@petrochenkov
Copy link
Contributor

Oh crap, fn glue doesn't add ' to the identifier string.
My test with lifetimes in #50473 passed accidentally because all the lifetimes lost their 's so their names were still equal and resolution succeeded.

@petrochenkov
Copy link
Contributor

Sorry.

@alexcrichton
Copy link
Member Author

Aha that'd do it! You found it much faster than I did :)

And no worries! Would you like to send a PR? Or shall I?

@petrochenkov
Copy link
Contributor

It'll happen sooner if you do it.

@alexcrichton
Copy link
Member Author

Ok! I'll take care of this

alexcrichton added a commit to alexcrichton/rust that referenced this issue May 21, 2018
This commit fixes an accidental regression from rust-lang#50473 where lifetime tokens
produced by procedural macros ended up getting lost in translation in the
compiler and not actually producing parseable code. The issue lies in the fact
that a lifetime's `Ident` is prefixed with `'`. The `glue` implementation for
gluing joint tokens together forgot to take this into account so the lifetime
inside of `Ident` was missing the leading tick!

The `glue` implementation here is updated to create a new `Symbol` in these
situations to manufacture a new `Ident` with a leading tick to ensure it parses
correctly.

Closes rust-lang#50942
@alexcrichton
Copy link
Member Author

I've posted a fix for this at #50946

kennytm added a commit to kennytm/rust that referenced this issue May 22, 2018
…petrochenkov

rustc: Fix procedural macros generating lifetime tokens

This commit fixes an accidental regression from rust-lang#50473 where lifetime tokens
produced by procedural macros ended up getting lost in translation in the
compiler and not actually producing parseable code. The issue lies in the fact
that a lifetime's `Ident` is prefixed with `'`. The `glue` implementation for
gluing joint tokens together forgot to take this into account so the lifetime
inside of `Ident` was missing the leading tick!

The `glue` implementation here is updated to create a new `Symbol` in these
situations to manufacture a new `Ident` with a leading tick to ensure it parses
correctly.

Closes rust-lang#50942
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros-2.0 Area: Declarative macros 2.0 (#39412)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants