Skip to content

Commit 71d4a86

Browse files
committed
Address review comments.
1 parent 1e32a3f commit 71d4a86

File tree

8 files changed

+172
-110
lines changed

8 files changed

+172
-110
lines changed

src/libproc_macro/lib.rs

Lines changed: 113 additions & 77 deletions
Large diffs are not rendered by default.

src/libproc_macro/quote.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99
// except according to those terms.
1010

1111
//! # Quasiquoter
12-
//! This file contains the implementation internals of the quasiquoter provided by `qquote!`.
12+
//! This file contains the implementation internals of the quasiquoter provided by `quote!`.
13+
14+
//! This quasiquoter uses macros 2.0 hygiene to reliably use items from `__rt`,
15+
//! including re-exported API `libsyntax`, to build a `syntax::tokenstream::TokenStream`
16+
//! and wrap it into a `proc_macro::TokenStream`.
1317
1418
use syntax::ast::Ident;
1519
use syntax::ext::base::{ExtCtxt, ProcMacro};
1620
use syntax::parse::token::{self, Token, Lit};
1721
use syntax::symbol::Symbol;
18-
use syntax::tokenstream::{Delimited, TokenTree, TokenStream};
22+
use syntax::tokenstream::{Delimited, TokenTree, TokenStream, TokenStreamBuilder};
1923
use syntax_pos::{DUMMY_SP, Span};
2024
use syntax_pos::hygiene::SyntaxContext;
2125

@@ -25,7 +29,7 @@ pub mod __rt {
2529
pub use syntax::ast::Ident;
2630
pub use syntax::parse::token;
2731
pub use syntax::symbol::Symbol;
28-
pub use syntax::tokenstream::{TokenStream, TokenTree, Delimited};
32+
pub use syntax::tokenstream::{TokenStream, TokenStreamBuilder, TokenTree, Delimited};
2933
pub use super::{ctxt, span};
3034

3135
pub fn unquote<T: Into<::TokenStream> + Clone>(tokens: &T) -> TokenStream {
@@ -41,7 +45,7 @@ pub fn span() -> Span {
4145
::Span::default().0
4246
}
4347

44-
trait Quote {
48+
pub trait Quote {
4549
fn quote(&self) -> TokenStream;
4650
}
4751

@@ -98,8 +102,8 @@ impl<T: Quote> Quote for Option<T> {
98102

99103
impl Quote for TokenStream {
100104
fn quote(&self) -> TokenStream {
101-
let mut builder = TokenStream::builder();
102-
builder.push(quote!(rt::TokenStream::builder()));
105+
let mut builder = TokenStreamBuilder::new();
106+
builder.push(quote!(rt::TokenStreamBuilder::new()));
103107

104108
let mut trees = self.trees();
105109
loop {

src/librustc_metadata/creader.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob};
1414
use locator::{self, CratePaths};
1515
use schema::{CrateRoot, Tracked};
1616

17-
use rustc::hir::def_id::{CrateNum, DefIndex};
17+
use rustc::hir::def_id::{CrateNum, DefIndex, CRATE_DEF_INDEX};
1818
use rustc::hir::svh::Svh;
1919
use rustc::middle::cstore::DepKind;
2020
use rustc::session::Session;
@@ -35,7 +35,7 @@ use std::path::PathBuf;
3535
use std::rc::Rc;
3636
use std::{cmp, fs};
3737

38-
use syntax::ast::{self, Ident};
38+
use syntax::ast;
3939
use syntax::abi::Abi;
4040
use syntax::attr;
4141
use syntax::ext::base::SyntaxExtension;
@@ -1238,7 +1238,7 @@ fn proc_macro_def_path_table(proc_macros: &[(ast::Name, Rc<SyntaxExtension>)]) -
12381238
let key = DefKey {
12391239
parent: Some(CRATE_DEF_INDEX),
12401240
disambiguated_data: DisambiguatedDefPathData {
1241-
data: DefPathData::MacroDef(Ident::with_empty_ctxt(proc_macro.0)),
1241+
data: DefPathData::MacroDef(proc_macro.0),
12421242
disambiguator: 0,
12431243
},
12441244
};

src/libsyntax/parse/lexer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ impl<'a> StringReader<'a> {
483483
self.with_str_from(start, |string| {
484484
if string == "_" {
485485
self.sess.span_diagnostic
486-
.struct_span_warn(mk_sp(start, self.pos),
486+
.struct_span_warn(self.mk_sp(start, self.pos),
487487
"underscore literal suffix is not allowed")
488488
.warn("this was previously accepted by the compiler but is \
489489
being phased out; it will become a hard error in \

src/libsyntax/parse/token.rs

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use serialize::{Decodable, Decoder, Encodable, Encoder};
2020
use symbol::keywords;
2121
use tokenstream::{TokenStream, TokenTree};
2222

23-
use std::cell::RefCell;
24-
use std::fmt;
23+
use std::cell::Cell;
24+
use std::{cmp, fmt};
2525
use std::rc::Rc;
2626

2727
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
@@ -169,7 +169,8 @@ pub enum Token {
169169
Underscore,
170170
Lifetime(ast::Ident),
171171

172-
/* For interpolation */
172+
// The `LazyTokenStream` is a pure function of the `Nonterminal`,
173+
// and so the `LazyTokenStream` can be ignored by Eq, Hash, etc.
173174
Interpolated(Rc<(Nonterminal, LazyTokenStream)>),
174175
// Can be expanded into several tokens.
175176
/// Doc comment
@@ -468,19 +469,40 @@ pub fn is_op(tok: &Token) -> bool {
468469
}
469470
}
470471

471-
#[derive(Clone, Eq, PartialEq, Debug)]
472-
pub struct LazyTokenStream(RefCell<Option<TokenStream>>);
472+
pub struct LazyTokenStream(Cell<Option<TokenStream>>);
473+
474+
impl Clone for LazyTokenStream {
475+
fn clone(&self) -> Self {
476+
let opt_stream = self.0.take();
477+
self.0.set(opt_stream.clone());
478+
LazyTokenStream(Cell::new(opt_stream))
479+
}
480+
}
481+
482+
impl cmp::Eq for LazyTokenStream {}
483+
impl PartialEq for LazyTokenStream {
484+
fn eq(&self, _other: &LazyTokenStream) -> bool {
485+
true
486+
}
487+
}
488+
489+
impl fmt::Debug for LazyTokenStream {
490+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
491+
fmt::Debug::fmt(&self.clone().0.into_inner(), f)
492+
}
493+
}
473494

474495
impl LazyTokenStream {
475496
pub fn new() -> Self {
476-
LazyTokenStream(RefCell::new(None))
497+
LazyTokenStream(Cell::new(None))
477498
}
478499

479500
pub fn force<F: FnOnce() -> TokenStream>(&self, f: F) -> TokenStream {
480-
let mut opt_stream = self.0.borrow_mut();
501+
let mut opt_stream = self.0.take();
481502
if opt_stream.is_none() {
482-
*opt_stream = Some(f());
483-
};
503+
opt_stream = Some(f());
504+
}
505+
self.0.set(opt_stream.clone());
484506
opt_stream.clone().unwrap()
485507
}
486508
}
@@ -498,7 +520,5 @@ impl Decodable for LazyTokenStream {
498520
}
499521

500522
impl ::std::hash::Hash for LazyTokenStream {
501-
fn hash<H: ::std::hash::Hasher>(&self, hasher: &mut H) {
502-
self.0.borrow().hash(hasher);
503-
}
523+
fn hash<H: ::std::hash::Hasher>(&self, _hasher: &mut H) {}
504524
}

src/libsyntax/tokenstream.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,6 @@ impl TokenStream {
201201
}
202202
}
203203

204-
pub fn builder() -> TokenStreamBuilder {
205-
TokenStreamBuilder(Vec::new())
206-
}
207-
208204
pub fn concat(mut streams: Vec<TokenStream>) -> TokenStream {
209205
match streams.len() {
210206
0 => TokenStream::empty(),
@@ -235,6 +231,8 @@ impl TokenStream {
235231
true
236232
}
237233

234+
/// Precondition: `self` consists of a single token tree.
235+
/// Returns true if the token tree is a joint operation w.r.t. `proc_macro::TokenNode`.
238236
pub fn as_tree(self) -> (TokenTree, bool /* joint? */) {
239237
match self.kind {
240238
TokenStreamKind::Tree(tree) => (tree, false),
@@ -277,6 +275,10 @@ impl TokenStream {
277275
pub struct TokenStreamBuilder(Vec<TokenStream>);
278276

279277
impl TokenStreamBuilder {
278+
pub fn new() -> TokenStreamBuilder {
279+
TokenStreamBuilder(Vec::new())
280+
}
281+
280282
pub fn push<T: Into<TokenStream>>(&mut self, stream: T) {
281283
let stream = stream.into();
282284
let last_tree_if_joint = self.0.last().and_then(TokenStream::last_tree_if_joint);

src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515

1616
extern crate proc_macro;
1717

18-
use proc_macro::{TokenStream, TokenKind, quote};
18+
use proc_macro::{TokenStream, TokenNode, quote};
1919

2020
#[proc_macro]
2121
pub fn cond(input: TokenStream) -> TokenStream {
2222
let mut conds = Vec::new();
2323
let mut input = input.into_iter().peekable();
2424
while let Some(tree) = input.next() {
2525
let cond = match tree.kind {
26-
TokenKind::Sequence(_, cond) => cond,
26+
TokenNode::Sequence(_, cond) => cond,
2727
_ => panic!("Invalid input"),
2828
};
2929
let mut cond_trees = cond.clone().into_iter();
@@ -33,7 +33,7 @@ pub fn cond(input: TokenStream) -> TokenStream {
3333
panic!("Invalid macro usage in cond: {}", cond);
3434
}
3535
let is_else = match test.kind {
36-
TokenKind::Word(word) => *word == *"else",
36+
TokenNode::Word(word) => word.as_str() == "else",
3737
_ => false,
3838
};
3939
conds.push(if is_else || input.peek().is_none() {

src/test/run-pass-fulldeps/proc-macro/auxiliary/count_compound_ops.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,20 @@
1515

1616
extern crate proc_macro;
1717

18-
use proc_macro::{TokenStream, TokenKind, OpKind, Literal, quote};
18+
use proc_macro::{TokenStream, TokenNode, OpKind, Literal, quote};
1919

2020
#[proc_macro]
2121
pub fn count_compound_ops(input: TokenStream) -> TokenStream {
2222
assert_eq!(count_compound_ops_helper(quote!(++ (&&) 4@a)), 3);
23-
TokenKind::Literal(Literal::u32(count_compound_ops_helper(input))).into()
23+
TokenNode::Literal(Literal::u32(count_compound_ops_helper(input))).into()
2424
}
2525

2626
fn count_compound_ops_helper(input: TokenStream) -> u32 {
2727
let mut count = 0;
2828
for token in input {
2929
match token.kind {
30-
TokenKind::Op(c, OpKind::Alone) => count += 1,
31-
TokenKind::Sequence(_, tokens) => count += count_compound_ops_helper(tokens),
30+
TokenNode::Op(c, OpKind::Alone) => count += 1,
31+
TokenNode::Sequence(_, tokens) => count += count_compound_ops_helper(tokens),
3232
_ => {}
3333
}
3434
}

0 commit comments

Comments
 (0)