diff --git a/src/libproc_macro_plugin/qquote.rs b/src/libproc_macro_plugin/qquote.rs index dc7c96a4e2767..b9bf35cff07b4 100644 --- a/src/libproc_macro_plugin/qquote.rs +++ b/src/libproc_macro_plugin/qquote.rs @@ -51,7 +51,7 @@ macro_rules! quote_tree { fn delimit(delim: token::DelimToken, stream: TokenStream) -> TokenStream { TokenTree::Delimited(DUMMY_SP, Rc::new(Delimited { delim: delim, - tts: stream.trees().cloned().collect(), + tts: stream.into_trees().collect(), })).into() } @@ -75,21 +75,21 @@ impl Quote for TokenStream { return quote!(::syntax::tokenstream::TokenStream::empty()); } - struct Quote<'a>(tokenstream::Cursor<'a>); + struct Quote(tokenstream::Cursor); - impl<'a> Iterator for Quote<'a> { + impl Iterator for Quote { type Item = TokenStream; fn next(&mut self) -> Option { let is_unquote = match self.0.peek() { - Some(&TokenTree::Token(_, Token::Ident(ident))) if ident.name == "unquote" => { + Some(TokenTree::Token(_, Token::Ident(ident))) if ident.name == "unquote" => { self.0.next(); true } _ => false, }; - self.0.next().cloned().map(|tree| { + self.0.next().map(|tree| { let quoted_tree = if is_unquote { tree.into() } else { tree.quote() }; quote!(::syntax::tokenstream::TokenStream::from((unquote quoted_tree)),) }) @@ -104,7 +104,7 @@ impl Quote for TokenStream { impl Quote for Vec { fn quote(&self) -> TokenStream { let stream = self.iter().cloned().collect::(); - quote!((quote stream).trees().cloned().collect::<::std::vec::Vec<_> >()) + quote!((quote stream).into_trees().collect::<::std::vec::Vec<_> >()) } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 38494378f72ad..8107696b8b920 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -647,7 +647,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, name: Name, span: Span) -> Expansion { - let mut parser = self.cx.new_parser_from_tts(&toks.trees().cloned().collect::>()); + let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::>()); let expansion = match parser.parse_expansion(kind, false) { Ok(expansion) => expansion, Err(mut err) => { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 6fec49b229abe..f783e32d62104 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -192,7 +192,7 @@ pub fn new_parser_from_tts<'a>(sess: &'a ParseSess, tts: Vec(sess: &'a ParseSess, ts: tokenstream::TokenStream) -> Parser<'a> { - tts_to_parser(sess, ts.trees().cloned().collect()) + tts_to_parser(sess, ts.into_trees().collect()) } diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 6665404672133..0f973540edb5a 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -35,7 +35,7 @@ use serialize::{Decoder, Decodable, Encoder, Encodable}; use symbol::Symbol; use util::RcSlice; -use std::{fmt, iter}; +use std::{fmt, iter, mem}; use std::rc::Rc; /// A delimited sequence of token trees @@ -338,14 +338,18 @@ impl TokenStream { TokenStream { kind: TokenStreamKind::Stream(RcSlice::new(vec)) } } - pub fn trees<'a>(&'a self) -> Cursor { + pub fn trees(&self) -> Cursor { + self.clone().into_trees() + } + + pub fn into_trees(self) -> Cursor { Cursor::new(self) } /// Compares two TokenStreams, checking equality without regarding span information. pub fn eq_unspanned(&self, other: &TokenStream) -> bool { for (t1, t2) in self.trees().zip(other.trees()) { - if !t1.eq_unspanned(t2) { + if !t1.eq_unspanned(&t2) { return false; } } @@ -353,58 +357,60 @@ impl TokenStream { } } -pub struct Cursor<'a> { - current_frame: CursorFrame<'a>, - stack: Vec>, +pub struct Cursor { + current_frame: CursorFrame, + stack: Vec, } -impl<'a> Iterator for Cursor<'a> { - type Item = &'a TokenTree; +impl Iterator for Cursor { + type Item = TokenTree; - fn next(&mut self) -> Option<&'a TokenTree> { + fn next(&mut self) -> Option { let tree = self.peek(); self.current_frame = self.stack.pop().unwrap_or(CursorFrame::Empty); tree } } -enum CursorFrame<'a> { +enum CursorFrame { Empty, - Tree(&'a TokenTree), - Stream(&'a RcSlice, usize), + Tree(TokenTree), + Stream(RcSlice, usize), } -impl<'a> CursorFrame<'a> { - fn new(stream: &'a TokenStream) -> Self { +impl CursorFrame { + fn new(stream: TokenStream) -> Self { match stream.kind { TokenStreamKind::Empty => CursorFrame::Empty, - TokenStreamKind::Tree(ref tree) => CursorFrame::Tree(tree), - TokenStreamKind::Stream(ref stream) => CursorFrame::Stream(stream, 0), + TokenStreamKind::Tree(tree) => CursorFrame::Tree(tree), + TokenStreamKind::Stream(stream) => CursorFrame::Stream(stream, 0), } } } -impl<'a> Cursor<'a> { - fn new(stream: &'a TokenStream) -> Self { +impl Cursor { + fn new(stream: TokenStream) -> Self { Cursor { current_frame: CursorFrame::new(stream), stack: Vec::new(), } } - pub fn peek(&mut self) -> Option<&'a TokenTree> { - while let CursorFrame::Stream(stream, index) = self.current_frame { + pub fn peek(&mut self) -> Option { + while let CursorFrame::Stream(stream, index) = + mem::replace(&mut self.current_frame, CursorFrame::Empty) { self.current_frame = if index == stream.len() { self.stack.pop().unwrap_or(CursorFrame::Empty) } else { + let frame = CursorFrame::new(stream[index].clone()); self.stack.push(CursorFrame::Stream(stream, index + 1)); - CursorFrame::new(&stream[index]) + frame }; } match self.current_frame { CursorFrame::Empty => None, - CursorFrame::Tree(tree) => Some(tree), + CursorFrame::Tree(ref tree) => Some(tree.clone()), CursorFrame::Stream(..) => unreachable!(), } } @@ -412,13 +418,13 @@ impl<'a> Cursor<'a> { impl fmt::Display for TokenStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(&pprust::tts_to_string(&self.trees().cloned().collect::>())) + f.write_str(&pprust::tts_to_string(&self.trees().collect::>())) } } impl Encodable for TokenStream { fn encode(&self, encoder: &mut E) -> Result<(), E::Error> { - self.trees().cloned().collect::>().encode(encoder) + self.trees().collect::>().encode(encoder) } } @@ -464,14 +470,14 @@ mod tests { fn test_from_to_bijection() { let test_start = string_to_tts("foo::bar(baz)".to_string()); let ts = test_start.iter().cloned().collect::(); - let test_end: Vec = ts.trees().cloned().collect(); + let test_end: Vec = ts.trees().collect(); assert_eq!(test_start, test_end) } #[test] fn test_to_from_bijection() { let test_start = string_to_ts("foo::bar(baz)"); - let test_end = test_start.trees().cloned().collect(); + let test_end = test_start.trees().collect(); assert_eq!(test_start, test_end) }