diff options
Diffstat (limited to 'crates/hir_expand')
-rw-r--r-- | crates/hir_expand/src/builtin_derive.rs | 2 | ||||
-rw-r--r-- | crates/hir_expand/src/builtin_macro.rs | 3 | ||||
-rw-r--r-- | crates/hir_expand/src/db.rs | 16 | ||||
-rw-r--r-- | crates/hir_expand/src/eager.rs | 6 | ||||
-rw-r--r-- | crates/hir_expand/src/hygiene.rs | 210 | ||||
-rw-r--r-- | crates/hir_expand/src/name.rs | 2 | ||||
-rw-r--r-- | crates/hir_expand/src/proc_macro.rs | 10 |
7 files changed, 204 insertions, 45 deletions
diff --git a/crates/hir_expand/src/builtin_derive.rs b/crates/hir_expand/src/builtin_derive.rs index ad378762a..eb257579f 100644 --- a/crates/hir_expand/src/builtin_derive.rs +++ b/crates/hir_expand/src/builtin_derive.rs | |||
@@ -277,7 +277,7 @@ mod tests { | |||
277 | let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap(); | 277 | let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap(); |
278 | let fixture = format!( | 278 | let fixture = format!( |
279 | r#"//- /main.rs crate:main deps:core | 279 | r#"//- /main.rs crate:main deps:core |
280 | <|> | 280 | $0 |
281 | {} | 281 | {} |
282 | //- /lib.rs crate:core | 282 | //- /lib.rs crate:core |
283 | // empty | 283 | // empty |
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index 6382521fb..80b60d59f 100644 --- a/crates/hir_expand/src/builtin_macro.rs +++ b/crates/hir_expand/src/builtin_macro.rs | |||
@@ -259,7 +259,8 @@ fn format_args_expand( | |||
259 | } | 259 | } |
260 | for arg in &mut args { | 260 | for arg in &mut args { |
261 | // Remove `key =`. | 261 | // Remove `key =`. |
262 | if matches!(arg.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=') { | 262 | if matches!(arg.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' && p.spacing != tt::Spacing::Joint) |
263 | { | ||
263 | arg.drain(..2); | 264 | arg.drain(..2); |
264 | } | 265 | } |
265 | } | 266 | } |
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 06f0a3ed9..c62086390 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs | |||
@@ -8,9 +8,9 @@ use parser::FragmentKind; | |||
8 | use syntax::{algo::diff, ast::NameOwner, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; | 8 | use syntax::{algo::diff, ast::NameOwner, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, | 11 | ast_id_map::AstIdMap, hygiene::HygieneFrame, BuiltinDeriveExpander, BuiltinFnLikeExpander, |
12 | HirFileId, HirFileIdRepr, LazyMacroId, MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, | 12 | EagerCallLoc, EagerMacroId, HirFileId, HirFileIdRepr, LazyMacroId, MacroCallId, MacroCallLoc, |
13 | MacroFile, ProcMacroExpander, | 13 | MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | /// Total limit on the number of tokens produced by any macro invocation. | 16 | /// Total limit on the number of tokens produced by any macro invocation. |
@@ -40,7 +40,7 @@ impl TokenExpander { | |||
40 | // FIXME switch these to ExpandResult as well | 40 | // FIXME switch these to ExpandResult as well |
41 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), | 41 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), |
42 | TokenExpander::ProcMacro(_) => { | 42 | TokenExpander::ProcMacro(_) => { |
43 | // We store the result in salsa db to prevent non-determinisc behavior in | 43 | // We store the result in salsa db to prevent non-deterministic behavior in |
44 | // some proc-macro implementation | 44 | // some proc-macro implementation |
45 | // See #4315 for details | 45 | // See #4315 for details |
46 | db.expand_proc_macro(id.into()).into() | 46 | db.expand_proc_macro(id.into()).into() |
@@ -94,6 +94,8 @@ pub trait AstDatabase: SourceDatabase { | |||
94 | fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId; | 94 | fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId; |
95 | 95 | ||
96 | fn expand_proc_macro(&self, call: MacroCallId) -> Result<tt::Subtree, mbe::ExpandError>; | 96 | fn expand_proc_macro(&self, call: MacroCallId) -> Result<tt::Subtree, mbe::ExpandError>; |
97 | |||
98 | fn hygiene_frame(&self, file_id: HirFileId) -> Arc<HygieneFrame>; | ||
97 | } | 99 | } |
98 | 100 | ||
99 | /// This expands the given macro call, but with different arguments. This is | 101 | /// This expands the given macro call, but with different arguments. This is |
@@ -369,6 +371,10 @@ fn parse_macro_with_arg( | |||
369 | } | 371 | } |
370 | } | 372 | } |
371 | 373 | ||
374 | fn hygiene_frame(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<HygieneFrame> { | ||
375 | Arc::new(HygieneFrame::new(db, file_id)) | ||
376 | } | ||
377 | |||
372 | /// Given a `MacroCallId`, return what `FragmentKind` it belongs to. | 378 | /// Given a `MacroCallId`, return what `FragmentKind` it belongs to. |
373 | /// FIXME: Not completed | 379 | /// FIXME: Not completed |
374 | fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind { | 380 | fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind { |
@@ -404,7 +410,7 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind { | |||
404 | TRY_EXPR => FragmentKind::Expr, | 410 | TRY_EXPR => FragmentKind::Expr, |
405 | TUPLE_EXPR => FragmentKind::Expr, | 411 | TUPLE_EXPR => FragmentKind::Expr, |
406 | PAREN_EXPR => FragmentKind::Expr, | 412 | PAREN_EXPR => FragmentKind::Expr, |
407 | 413 | ARRAY_EXPR => FragmentKind::Expr, | |
408 | FOR_EXPR => FragmentKind::Expr, | 414 | FOR_EXPR => FragmentKind::Expr, |
409 | PATH_EXPR => FragmentKind::Expr, | 415 | PATH_EXPR => FragmentKind::Expr, |
410 | CLOSURE_EXPR => FragmentKind::Expr, | 416 | CLOSURE_EXPR => FragmentKind::Expr, |
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs index 6354b090d..ae7b51a08 100644 --- a/crates/hir_expand/src/eager.rs +++ b/crates/hir_expand/src/eager.rs | |||
@@ -218,6 +218,12 @@ fn eager_macro_recur( | |||
218 | } | 218 | } |
219 | }; | 219 | }; |
220 | 220 | ||
221 | // check if the whole original sytnax is replaced | ||
222 | // Note that SyntaxRewriter cannot replace the root node itself | ||
223 | if child.syntax() == &original { | ||
224 | return Ok(insert); | ||
225 | } | ||
226 | |||
221 | rewriter.replace(child.syntax(), &insert); | 227 | rewriter.replace(child.syntax(), &insert); |
222 | } | 228 | } |
223 | 229 | ||
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index 7ab0a5e52..8db581b77 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs | |||
@@ -2,65 +2,209 @@ | |||
2 | //! | 2 | //! |
3 | //! Specifically, `ast` + `Hygiene` allows you to create a `Name`. Note that, at | 3 | //! Specifically, `ast` + `Hygiene` allows you to create a `Name`. Note that, at |
4 | //! this moment, this is horribly incomplete and handles only `$crate`. | 4 | //! this moment, this is horribly incomplete and handles only `$crate`. |
5 | use std::sync::Arc; | ||
6 | |||
5 | use base_db::CrateId; | 7 | use base_db::CrateId; |
6 | use either::Either; | 8 | use either::Either; |
7 | use syntax::ast; | 9 | use mbe::Origin; |
10 | use parser::SyntaxKind; | ||
11 | use syntax::{ast, AstNode, SyntaxNode, TextRange, TextSize}; | ||
8 | 12 | ||
9 | use crate::{ | 13 | use crate::{ |
10 | db::AstDatabase, | 14 | db::{self, AstDatabase}, |
11 | name::{AsName, Name}, | 15 | name::{AsName, Name}, |
12 | HirFileId, HirFileIdRepr, MacroCallId, MacroDefKind, | 16 | HirFileId, HirFileIdRepr, InFile, MacroCallId, MacroCallLoc, MacroDefKind, MacroFile, |
13 | }; | 17 | }; |
14 | 18 | ||
15 | #[derive(Clone, Debug)] | 19 | #[derive(Clone, Debug)] |
16 | pub struct Hygiene { | 20 | pub struct Hygiene { |
17 | // This is what `$crate` expands to | 21 | frames: Option<HygieneFrames>, |
18 | def_crate: Option<CrateId>, | ||
19 | |||
20 | // Indicate this is a local inner macro | ||
21 | local_inner: bool, | ||
22 | } | 22 | } |
23 | 23 | ||
24 | impl Hygiene { | 24 | impl Hygiene { |
25 | pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene { | 25 | pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene { |
26 | let (def_crate, local_inner) = match file_id.0 { | 26 | Hygiene { frames: Some(HygieneFrames::new(db, file_id.clone())) } |
27 | HirFileIdRepr::FileId(_) => (None, false), | ||
28 | HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { | ||
29 | MacroCallId::LazyMacro(id) => { | ||
30 | let loc = db.lookup_intern_macro(id); | ||
31 | match loc.def.kind { | ||
32 | MacroDefKind::Declarative => (Some(loc.def.krate), loc.def.local_inner), | ||
33 | MacroDefKind::BuiltIn(_) => (Some(loc.def.krate), false), | ||
34 | MacroDefKind::BuiltInDerive(_) => (None, false), | ||
35 | MacroDefKind::BuiltInEager(_) => (None, false), | ||
36 | MacroDefKind::ProcMacro(_) => (None, false), | ||
37 | } | ||
38 | } | ||
39 | MacroCallId::EagerMacro(_id) => (None, false), | ||
40 | }, | ||
41 | }; | ||
42 | Hygiene { def_crate, local_inner } | ||
43 | } | 27 | } |
44 | 28 | ||
45 | pub fn new_unhygienic() -> Hygiene { | 29 | pub fn new_unhygienic() -> Hygiene { |
46 | Hygiene { def_crate: None, local_inner: false } | 30 | Hygiene { frames: None } |
47 | } | 31 | } |
48 | 32 | ||
49 | // FIXME: this should just return name | 33 | // FIXME: this should just return name |
50 | pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either<Name, CrateId> { | 34 | pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either<Name, CrateId> { |
51 | if let Some(def_crate) = self.def_crate { | 35 | if let Some(frames) = &self.frames { |
52 | if name_ref.text() == "$crate" { | 36 | if name_ref.text() == "$crate" { |
53 | return Either::Right(def_crate); | 37 | if let Some(krate) = frames.root_crate(name_ref.syntax()) { |
38 | return Either::Right(krate); | ||
39 | } | ||
54 | } | 40 | } |
55 | } | 41 | } |
42 | |||
56 | Either::Left(name_ref.as_name()) | 43 | Either::Left(name_ref.as_name()) |
57 | } | 44 | } |
58 | 45 | ||
59 | pub fn local_inner_macros(&self) -> Option<CrateId> { | 46 | pub fn local_inner_macros(&self, path: ast::Path) -> Option<CrateId> { |
60 | if self.local_inner { | 47 | let mut token = path.syntax().first_token()?.text_range(); |
61 | self.def_crate | 48 | let frames = self.frames.as_ref()?; |
62 | } else { | 49 | let mut current = frames.0.clone(); |
63 | None | 50 | |
51 | loop { | ||
52 | let (mapped, origin) = current.expansion.as_ref()?.map_ident_up(token)?; | ||
53 | if origin == Origin::Def { | ||
54 | return if current.local_inner { frames.root_crate(path.syntax()) } else { None }; | ||
55 | } | ||
56 | current = current.call_site.as_ref()?.clone(); | ||
57 | token = mapped.value; | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | |||
62 | #[derive(Clone, Debug)] | ||
63 | struct HygieneFrames(Arc<HygieneFrame>); | ||
64 | |||
65 | #[derive(Clone, Debug, Eq, PartialEq)] | ||
66 | pub struct HygieneFrame { | ||
67 | expansion: Option<HygieneInfo>, | ||
68 | |||
69 | // Indicate this is a local inner macro | ||
70 | local_inner: bool, | ||
71 | krate: Option<CrateId>, | ||
72 | |||
73 | call_site: Option<Arc<HygieneFrame>>, | ||
74 | def_site: Option<Arc<HygieneFrame>>, | ||
75 | } | ||
76 | |||
77 | impl HygieneFrames { | ||
78 | fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Self { | ||
79 | HygieneFrames(Arc::new(HygieneFrame::new(db, file_id))) | ||
80 | } | ||
81 | |||
82 | fn root_crate(&self, node: &SyntaxNode) -> Option<CrateId> { | ||
83 | let mut token = node.first_token()?.text_range(); | ||
84 | let mut result = self.0.krate; | ||
85 | let mut current = self.0.clone(); | ||
86 | |||
87 | while let Some((mapped, origin)) = | ||
88 | current.expansion.as_ref().and_then(|it| it.map_ident_up(token)) | ||
89 | { | ||
90 | result = current.krate; | ||
91 | |||
92 | let site = match origin { | ||
93 | Origin::Def => ¤t.def_site, | ||
94 | Origin::Call => ¤t.call_site, | ||
95 | }; | ||
96 | |||
97 | let site = match site { | ||
98 | None => break, | ||
99 | Some(it) => it, | ||
100 | }; | ||
101 | |||
102 | current = site.clone(); | ||
103 | token = mapped.value; | ||
64 | } | 104 | } |
105 | |||
106 | result | ||
107 | } | ||
108 | } | ||
109 | |||
110 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
111 | struct HygieneInfo { | ||
112 | arg_start: InFile<TextSize>, | ||
113 | /// The `macro_rules!` arguments. | ||
114 | def_start: Option<InFile<TextSize>>, | ||
115 | |||
116 | macro_def: Arc<(db::TokenExpander, mbe::TokenMap)>, | ||
117 | macro_arg: Arc<(tt::Subtree, mbe::TokenMap)>, | ||
118 | exp_map: Arc<mbe::TokenMap>, | ||
119 | } | ||
120 | |||
121 | impl HygieneInfo { | ||
122 | fn map_ident_up(&self, token: TextRange) -> Option<(InFile<TextRange>, Origin)> { | ||
123 | let token_id = self.exp_map.token_by_range(token)?; | ||
124 | |||
125 | let (token_id, origin) = self.macro_def.0.map_id_up(token_id); | ||
126 | let (token_map, tt) = match origin { | ||
127 | mbe::Origin::Call => (&self.macro_arg.1, self.arg_start), | ||
128 | mbe::Origin::Def => ( | ||
129 | &self.macro_def.1, | ||
130 | self.def_start | ||
131 | .as_ref() | ||
132 | .expect("`Origin::Def` used with non-`macro_rules!` macro") | ||
133 | .clone(), | ||
134 | ), | ||
135 | }; | ||
136 | |||
137 | let range = token_map.range_by_token(token_id)?.by_kind(SyntaxKind::IDENT)?; | ||
138 | Some((tt.with_value(range + tt.value), origin)) | ||
139 | } | ||
140 | } | ||
141 | |||
142 | fn make_hygiene_info( | ||
143 | db: &dyn AstDatabase, | ||
144 | macro_file: MacroFile, | ||
145 | loc: &MacroCallLoc, | ||
146 | ) -> Option<HygieneInfo> { | ||
147 | let arg_tt = loc.kind.arg(db)?; | ||
148 | |||
149 | let def_offset = loc.def.ast_id.and_then(|id| { | ||
150 | let def_tt = match id.to_node(db) { | ||
151 | ast::Macro::MacroRules(mac) => mac.token_tree()?.syntax().text_range().start(), | ||
152 | ast::Macro::MacroDef(_) => return None, | ||
153 | }; | ||
154 | Some(InFile::new(id.file_id, def_tt)) | ||
155 | }); | ||
156 | |||
157 | let macro_def = db.macro_def(loc.def)?; | ||
158 | let (_, exp_map) = db.parse_macro_expansion(macro_file).value?; | ||
159 | let macro_arg = db.macro_arg(macro_file.macro_call_id)?; | ||
160 | |||
161 | Some(HygieneInfo { | ||
162 | arg_start: InFile::new(loc.kind.file_id(), arg_tt.text_range().start()), | ||
163 | def_start: def_offset, | ||
164 | macro_arg, | ||
165 | macro_def, | ||
166 | exp_map, | ||
167 | }) | ||
168 | } | ||
169 | |||
170 | impl HygieneFrame { | ||
171 | pub(crate) fn new(db: &dyn AstDatabase, file_id: HirFileId) -> HygieneFrame { | ||
172 | let (info, krate, local_inner) = match file_id.0 { | ||
173 | HirFileIdRepr::FileId(_) => (None, None, false), | ||
174 | HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { | ||
175 | MacroCallId::EagerMacro(_id) => (None, None, false), | ||
176 | MacroCallId::LazyMacro(id) => { | ||
177 | let loc = db.lookup_intern_macro(id); | ||
178 | let info = make_hygiene_info(db, macro_file, &loc); | ||
179 | match loc.def.kind { | ||
180 | MacroDefKind::Declarative => { | ||
181 | (info, Some(loc.def.krate), loc.def.local_inner) | ||
182 | } | ||
183 | MacroDefKind::BuiltIn(_) => (info, Some(loc.def.krate), false), | ||
184 | MacroDefKind::BuiltInDerive(_) => (info, None, false), | ||
185 | MacroDefKind::BuiltInEager(_) => (info, None, false), | ||
186 | MacroDefKind::ProcMacro(_) => (info, None, false), | ||
187 | } | ||
188 | } | ||
189 | }, | ||
190 | }; | ||
191 | |||
192 | let info = match info { | ||
193 | None => { | ||
194 | return HygieneFrame { | ||
195 | expansion: None, | ||
196 | local_inner, | ||
197 | krate, | ||
198 | call_site: None, | ||
199 | def_site: None, | ||
200 | }; | ||
201 | } | ||
202 | Some(it) => it, | ||
203 | }; | ||
204 | |||
205 | let def_site = info.def_start.map(|it| db.hygiene_frame(it.file_id)); | ||
206 | let call_site = Some(db.hygiene_frame(info.arg_start.file_id)); | ||
207 | |||
208 | HygieneFrame { expansion: Some(info), local_inner, krate, call_site, def_site } | ||
65 | } | 209 | } |
66 | } | 210 | } |
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index 2f44876a8..95d853b6d 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs | |||
@@ -164,6 +164,7 @@ pub mod known { | |||
164 | future, | 164 | future, |
165 | result, | 165 | result, |
166 | boxed, | 166 | boxed, |
167 | option, | ||
167 | // Components of known path (type name) | 168 | // Components of known path (type name) |
168 | Iterator, | 169 | Iterator, |
169 | IntoIterator, | 170 | IntoIterator, |
@@ -172,6 +173,7 @@ pub mod known { | |||
172 | Ok, | 173 | Ok, |
173 | Future, | 174 | Future, |
174 | Result, | 175 | Result, |
176 | Option, | ||
175 | Output, | 177 | Output, |
176 | Target, | 178 | Target, |
177 | Box, | 179 | Box, |
diff --git a/crates/hir_expand/src/proc_macro.rs b/crates/hir_expand/src/proc_macro.rs index 7c77f6ce0..1923daca5 100644 --- a/crates/hir_expand/src/proc_macro.rs +++ b/crates/hir_expand/src/proc_macro.rs | |||
@@ -58,7 +58,7 @@ impl ProcMacroExpander { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | fn eat_punct(cursor: &mut Cursor, c: char) -> bool { | 60 | fn eat_punct(cursor: &mut Cursor, c: char) -> bool { |
61 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = cursor.token_tree() { | 61 | if let Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(punct), _)) = cursor.token_tree() { |
62 | if punct.char == c { | 62 | if punct.char == c { |
63 | *cursor = cursor.bump(); | 63 | *cursor = cursor.bump(); |
64 | return true; | 64 | return true; |
@@ -68,7 +68,7 @@ fn eat_punct(cursor: &mut Cursor, c: char) -> bool { | |||
68 | } | 68 | } |
69 | 69 | ||
70 | fn eat_subtree(cursor: &mut Cursor, kind: tt::DelimiterKind) -> bool { | 70 | fn eat_subtree(cursor: &mut Cursor, kind: tt::DelimiterKind) -> bool { |
71 | if let Some(tt::TokenTree::Subtree(subtree)) = cursor.token_tree() { | 71 | if let Some(tt::buffer::TokenTreeRef::Subtree(subtree, _)) = cursor.token_tree() { |
72 | if Some(kind) == subtree.delimiter_kind() { | 72 | if Some(kind) == subtree.delimiter_kind() { |
73 | *cursor = cursor.bump_subtree(); | 73 | *cursor = cursor.bump_subtree(); |
74 | return true; | 74 | return true; |
@@ -78,7 +78,7 @@ fn eat_subtree(cursor: &mut Cursor, kind: tt::DelimiterKind) -> bool { | |||
78 | } | 78 | } |
79 | 79 | ||
80 | fn eat_ident(cursor: &mut Cursor, t: &str) -> bool { | 80 | fn eat_ident(cursor: &mut Cursor, t: &str) -> bool { |
81 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) = cursor.token_tree() { | 81 | if let Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Ident(ident), _)) = cursor.token_tree() { |
82 | if t == ident.text.as_str() { | 82 | if t == ident.text.as_str() { |
83 | *cursor = cursor.bump(); | 83 | *cursor = cursor.bump(); |
84 | return true; | 84 | return true; |
@@ -88,7 +88,7 @@ fn eat_ident(cursor: &mut Cursor, t: &str) -> bool { | |||
88 | } | 88 | } |
89 | 89 | ||
90 | fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> { | 90 | fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> { |
91 | let buffer = TokenBuffer::new(&tt.token_trees); | 91 | let buffer = TokenBuffer::from_tokens(&tt.token_trees); |
92 | let mut p = buffer.begin(); | 92 | let mut p = buffer.begin(); |
93 | let mut result = tt::Subtree::default(); | 93 | let mut result = tt::Subtree::default(); |
94 | 94 | ||
@@ -106,7 +106,7 @@ fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> { | |||
106 | } | 106 | } |
107 | } | 107 | } |
108 | 108 | ||
109 | result.token_trees.push(curr.token_tree()?.clone()); | 109 | result.token_trees.push(curr.token_tree()?.cloned()); |
110 | p = curr.bump(); | 110 | p = curr.bump(); |
111 | } | 111 | } |
112 | 112 | ||