diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2023-07-27 11:48:55 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2023-07-27 11:59:03 +1000 |
| commit | 4ebf2be8bb91e41fdf6c7c337482c72317508cef (patch) | |
| tree | fb5e3a32517ef0e603ac28a925b7bde8fa21fa11 | |
| parent | ee6ed603733c5b61690a920c4eaa4806f1d0f213 (diff) | |
| download | rust-4ebf2be8bb91e41fdf6c7c337482c72317508cef.tar.gz rust-4ebf2be8bb91e41fdf6c7c337482c72317508cef.zip | |
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`.
| -rw-r--r-- | compiler/rustc_ast/src/tokenstream.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/config.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/proc_macro_server.rs | 4 |
3 files changed, 13 insertions, 18 deletions
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index c6f0643147d..348c37c480f 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -597,26 +597,21 @@ impl<'t> Iterator for RefTokenTreeCursor<'t> { } } -/// Owning by-value iterator over a [`TokenStream`], that produces `TokenTree` +/// Owning by-value iterator over a [`TokenStream`], that produces `&TokenTree` /// items. -// FIXME: Many uses of this can be replaced with by-reference iterator to avoid clones. +/// +/// Doesn't impl `Iterator` because Rust doesn't permit an owning iterator to +/// return `&T` from `next`; the need for an explicit lifetime in the `Item` +/// associated type gets in the way. Instead, use `next_ref` (which doesn't +/// involve associated types) for getting individual elements, or +/// `RefTokenTreeCursor` if you really want an `Iterator`, e.g. in a `for` +/// loop. #[derive(Clone)] pub struct TokenTreeCursor { pub stream: TokenStream, index: usize, } -impl Iterator for TokenTreeCursor { - type Item = TokenTree; - - fn next(&mut self) -> Option<TokenTree> { - self.stream.0.get(self.index).map(|tree| { - self.index += 1; - tree.clone() - }) - } -} - impl TokenTreeCursor { fn new(stream: TokenStream) -> Self { TokenTreeCursor { stream, index: 0 } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 4ec5ac22e90..aeb4f6e861b 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -365,9 +365,9 @@ impl<'a> StripUnconfigured<'a> { // Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token // for `attr` when we expand it to `#[attr]` - let mut orig_trees = orig_tokens.into_trees(); + let mut orig_trees = orig_tokens.trees(); let TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }, _) = - orig_trees.next().unwrap() + orig_trees.next().unwrap().clone() else { panic!("Bad tokens for attribute {:?}", attr); }; @@ -377,7 +377,7 @@ impl<'a> StripUnconfigured<'a> { if attr.style == AttrStyle::Inner { // For inner attributes, we do the same thing for the `!` in `#![some_attr]` let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) = - orig_trees.next().unwrap() + orig_trees.next().unwrap().clone() else { panic!("Bad tokens for attribute {:?}", attr); }; diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index ecd2315112a..ac73b5d72b7 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -94,10 +94,10 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre // Estimate the capacity as `stream.len()` rounded up to the next power // of two to limit the number of required reallocations. let mut trees = Vec::with_capacity(stream.len().next_power_of_two()); - let mut cursor = stream.into_trees(); + let mut cursor = stream.trees(); while let Some(tree) = cursor.next() { - let (Token { kind, span }, joint) = match tree { + let (Token { kind, span }, joint) = match tree.clone() { tokenstream::TokenTree::Delimited(span, delim, tts) => { let delimiter = pm::Delimiter::from_internal(delim); trees.push(TokenTree::Group(Group { |
