about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-05-21 09:02:50 -0700
committerAlex Crichton <alex@alexcrichton.com>2018-05-21 09:35:15 -0700
commit3b8f791bf60c0e77ec713356e841c836eb6a55fb (patch)
tree4922eff2c78843099e65dfa2a0f3f5f5336c7929
parent6e6a4b1957e2407563f3c9005504f95138ffe28f (diff)
downloadrust-3b8f791bf60c0e77ec713356e841c836eb6a55fb.tar.gz
rust-3b8f791bf60c0e77ec713356e841c836eb6a55fb.zip
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
-rw-r--r--src/libsyntax/parse/token.rs9
-rw-r--r--src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs35
-rw-r--r--src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs22
3 files changed, 65 insertions, 1 deletions
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 5575614a4d4..06af21b3747 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -22,6 +22,7 @@ use serialize::{Decodable, Decoder, Encodable, Encoder};
 use symbol::keywords;
 use syntax::parse::parse_stream_from_source_str;
 use syntax_pos::{self, Span, FileName};
+use syntax_pos::symbol::{self, Symbol};
 use tokenstream::{TokenStream, TokenTree};
 use tokenstream;
 
@@ -478,7 +479,13 @@ impl Token {
                 _ => return None,
             },
             SingleQuote => match joint {
-                Ident(ident, false) => Lifetime(ident),
+                Ident(ident, false) => {
+                    let name = Symbol::intern(&format!("'{}", ident));
+                    Lifetime(symbol::Ident {
+                        name,
+                        span: ident.span,
+                    })
+                }
                 _ => return None,
             },
 
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs
new file mode 100644
index 00000000000..e288050a928
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/gen-lifetime-token.rs
@@ -0,0 +1,35 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![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());
+    ret.into_iter().collect()
+}
diff --git a/src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs b/src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs
new file mode 100644
index 00000000000..539e3aa8ecb
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/gen-lifetime-token.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:gen-lifetime-token.rs
+
+#![feature(proc_macro)]
+
+extern crate gen_lifetime_token as bar;
+
+bar::bar!();
+
+fn main() {
+    let x: &'static i32 = FOO;
+    assert_eq!(*x, 1);
+}