Skip to content

Commit 4ebf2be

Browse files
committed
Remove Iterator impl for TokenTreeCursor.
This is surprising, but the new comment explains why. It's a logical conclusion in the drive to avoid `TokenTree` clones. `TokenTreeCursor` is now only used within `Parser`. It's still needed due to `replace_prev_and_rewind`.
1 parent ee6ed60 commit 4ebf2be

File tree

3 files changed

+13
-18
lines changed

3 files changed

+13
-18
lines changed

compiler/rustc_ast/src/tokenstream.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -597,26 +597,21 @@ impl<'t> Iterator for RefTokenTreeCursor<'t> {
597597
}
598598
}
599599

600-
/// Owning by-value iterator over a [`TokenStream`], that produces `TokenTree`
600+
/// Owning by-value iterator over a [`TokenStream`], that produces `&TokenTree`
601601
/// items.
602-
// FIXME: Many uses of this can be replaced with by-reference iterator to avoid clones.
602+
///
603+
/// Doesn't impl `Iterator` because Rust doesn't permit an owning iterator to
604+
/// return `&T` from `next`; the need for an explicit lifetime in the `Item`
605+
/// associated type gets in the way. Instead, use `next_ref` (which doesn't
606+
/// involve associated types) for getting individual elements, or
607+
/// `RefTokenTreeCursor` if you really want an `Iterator`, e.g. in a `for`
608+
/// loop.
603609
#[derive(Clone)]
604610
pub struct TokenTreeCursor {
605611
pub stream: TokenStream,
606612
index: usize,
607613
}
608614

609-
impl Iterator for TokenTreeCursor {
610-
type Item = TokenTree;
611-
612-
fn next(&mut self) -> Option<TokenTree> {
613-
self.stream.0.get(self.index).map(|tree| {
614-
self.index += 1;
615-
tree.clone()
616-
})
617-
}
618-
}
619-
620615
impl TokenTreeCursor {
621616
fn new(stream: TokenStream) -> Self {
622617
TokenTreeCursor { stream, index: 0 }

compiler/rustc_expand/src/config.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,9 @@ impl<'a> StripUnconfigured<'a> {
365365

366366
// Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token
367367
// for `attr` when we expand it to `#[attr]`
368-
let mut orig_trees = orig_tokens.into_trees();
368+
let mut orig_trees = orig_tokens.trees();
369369
let TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }, _) =
370-
orig_trees.next().unwrap()
370+
orig_trees.next().unwrap().clone()
371371
else {
372372
panic!("Bad tokens for attribute {:?}", attr);
373373
};
@@ -377,7 +377,7 @@ impl<'a> StripUnconfigured<'a> {
377377
if attr.style == AttrStyle::Inner {
378378
// For inner attributes, we do the same thing for the `!` in `#![some_attr]`
379379
let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) =
380-
orig_trees.next().unwrap()
380+
orig_trees.next().unwrap().clone()
381381
else {
382382
panic!("Bad tokens for attribute {:?}", attr);
383383
};

compiler/rustc_expand/src/proc_macro_server.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
9494
// Estimate the capacity as `stream.len()` rounded up to the next power
9595
// of two to limit the number of required reallocations.
9696
let mut trees = Vec::with_capacity(stream.len().next_power_of_two());
97-
let mut cursor = stream.into_trees();
97+
let mut cursor = stream.trees();
9898

9999
while let Some(tree) = cursor.next() {
100-
let (Token { kind, span }, joint) = match tree {
100+
let (Token { kind, span }, joint) = match tree.clone() {
101101
tokenstream::TokenTree::Delimited(span, delim, tts) => {
102102
let delimiter = pm::Delimiter::from_internal(delim);
103103
trees.push(TokenTree::Group(Group {

0 commit comments

Comments
 (0)