Skip to content

Commit 20eb5ed

Browse files
authored
Merge pull request #341 from dtolnay/rcvec
Replace Rc<Vec<T>> with RcVec<T>
2 parents e338234 + 275aaeb commit 20eb5ed

File tree

3 files changed

+169
-23
lines changed

3 files changed

+169
-23
lines changed

src/fallback.rs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
use crate::parse::{self, Cursor};
2+
use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut};
23
use crate::{Delimiter, Spacing, TokenTree};
34
#[cfg(span_locations)]
45
use std::cell::RefCell;
56
#[cfg(span_locations)]
67
use std::cmp;
78
use std::fmt::{self, Debug, Display, Write};
89
use std::iter::FromIterator;
9-
use std::mem;
1010
use std::ops::RangeBounds;
1111
#[cfg(procmacro2_semver_exempt)]
1212
use std::path::Path;
1313
use std::path::PathBuf;
14-
use std::rc::Rc;
1514
use std::str::FromStr;
16-
use std::vec;
1715

1816
/// Force use of proc-macro2's fallback implementation of the API for now, even
1917
/// if the compiler's implementation is available.
@@ -31,7 +29,7 @@ pub fn unforce() {
3129

3230
#[derive(Clone)]
3331
pub(crate) struct TokenStream {
34-
inner: Rc<Vec<TokenTree>>,
32+
inner: RcVec<TokenTree>,
3533
}
3634

3735
#[derive(Debug)]
@@ -54,20 +52,20 @@ impl LexError {
5452
impl TokenStream {
5553
pub fn new() -> Self {
5654
TokenStream {
57-
inner: Rc::new(Vec::new()),
55+
inner: RcVec::new(),
5856
}
5957
}
6058

6159
pub fn is_empty(&self) -> bool {
6260
self.inner.len() == 0
6361
}
6462

65-
fn take_inner(&mut self) -> Vec<TokenTree> {
66-
mem::replace(Rc::make_mut(&mut self.inner), Vec::new())
63+
fn take_inner(&mut self) -> RcVecBuilder<TokenTree> {
64+
self.inner.make_mut().take()
6765
}
6866
}
6967

70-
fn push_token_from_proc_macro(vec: &mut Vec<TokenTree>, token: TokenTree) {
68+
fn push_token_from_proc_macro(mut vec: RcVecMut<TokenTree>, token: TokenTree) {
7169
// https://github.com/dtolnay/proc-macro2/issues/235
7270
match token {
7371
#[cfg(not(no_bind_by_move_pattern_guard))]
@@ -98,7 +96,7 @@ fn push_token_from_proc_macro(vec: &mut Vec<TokenTree>, token: TokenTree) {
9896
}
9997

10098
#[cold]
101-
fn push_negative_literal(vec: &mut Vec<TokenTree>, mut literal: Literal) {
99+
fn push_negative_literal(mut vec: RcVecMut<TokenTree>, mut literal: Literal) {
102100
literal.repr.remove(0);
103101
let mut punct = crate::Punct::new('-', Spacing::Alone);
104102
punct.set_span(crate::Span::_new_stable(literal.span));
@@ -110,7 +108,7 @@ fn push_token_from_proc_macro(vec: &mut Vec<TokenTree>, token: TokenTree) {
110108
// Nonrecursive to prevent stack overflow.
111109
impl Drop for TokenStream {
112110
fn drop(&mut self) {
113-
let inner = match Rc::get_mut(&mut self.inner) {
111+
let mut inner = match self.inner.get_mut() {
114112
Some(inner) => inner,
115113
None => return,
116114
};
@@ -131,17 +129,19 @@ impl Drop for TokenStream {
131129
}
132130

133131
pub(crate) struct TokenStreamBuilder {
134-
inner: Vec<TokenTree>,
132+
inner: RcVecBuilder<TokenTree>,
135133
}
136134

137135
impl TokenStreamBuilder {
138136
pub fn new() -> Self {
139-
TokenStreamBuilder { inner: Vec::new() }
137+
TokenStreamBuilder {
138+
inner: RcVecBuilder::new(),
139+
}
140140
}
141141

142142
pub fn with_capacity(cap: usize) -> Self {
143143
TokenStreamBuilder {
144-
inner: Vec::with_capacity(cap),
144+
inner: RcVecBuilder::with_capacity(cap),
145145
}
146146
}
147147

@@ -151,7 +151,7 @@ impl TokenStreamBuilder {
151151

152152
pub fn build(self) -> TokenStream {
153153
TokenStream {
154-
inner: Rc::new(self.inner),
154+
inner: self.inner.build(),
155155
}
156156
}
157157
}
@@ -244,9 +244,11 @@ impl From<TokenStream> for proc_macro::TokenStream {
244244

245245
impl From<TokenTree> for TokenStream {
246246
fn from(tree: TokenTree) -> TokenStream {
247-
let mut stream = TokenStreamBuilder::new();
248-
push_token_from_proc_macro(&mut stream.inner, tree);
249-
stream.build()
247+
let mut stream = RcVecBuilder::new();
248+
push_token_from_proc_macro(stream.as_mut(), tree);
249+
TokenStream {
250+
inner: stream.build(),
251+
}
250252
}
251253
}
252254

@@ -260,32 +262,32 @@ impl FromIterator<TokenTree> for TokenStream {
260262

261263
impl FromIterator<TokenStream> for TokenStream {
262264
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
263-
let mut v = Vec::new();
265+
let mut v = RcVecBuilder::new();
264266

265267
for mut stream in streams {
266268
v.extend(stream.take_inner());
267269
}
268270

269-
TokenStream { inner: Rc::new(v) }
271+
TokenStream { inner: v.build() }
270272
}
271273
}
272274

273275
impl Extend<TokenTree> for TokenStream {
274276
fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, tokens: I) {
275-
let vec = Rc::make_mut(&mut self.inner);
277+
let mut vec = self.inner.make_mut();
276278
tokens
277279
.into_iter()
278-
.for_each(|token| push_token_from_proc_macro(vec, token));
280+
.for_each(|token| push_token_from_proc_macro(vec.as_mut(), token));
279281
}
280282
}
281283

282284
impl Extend<TokenStream> for TokenStream {
283285
fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
284-
Rc::make_mut(&mut self.inner).extend(streams.into_iter().flatten());
286+
self.inner.make_mut().extend(streams.into_iter().flatten());
285287
}
286288
}
287289

288-
pub(crate) type TokenTreeIter = vec::IntoIter<TokenTree>;
290+
pub(crate) type TokenTreeIter = RcVecIntoIter<TokenTree>;
289291

290292
impl IntoIterator for TokenStream {
291293
type Item = TokenTree;

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ extern crate proc_macro;
120120

121121
mod marker;
122122
mod parse;
123+
mod rcvec;
123124

124125
#[cfg(wrap_proc_macro)]
125126
mod detection;

src/rcvec.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
use std::mem;
2+
use std::rc::Rc;
3+
use std::slice;
4+
use std::vec;
5+
6+
pub(crate) struct RcVec<T> {
7+
inner: Rc<Vec<T>>,
8+
}
9+
10+
pub(crate) struct RcVecBuilder<T> {
11+
inner: Vec<T>,
12+
}
13+
14+
pub(crate) struct RcVecMut<'a, T> {
15+
inner: &'a mut Vec<T>,
16+
}
17+
18+
#[derive(Clone)]
19+
pub(crate) struct RcVecIntoIter<T> {
20+
inner: vec::IntoIter<T>,
21+
}
22+
23+
impl<T> RcVec<T> {
24+
pub fn new() -> Self {
25+
RcVec {
26+
inner: Rc::new(Vec::new()),
27+
}
28+
}
29+
30+
pub fn is_empty(&self) -> bool {
31+
self.inner.is_empty()
32+
}
33+
34+
pub fn len(&self) -> usize {
35+
self.inner.len()
36+
}
37+
38+
pub fn iter(&self) -> slice::Iter<T> {
39+
self.inner.iter()
40+
}
41+
42+
pub fn make_mut(&mut self) -> RcVecMut<T>
43+
where
44+
T: Clone,
45+
{
46+
RcVecMut {
47+
inner: Rc::make_mut(&mut self.inner),
48+
}
49+
}
50+
51+
pub fn get_mut(&mut self) -> Option<RcVecMut<T>> {
52+
Some(RcVecMut {
53+
inner: Rc::get_mut(&mut self.inner)?,
54+
})
55+
}
56+
}
57+
58+
impl<T> RcVecBuilder<T> {
59+
pub fn new() -> Self {
60+
RcVecBuilder { inner: Vec::new() }
61+
}
62+
63+
pub fn with_capacity(cap: usize) -> Self {
64+
RcVecBuilder {
65+
inner: Vec::with_capacity(cap),
66+
}
67+
}
68+
69+
pub fn push(&mut self, element: T) {
70+
self.inner.push(element);
71+
}
72+
73+
pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
74+
self.inner.extend(iter);
75+
}
76+
77+
pub fn as_mut(&mut self) -> RcVecMut<T> {
78+
RcVecMut {
79+
inner: &mut self.inner,
80+
}
81+
}
82+
83+
pub fn build(self) -> RcVec<T> {
84+
RcVec {
85+
inner: Rc::new(self.inner),
86+
}
87+
}
88+
}
89+
90+
impl<'a, T> RcVecMut<'a, T> {
91+
pub fn push(&mut self, element: T) {
92+
self.inner.push(element);
93+
}
94+
95+
pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
96+
self.inner.extend(iter);
97+
}
98+
99+
pub fn pop(&mut self) -> Option<T> {
100+
self.inner.pop()
101+
}
102+
103+
pub fn as_mut(&mut self) -> RcVecMut<T> {
104+
RcVecMut { inner: self.inner }
105+
}
106+
107+
pub fn take(self) -> RcVecBuilder<T> {
108+
RcVecBuilder {
109+
inner: mem::replace(self.inner, Vec::new()),
110+
}
111+
}
112+
}
113+
114+
impl<T> Clone for RcVec<T> {
115+
fn clone(&self) -> Self {
116+
RcVec {
117+
inner: Rc::clone(&self.inner),
118+
}
119+
}
120+
}
121+
122+
impl<T> IntoIterator for RcVecBuilder<T> {
123+
type Item = T;
124+
type IntoIter = RcVecIntoIter<T>;
125+
126+
fn into_iter(self) -> Self::IntoIter {
127+
RcVecIntoIter {
128+
inner: self.inner.into_iter(),
129+
}
130+
}
131+
}
132+
133+
impl<T> Iterator for RcVecIntoIter<T> {
134+
type Item = T;
135+
136+
fn next(&mut self) -> Option<Self::Item> {
137+
self.inner.next()
138+
}
139+
140+
fn size_hint(&self) -> (usize, Option<usize>) {
141+
self.inner.size_hint()
142+
}
143+
}

0 commit comments

Comments
 (0)