aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ide_assists/src/handlers/pull_assignment_up.rs43
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs80
-rw-r--r--crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt2
3 files changed, 86 insertions, 39 deletions
diff --git a/crates/ide_assists/src/handlers/pull_assignment_up.rs b/crates/ide_assists/src/handlers/pull_assignment_up.rs
index 13e1cb754..377ed4f2f 100644
--- a/crates/ide_assists/src/handlers/pull_assignment_up.rs
+++ b/crates/ide_assists/src/handlers/pull_assignment_up.rs
@@ -156,6 +156,17 @@ fn is_equivalent(
156 false 156 false
157 } 157 }
158 } 158 }
159 (ast::Expr::PrefixExpr(prefix0), ast::Expr::PrefixExpr(prefix1))
160 if prefix0.op_kind() == Some(ast::PrefixOp::Deref)
161 && prefix1.op_kind() == Some(ast::PrefixOp::Deref) =>
162 {
163 mark::hit!(test_pull_assignment_up_deref);
164 if let (Some(prefix0), Some(prefix1)) = (prefix0.expr(), prefix1.expr()) {
165 is_equivalent(sema, &prefix0, &prefix1)
166 } else {
167 false
168 }
169 }
159 _ => false, 170 _ => false,
160 } 171 }
161} 172}
@@ -397,4 +408,36 @@ fn foo() {
397}"#, 408}"#,
398 ) 409 )
399 } 410 }
411
412 #[test]
413 fn test_pull_assignment_up_deref() {
414 mark::check!(test_pull_assignment_up_deref);
415 check_assist(
416 pull_assignment_up,
417 r#"
418fn foo() {
419 let mut a = 1;
420 let b = &mut a;
421
422 if true {
423 $0*b = 2;
424 } else {
425 *b = 3;
426 }
427}
428"#,
429 r#"
430fn foo() {
431 let mut a = 1;
432 let b = &mut a;
433
434 *b = if true {
435 2
436 } else {
437 3
438 };
439}
440"#,
441 )
442 }
400} 443}
diff --git a/crates/proc_macro_srv/src/rustc_server.rs b/crates/proc_macro_srv/src/rustc_server.rs
index 952b4a97f..14c853c77 100644
--- a/crates/proc_macro_srv/src/rustc_server.rs
+++ b/crates/proc_macro_srv/src/rustc_server.rs
@@ -184,6 +184,7 @@ pub mod token_stream {
184 let (subtree, _token_map) = 184 let (subtree, _token_map) =
185 mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?; 185 mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?;
186 186
187 let subtree = subtree_replace_token_ids_with_unspecified(subtree);
187 Ok(TokenStream { subtree }) 188 Ok(TokenStream { subtree })
188 } 189 }
189 } 190 }
@@ -226,6 +227,44 @@ pub mod token_stream {
226 } 227 }
227 } 228 }
228 } 229 }
230
231 fn subtree_replace_token_ids_with_unspecified(subtree: tt::Subtree) -> tt::Subtree {
232 tt::Subtree {
233 delimiter: subtree
234 .delimiter
235 .map(|d| tt::Delimiter { id: tt::TokenId::unspecified(), ..d }),
236 token_trees: subtree
237 .token_trees
238 .into_iter()
239 .map(|t| token_tree_replace_token_ids_with_unspecified(t))
240 .collect(),
241 }
242 }
243
244 fn token_tree_replace_token_ids_with_unspecified(tt: tt::TokenTree) -> tt::TokenTree {
245 match tt {
246 tt::TokenTree::Leaf(leaf) => {
247 tt::TokenTree::Leaf(leaf_replace_token_ids_with_unspecified(leaf))
248 }
249 tt::TokenTree::Subtree(subtree) => {
250 tt::TokenTree::Subtree(subtree_replace_token_ids_with_unspecified(subtree))
251 }
252 }
253 }
254
255 fn leaf_replace_token_ids_with_unspecified(leaf: tt::Leaf) -> tt::Leaf {
256 match leaf {
257 tt::Leaf::Literal(lit) => {
258 tt::Leaf::Literal(tt::Literal { id: tt::TokenId::unspecified(), ..lit })
259 }
260 tt::Leaf::Punct(punct) => {
261 tt::Leaf::Punct(tt::Punct { id: tt::TokenId::unspecified(), ..punct })
262 }
263 tt::Leaf::Ident(ident) => {
264 tt::Leaf::Ident(tt::Ident { id: tt::TokenId::unspecified(), ..ident })
265 }
266 }
267 }
229} 268}
230 269
231impl TokenStreamBuilder { 270impl TokenStreamBuilder {
@@ -277,42 +316,6 @@ impl server::FreeFunctions for Rustc {
277 } 316 }
278} 317}
279 318
280fn subtree_replace_token_ids_with_unspecified(subtree: tt::Subtree) -> tt::Subtree {
281 tt::Subtree {
282 delimiter: subtree.delimiter.map(|d| tt::Delimiter { id: tt::TokenId::unspecified(), ..d }),
283 token_trees: subtree
284 .token_trees
285 .into_iter()
286 .map(|t| token_tree_replace_token_ids_with_unspecified(t))
287 .collect(),
288 }
289}
290
291fn token_tree_replace_token_ids_with_unspecified(tt: tt::TokenTree) -> tt::TokenTree {
292 match tt {
293 tt::TokenTree::Leaf(leaf) => {
294 tt::TokenTree::Leaf(leaf_replace_token_ids_with_unspecified(leaf))
295 }
296 tt::TokenTree::Subtree(subtree) => {
297 tt::TokenTree::Subtree(subtree_replace_token_ids_with_unspecified(subtree))
298 }
299 }
300}
301
302fn leaf_replace_token_ids_with_unspecified(leaf: tt::Leaf) -> tt::Leaf {
303 match leaf {
304 tt::Leaf::Literal(lit) => {
305 tt::Leaf::Literal(tt::Literal { id: tt::TokenId::unspecified(), ..lit })
306 }
307 tt::Leaf::Punct(punct) => {
308 tt::Leaf::Punct(tt::Punct { id: tt::TokenId::unspecified(), ..punct })
309 }
310 tt::Leaf::Ident(ident) => {
311 tt::Leaf::Ident(tt::Ident { id: tt::TokenId::unspecified(), ..ident })
312 }
313 }
314}
315
316impl server::TokenStream for Rustc { 319impl server::TokenStream for Rustc {
317 fn new(&mut self) -> Self::TokenStream { 320 fn new(&mut self) -> Self::TokenStream {
318 Self::TokenStream::new() 321 Self::TokenStream::new()
@@ -322,8 +325,9 @@ impl server::TokenStream for Rustc {
322 stream.is_empty() 325 stream.is_empty()
323 } 326 }
324 fn from_str(&mut self, src: &str) -> Self::TokenStream { 327 fn from_str(&mut self, src: &str) -> Self::TokenStream {
325 let (subtree, _) = mbe::parse_to_token_tree(src).expect("cannot parse string"); 328 use std::str::FromStr;
326 TokenStream::with_subtree(subtree_replace_token_ids_with_unspecified(subtree)) 329
330 Self::TokenStream::from_str(src).expect("cannot parse string")
327 } 331 }
328 fn to_string(&mut self, stream: &Self::TokenStream) -> String { 332 fn to_string(&mut self, stream: &Self::TokenStream) -> String {
329 stream.to_string() 333 stream.to_string()
diff --git a/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt b/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
index ea34e688f..fa581f110 100644
--- a/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
+++ b/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt
@@ -101,7 +101,7 @@ SUBTREE $
101 PUNCH : [alone] 4294967295 101 PUNCH : [alone] 4294967295
102 IDENT Serialize 4294967295 102 IDENT Serialize 4294967295
103 IDENT for 4294967295 103 IDENT for 4294967295
104 IDENT Foo 1 104 IDENT Foo 4294967295
105 SUBTREE {} 4294967295 105 SUBTREE {} 4294967295
106 IDENT fn 4294967295 106 IDENT fn 4294967295
107 IDENT serialize 4294967295 107 IDENT serialize 4294967295