Skip to content

Commit 3b8f791

Browse files
committed
rustc: Fix procedural macros generating lifetime tokens
This commit fixes an accidental regression from #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 #50942
1 parent 6e6a4b1 commit 3b8f791

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

src/libsyntax/parse/token.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use serialize::{Decodable, Decoder, Encodable, Encoder};
2222
use symbol::keywords;
2323
use syntax::parse::parse_stream_from_source_str;
2424
use syntax_pos::{self, Span, FileName};
25+
use syntax_pos::symbol::{self, Symbol};
2526
use tokenstream::{TokenStream, TokenTree};
2627
use tokenstream;
2728

@@ -478,7 +479,13 @@ impl Token {
478479
_ => return None,
479480
},
480481
SingleQuote => match joint {
481-
Ident(ident, false) => Lifetime(ident),
482+
Ident(ident, false) => {
483+
let name = Symbol::intern(&format!("'{}", ident));
484+
Lifetime(symbol::Ident {
485+
name,
486+
span: ident.span,
487+
})
488+
}
482489
_ => return None,
483490
},
484491

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// no-prefer-dynamic
12+
13+
#![crate_type = "proc-macro"]
14+
#![feature(proc_macro)]
15+
16+
extern crate proc_macro;
17+
18+
use proc_macro::*;
19+
20+
#[proc_macro]
21+
pub fn bar(_input: TokenStream) -> TokenStream {
22+
let mut ret = Vec::<TokenTree>::new();
23+
ret.push(Ident::new("static", Span::call_site()).into());
24+
ret.push(Ident::new("FOO", Span::call_site()).into());
25+
ret.push(Punct::new(':', Spacing::Alone).into());
26+
ret.push(Punct::new('&', Spacing::Alone).into());
27+
ret.push(Punct::new('\'', Spacing::Joint).into());
28+
ret.push(Ident::new("static", Span::call_site()).into());
29+
ret.push(Ident::new("i32", Span::call_site()).into());
30+
ret.push(Punct::new('=', Spacing::Alone).into());
31+
ret.push(Punct::new('&', Spacing::Alone).into());
32+
ret.push(Literal::i32_unsuffixed(1).into());
33+
ret.push(Punct::new(';', Spacing::Alone).into());
34+
ret.into_iter().collect()
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:gen-lifetime-token.rs
12+
13+
#![feature(proc_macro)]
14+
15+
extern crate gen_lifetime_token as bar;
16+
17+
bar::bar!();
18+
19+
fn main() {
20+
let x: &'static i32 = FOO;
21+
assert_eq!(*x, 1);
22+
}

0 commit comments

Comments
 (0)