|
| 1 | +use syn::visit::Visit; |
| 2 | + |
1 | 3 | use crate::prelude::*;
|
2 | 4 | use crate::rewrite_self::*;
|
3 | 5 |
|
@@ -140,6 +142,29 @@ pub(crate) fn expect_future_expr(e: &Expr) -> Option<std::result::Result<Ident,
|
140 | 142 | None
|
141 | 143 | }
|
142 | 144 |
|
| 145 | +#[derive(Default)] |
| 146 | +pub struct IdentCollector { |
| 147 | + pub idents: Vec<Ident>, |
| 148 | +} |
| 149 | + |
| 150 | +impl<'ast> syn::visit::Visit<'ast> for IdentCollector { |
| 151 | + fn visit_ident(&mut self, ident: &'ast Ident) { |
| 152 | + self.idents.push(ident.clone()); |
| 153 | + } |
| 154 | +} |
| 155 | + |
| 156 | +impl IdentCollector { |
| 157 | + /// Returns a fresh identifier with the given prefix that is not in the collected identifiers. |
| 158 | + pub fn fresh_ident(&self, prefix: &str) -> Ident { |
| 159 | + let idents: HashSet<&Ident> = HashSet::from_iter(self.idents.iter()); |
| 160 | + let mk = |s| Ident::new(s, Span::call_site()); |
| 161 | + std::iter::once(mk(prefix)) |
| 162 | + .chain((0u64..).map(|i| Ident::new(&format!("{}{}", prefix, i), Span::call_site()))) |
| 163 | + .find(|ident| !idents.contains(ident)) |
| 164 | + .unwrap() |
| 165 | + } |
| 166 | +} |
| 167 | + |
143 | 168 | /// Rewrites `future(x)` nodes in an expression when (1) `x` is an
|
144 | 169 | /// ident and (2) the ident `x` is contained in the HashSet.
|
145 | 170 | struct RewriteFuture(HashSet<String>);
|
@@ -206,7 +231,12 @@ pub fn make_fn_decoration(
|
206 | 231 | mut generics: Option<Generics>,
|
207 | 232 | self_type: Option<Type>,
|
208 | 233 | ) -> (TokenStream, AttrPayload) {
|
209 |
| - let self_ident: Ident = syn::parse_quote! {self_}; |
| 234 | + let self_ident: Ident = { |
| 235 | + let mut idents = IdentCollector::default(); |
| 236 | + idents.visit_expr(&phi); |
| 237 | + idents.visit_signature(&signature); |
| 238 | + idents.fresh_ident("self_") |
| 239 | + }; |
210 | 240 | let error = {
|
211 | 241 | let mut rewriter = RewriteSelf::new(self_ident, self_type);
|
212 | 242 | rewriter.visit_expr_mut(&mut phi);
|
|
0 commit comments