diff options
author | Seivan Heidari <[email protected]> | 2019-10-31 08:43:20 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-10-31 08:43:20 +0000 |
commit | 8edda0e7b164009d6c03bb3d4be603fb38ad2e2a (patch) | |
tree | 744cf81075d394e2f9c06afb07642a2601800dda /docs/user | |
parent | 49562d36b97ddde34cf7585a8c2e8f232519b657 (diff) | |
parent | d067afb064a7fa67b172abf561b7d80740cd6f18 (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'docs/user')
-rw-r--r-- | docs/user/README.md | 19 | ||||
-rw-r--r-- | docs/user/assists.md | 505 | ||||
-rw-r--r-- | docs/user/features.md | 424 |
3 files changed, 527 insertions, 421 deletions
diff --git a/docs/user/README.md b/docs/user/README.md index f1628d6a4..eb1d5ed14 100644 --- a/docs/user/README.md +++ b/docs/user/README.md | |||
@@ -83,8 +83,6 @@ host. | |||
83 | ### Settings | 83 | ### Settings |
84 | 84 | ||
85 | * `rust-analyzer.highlightingOn`: enables experimental syntax highlighting | 85 | * `rust-analyzer.highlightingOn`: enables experimental syntax highlighting |
86 | * `rust-analyzer.showWorkspaceLoadedNotification`: to ease troubleshooting, a | ||
87 | notification is shown by default when a workspace is loaded | ||
88 | * `rust-analyzer.enableEnhancedTyping`: by default, rust-analyzer intercepts | 86 | * `rust-analyzer.enableEnhancedTyping`: by default, rust-analyzer intercepts |
89 | `Enter` key to make it easier to continue comments. Note that it may conflict with VIM emulation plugin. | 87 | `Enter` key to make it easier to continue comments. Note that it may conflict with VIM emulation plugin. |
90 | * `rust-analyzer.raLspServerPath`: path to `ra_lsp_server` executable | 88 | * `rust-analyzer.raLspServerPath`: path to `ra_lsp_server` executable |
@@ -102,6 +100,17 @@ host. | |||
102 | * `rust-analyzer.trace.server`: enables internal logging | 100 | * `rust-analyzer.trace.server`: enables internal logging |
103 | * `rust-analyzer.trace.cargo-watch`: enables cargo-watch logging | 101 | * `rust-analyzer.trace.cargo-watch`: enables cargo-watch logging |
104 | * `RUST_SRC_PATH`: environment variable that overwrites the sysroot | 102 | * `RUST_SRC_PATH`: environment variable that overwrites the sysroot |
103 | * `rust-analyzer.featureFlags` -- a JSON object to tweak fine-grained behavior: | ||
104 | ```js | ||
105 | { | ||
106 | // Show diagnostics produced by rust-analyzer itself. | ||
107 | "lsp.diagnostics": true, | ||
108 | // Automatically insert `()` and `<>` when completing functions and types. | ||
109 | "completion.insertion.add-call-parenthesis": true, | ||
110 | // Show notification when workspace is fully loaded | ||
111 | "notifications.workspace-loaded": true, | ||
112 | } | ||
113 | ``` | ||
105 | 114 | ||
106 | 115 | ||
107 | ## Emacs | 116 | ## Emacs |
@@ -173,7 +182,11 @@ Installation: | |||
173 | "syntaxes": [ | 182 | "syntaxes": [ |
174 | "Packages/Rust/Rust.sublime-syntax", | 183 | "Packages/Rust/Rust.sublime-syntax", |
175 | "Packages/Rust Enhanced/RustEnhanced.sublime-syntax" | 184 | "Packages/Rust Enhanced/RustEnhanced.sublime-syntax" |
176 | ] | 185 | ], |
186 | "initializationOptions": { | ||
187 | "featureFlags": { | ||
188 | } | ||
189 | }, | ||
177 | } | 190 | } |
178 | ``` | 191 | ``` |
179 | 192 | ||
diff --git a/docs/user/assists.md b/docs/user/assists.md new file mode 100644 index 000000000..303353e74 --- /dev/null +++ b/docs/user/assists.md | |||
@@ -0,0 +1,505 @@ | |||
1 | # Assists | ||
2 | |||
3 | Cursor position or selection is signified by `┃` character. | ||
4 | |||
5 | |||
6 | ## `add_derive` | ||
7 | |||
8 | Adds a new `#[derive()]` clause to a struct or enum. | ||
9 | |||
10 | ```rust | ||
11 | // BEFORE | ||
12 | struct Point { | ||
13 | x: u32, | ||
14 | y: u32,┃ | ||
15 | } | ||
16 | |||
17 | // AFTER | ||
18 | #[derive()] | ||
19 | struct Point { | ||
20 | x: u32, | ||
21 | y: u32, | ||
22 | } | ||
23 | ``` | ||
24 | |||
25 | ## `add_explicit_type` | ||
26 | |||
27 | Specify type for a let binding. | ||
28 | |||
29 | ```rust | ||
30 | // BEFORE | ||
31 | fn main() { | ||
32 | let x┃ = 92; | ||
33 | } | ||
34 | |||
35 | // AFTER | ||
36 | fn main() { | ||
37 | let x: i32 = 92; | ||
38 | } | ||
39 | ``` | ||
40 | |||
41 | ## `add_hash` | ||
42 | |||
43 | Adds a hash to a raw string literal. | ||
44 | |||
45 | ```rust | ||
46 | // BEFORE | ||
47 | fn main() { | ||
48 | r#"Hello,┃ World!"#; | ||
49 | } | ||
50 | |||
51 | // AFTER | ||
52 | fn main() { | ||
53 | r##"Hello, World!"##; | ||
54 | } | ||
55 | ``` | ||
56 | |||
57 | ## `add_impl` | ||
58 | |||
59 | Adds a new inherent impl for a type. | ||
60 | |||
61 | ```rust | ||
62 | // BEFORE | ||
63 | struct Ctx<T: Clone> { | ||
64 | data: T,┃ | ||
65 | } | ||
66 | |||
67 | // AFTER | ||
68 | struct Ctx<T: Clone> { | ||
69 | data: T, | ||
70 | } | ||
71 | |||
72 | impl<T: Clone> Ctx<T> { | ||
73 | |||
74 | } | ||
75 | ``` | ||
76 | |||
77 | ## `add_impl_default_members` | ||
78 | |||
79 | Adds scaffold for overriding default impl members. | ||
80 | |||
81 | ```rust | ||
82 | // BEFORE | ||
83 | trait T { | ||
84 | Type X; | ||
85 | fn foo(&self); | ||
86 | fn bar(&self) {} | ||
87 | } | ||
88 | |||
89 | impl T for () { | ||
90 | Type X = (); | ||
91 | fn foo(&self) {}┃ | ||
92 | |||
93 | } | ||
94 | |||
95 | // AFTER | ||
96 | trait T { | ||
97 | Type X; | ||
98 | fn foo(&self); | ||
99 | fn bar(&self) {} | ||
100 | } | ||
101 | |||
102 | impl T for () { | ||
103 | Type X = (); | ||
104 | fn foo(&self) {} | ||
105 | fn bar(&self) {} | ||
106 | |||
107 | } | ||
108 | ``` | ||
109 | |||
110 | ## `add_impl_missing_members` | ||
111 | |||
112 | Adds scaffold for required impl members. | ||
113 | |||
114 | ```rust | ||
115 | // BEFORE | ||
116 | trait T { | ||
117 | Type X; | ||
118 | fn foo(&self); | ||
119 | fn bar(&self) {} | ||
120 | } | ||
121 | |||
122 | impl T for () {┃ | ||
123 | |||
124 | } | ||
125 | |||
126 | // AFTER | ||
127 | trait T { | ||
128 | Type X; | ||
129 | fn foo(&self); | ||
130 | fn bar(&self) {} | ||
131 | } | ||
132 | |||
133 | impl T for () { | ||
134 | fn foo(&self) { unimplemented!() } | ||
135 | |||
136 | } | ||
137 | ``` | ||
138 | |||
139 | ## `add_import` | ||
140 | |||
141 | Adds a use statement for a given fully-qualified path. | ||
142 | |||
143 | ```rust | ||
144 | // BEFORE | ||
145 | fn process(map: std::collections::┃HashMap<String, String>) {} | ||
146 | |||
147 | // AFTER | ||
148 | use std::collections::HashMap; | ||
149 | |||
150 | fn process(map: HashMap<String, String>) {} | ||
151 | ``` | ||
152 | |||
153 | ## `apply_demorgan` | ||
154 | |||
155 | Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws). | ||
156 | This transforms expressions of the form `!l || !r` into `!(l && r)`. | ||
157 | This also works with `&&`. This assist can only be applied with the cursor | ||
158 | on either `||` or `&&`, with both operands being a negation of some kind. | ||
159 | This means something of the form `!x` or `x != y`. | ||
160 | |||
161 | ```rust | ||
162 | // BEFORE | ||
163 | fn main() { | ||
164 | if x != 4 ||┃ !y {} | ||
165 | } | ||
166 | |||
167 | // AFTER | ||
168 | fn main() { | ||
169 | if !(x == 4 && y) {} | ||
170 | } | ||
171 | ``` | ||
172 | |||
173 | ## `change_visibility` | ||
174 | |||
175 | Adds or changes existing visibility specifier. | ||
176 | |||
177 | ```rust | ||
178 | // BEFORE | ||
179 | ┃fn frobnicate() {} | ||
180 | |||
181 | // AFTER | ||
182 | pub(crate) fn frobnicate() {} | ||
183 | ``` | ||
184 | |||
185 | ## `convert_to_guarded_return` | ||
186 | |||
187 | Replace a large conditional with a guarded return. | ||
188 | |||
189 | ```rust | ||
190 | // BEFORE | ||
191 | fn main() { | ||
192 | ┃if cond { | ||
193 | foo(); | ||
194 | bar(); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | // AFTER | ||
199 | fn main() { | ||
200 | if !cond { | ||
201 | return; | ||
202 | } | ||
203 | foo(); | ||
204 | bar(); | ||
205 | } | ||
206 | ``` | ||
207 | |||
208 | ## `fill_match_arms` | ||
209 | |||
210 | Adds missing clauses to a `match` expression. | ||
211 | |||
212 | ```rust | ||
213 | // BEFORE | ||
214 | enum Action { Move { distance: u32 }, Stop } | ||
215 | |||
216 | fn handle(action: Action) { | ||
217 | match action { | ||
218 | ┃ | ||
219 | } | ||
220 | } | ||
221 | |||
222 | // AFTER | ||
223 | enum Action { Move { distance: u32 }, Stop } | ||
224 | |||
225 | fn handle(action: Action) { | ||
226 | match action { | ||
227 | Action::Move { distance } => (), | ||
228 | Action::Stop => (), | ||
229 | } | ||
230 | } | ||
231 | ``` | ||
232 | |||
233 | ## `flip_binexpr` | ||
234 | |||
235 | Flips operands of a binary expression. | ||
236 | |||
237 | ```rust | ||
238 | // BEFORE | ||
239 | fn main() { | ||
240 | let _ = 90 +┃ 2; | ||
241 | } | ||
242 | |||
243 | // AFTER | ||
244 | fn main() { | ||
245 | let _ = 2 + 90; | ||
246 | } | ||
247 | ``` | ||
248 | |||
249 | ## `flip_comma` | ||
250 | |||
251 | Flips two comma-separated items. | ||
252 | |||
253 | ```rust | ||
254 | // BEFORE | ||
255 | fn main() { | ||
256 | ((1, 2),┃ (3, 4)); | ||
257 | } | ||
258 | |||
259 | // AFTER | ||
260 | fn main() { | ||
261 | ((3, 4), (1, 2)); | ||
262 | } | ||
263 | ``` | ||
264 | |||
265 | ## `flip_trait_bound` | ||
266 | |||
267 | Flips two trait bounds. | ||
268 | |||
269 | ```rust | ||
270 | // BEFORE | ||
271 | fn foo<T: Clone +┃ Copy>() { } | ||
272 | |||
273 | // AFTER | ||
274 | fn foo<T: Copy + Clone>() { } | ||
275 | ``` | ||
276 | |||
277 | ## `inline_local_variable` | ||
278 | |||
279 | Inlines local variable. | ||
280 | |||
281 | ```rust | ||
282 | // BEFORE | ||
283 | fn main() { | ||
284 | let x┃ = 1 + 2; | ||
285 | x * 4; | ||
286 | } | ||
287 | |||
288 | // AFTER | ||
289 | fn main() { | ||
290 | (1 + 2) * 4; | ||
291 | } | ||
292 | ``` | ||
293 | |||
294 | ## `introduce_variable` | ||
295 | |||
296 | Extracts subexpression into a variable. | ||
297 | |||
298 | ```rust | ||
299 | // BEFORE | ||
300 | fn main() { | ||
301 | ┃(1 + 2)┃ * 4; | ||
302 | } | ||
303 | |||
304 | // AFTER | ||
305 | fn main() { | ||
306 | let var_name = (1 + 2); | ||
307 | var_name * 4; | ||
308 | } | ||
309 | ``` | ||
310 | |||
311 | ## `make_raw_string` | ||
312 | |||
313 | Adds `r#` to a plain string literal. | ||
314 | |||
315 | ```rust | ||
316 | // BEFORE | ||
317 | fn main() { | ||
318 | "Hello,┃ World!"; | ||
319 | } | ||
320 | |||
321 | // AFTER | ||
322 | fn main() { | ||
323 | r#"Hello, World!"#; | ||
324 | } | ||
325 | ``` | ||
326 | |||
327 | ## `make_usual_string` | ||
328 | |||
329 | Turns a raw string into a plain string. | ||
330 | |||
331 | ```rust | ||
332 | // BEFORE | ||
333 | fn main() { | ||
334 | r#"Hello,┃ "World!""#; | ||
335 | } | ||
336 | |||
337 | // AFTER | ||
338 | fn main() { | ||
339 | "Hello, \"World!\""; | ||
340 | } | ||
341 | ``` | ||
342 | |||
343 | ## `merge_match_arms` | ||
344 | |||
345 | Merges identical match arms. | ||
346 | |||
347 | ```rust | ||
348 | // BEFORE | ||
349 | enum Action { Move { distance: u32 }, Stop } | ||
350 | |||
351 | fn handle(action: Action) { | ||
352 | match action { | ||
353 | ┃Action::Move(..) => foo(), | ||
354 | Action::Stop => foo(), | ||
355 | } | ||
356 | } | ||
357 | |||
358 | // AFTER | ||
359 | enum Action { Move { distance: u32 }, Stop } | ||
360 | |||
361 | fn handle(action: Action) { | ||
362 | match action { | ||
363 | Action::Move(..) | Action::Stop => foo(), | ||
364 | } | ||
365 | } | ||
366 | ``` | ||
367 | |||
368 | ## `move_arm_cond_to_match_guard` | ||
369 | |||
370 | Moves if expression from match arm body into a guard. | ||
371 | |||
372 | ```rust | ||
373 | // BEFORE | ||
374 | enum Action { Move { distance: u32 }, Stop } | ||
375 | |||
376 | fn handle(action: Action) { | ||
377 | match action { | ||
378 | Action::Move { distance } => ┃if distance > 10 { foo() }, | ||
379 | _ => (), | ||
380 | } | ||
381 | } | ||
382 | |||
383 | // AFTER | ||
384 | enum Action { Move { distance: u32 }, Stop } | ||
385 | |||
386 | fn handle(action: Action) { | ||
387 | match action { | ||
388 | Action::Move { distance } if distance > 10 => foo(), | ||
389 | _ => (), | ||
390 | } | ||
391 | } | ||
392 | ``` | ||
393 | |||
394 | ## `move_bounds_to_where_clause` | ||
395 | |||
396 | Moves inline type bounds to a where clause. | ||
397 | |||
398 | ```rust | ||
399 | // BEFORE | ||
400 | fn apply<T, U, ┃F: FnOnce(T) -> U>(f: F, x: T) -> U { | ||
401 | f(x) | ||
402 | } | ||
403 | |||
404 | // AFTER | ||
405 | fn apply<T, U, F>(f: F, x: T) -> U where F: FnOnce(T) -> U { | ||
406 | f(x) | ||
407 | } | ||
408 | ``` | ||
409 | |||
410 | ## `move_guard_to_arm_body` | ||
411 | |||
412 | Moves match guard into match arm body. | ||
413 | |||
414 | ```rust | ||
415 | // BEFORE | ||
416 | enum Action { Move { distance: u32 }, Stop } | ||
417 | |||
418 | fn handle(action: Action) { | ||
419 | match action { | ||
420 | Action::Move { distance } ┃if distance > 10 => foo(), | ||
421 | _ => (), | ||
422 | } | ||
423 | } | ||
424 | |||
425 | // AFTER | ||
426 | enum Action { Move { distance: u32 }, Stop } | ||
427 | |||
428 | fn handle(action: Action) { | ||
429 | match action { | ||
430 | Action::Move { distance } => if distance > 10 { foo() }, | ||
431 | _ => (), | ||
432 | } | ||
433 | } | ||
434 | ``` | ||
435 | |||
436 | ## `remove_dbg` | ||
437 | |||
438 | Removes `dbg!()` macro call. | ||
439 | |||
440 | ```rust | ||
441 | // BEFORE | ||
442 | fn main() { | ||
443 | ┃dbg!(92); | ||
444 | } | ||
445 | |||
446 | // AFTER | ||
447 | fn main() { | ||
448 | 92; | ||
449 | } | ||
450 | ``` | ||
451 | |||
452 | ## `remove_hash` | ||
453 | |||
454 | Removes a hash from a raw string literal. | ||
455 | |||
456 | ```rust | ||
457 | // BEFORE | ||
458 | fn main() { | ||
459 | r#"Hello,┃ World!"#; | ||
460 | } | ||
461 | |||
462 | // AFTER | ||
463 | fn main() { | ||
464 | r"Hello, World!"; | ||
465 | } | ||
466 | ``` | ||
467 | |||
468 | ## `replace_if_let_with_match` | ||
469 | |||
470 | Replaces `if let` with an else branch with a `match` expression. | ||
471 | |||
472 | ```rust | ||
473 | // BEFORE | ||
474 | enum Action { Move { distance: u32 }, Stop } | ||
475 | |||
476 | fn handle(action: Action) { | ||
477 | ┃if let Action::Move { distance } = action { | ||
478 | foo(distance) | ||
479 | } else { | ||
480 | bar() | ||
481 | } | ||
482 | } | ||
483 | |||
484 | // AFTER | ||
485 | enum Action { Move { distance: u32 }, Stop } | ||
486 | |||
487 | fn handle(action: Action) { | ||
488 | match action { | ||
489 | Action::Move { distance } => foo(distance), | ||
490 | _ => bar(), | ||
491 | } | ||
492 | } | ||
493 | ``` | ||
494 | |||
495 | ## `split_import` | ||
496 | |||
497 | Wraps the tail of import into braces. | ||
498 | |||
499 | ```rust | ||
500 | // BEFORE | ||
501 | use std::┃collections::HashMap; | ||
502 | |||
503 | // AFTER | ||
504 | use std::{collections::HashMap}; | ||
505 | ``` | ||
diff --git a/docs/user/features.md b/docs/user/features.md index 8b7a8d7fc..c160dd70b 100644 --- a/docs/user/features.md +++ b/docs/user/features.md | |||
@@ -97,424 +97,12 @@ Start `cargo watch` for live error highlighting. Will prompt to install if it's | |||
97 | 97 | ||
98 | Stop `cargo watch` | 98 | Stop `cargo watch` |
99 | 99 | ||
100 | ### Code Actions (Assists) | 100 | ### Assists (Code Actions) |
101 | 101 | ||
102 | These are triggered in a particular context via light bulb. We use custom code on | 102 | Assists, or code actions, are small local refactorings, available in a particular context. |
103 | the VS Code side to be able to position cursor. `<|>` signifies cursor | 103 | They are usually triggered by a shortcut or by clicking a light bulb icon in the editor. |
104 | 104 | ||
105 | - Add `#[derive]` | 105 | See [assists.md](./assists.md) for the list of available assists. |
106 | |||
107 | ```rust | ||
108 | // before: | ||
109 | struct Foo { | ||
110 | <|>x: i32 | ||
111 | } | ||
112 | // after: | ||
113 | #[derive(<|>)] | ||
114 | struct Foo { | ||
115 | x: i32 | ||
116 | } | ||
117 | ``` | ||
118 | |||
119 | - Add `impl` | ||
120 | |||
121 | ```rust | ||
122 | // before: | ||
123 | struct Foo<'a, T: Debug> { | ||
124 | <|>t: T | ||
125 | } | ||
126 | // after: | ||
127 | struct Foo<'a, T: Debug> { | ||
128 | t: T | ||
129 | } | ||
130 | |||
131 | impl<'a, T: Debug> Foo<'a, T> { | ||
132 | <|> | ||
133 | } | ||
134 | ``` | ||
135 | |||
136 | - Add missing `impl` members | ||
137 | |||
138 | ```rust | ||
139 | // before: | ||
140 | trait Foo { | ||
141 | fn foo(&self); | ||
142 | fn bar(&self); | ||
143 | fn baz(&self); | ||
144 | } | ||
145 | |||
146 | struct S; | ||
147 | |||
148 | impl Foo for S { | ||
149 | fn bar(&self) {} | ||
150 | <|> | ||
151 | } | ||
152 | |||
153 | // after: | ||
154 | trait Foo { | ||
155 | fn foo(&self); | ||
156 | fn bar(&self); | ||
157 | fn baz(&self); | ||
158 | } | ||
159 | |||
160 | struct S; | ||
161 | |||
162 | impl Foo for S { | ||
163 | fn bar(&self) {} | ||
164 | fn foo(&self) { unimplemented!() } | ||
165 | fn baz(&self) { unimplemented!() }<|> | ||
166 | } | ||
167 | ``` | ||
168 | |||
169 | - Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) | ||
170 | |||
171 | ```rust | ||
172 | // before: | ||
173 | fn example(x: bool) -> bool { | ||
174 | !x || !x | ||
175 | } | ||
176 | |||
177 | // after: | ||
178 | fn example(x: bool) -> bool { | ||
179 | !(x && x) | ||
180 | } | ||
181 | ``` | ||
182 | |||
183 | - Import path | ||
184 | |||
185 | ```rust | ||
186 | // before: | ||
187 | impl std::fmt::Debug<|> for Foo { | ||
188 | } | ||
189 | |||
190 | // after: | ||
191 | use std::fmt::Debug; | ||
192 | |||
193 | impl Debug<|> for Foo { | ||
194 | } | ||
195 | ``` | ||
196 | |||
197 | - Change Visibility | ||
198 | |||
199 | ```rust | ||
200 | // before: | ||
201 | <|>fn foo() {} | ||
202 | |||
203 | // after: | ||
204 | <|>pub(crate) fn foo() {} | ||
205 | |||
206 | // after: | ||
207 | <|>pub fn foo() {} | ||
208 | ``` | ||
209 | |||
210 | - Fill match arms | ||
211 | |||
212 | ```rust | ||
213 | // before: | ||
214 | enum A { | ||
215 | As, | ||
216 | Bs, | ||
217 | Cs(String), | ||
218 | Ds(String, String), | ||
219 | Es{x: usize, y: usize} | ||
220 | } | ||
221 | |||
222 | fn main() { | ||
223 | let a = A::As; | ||
224 | match a<|> {} | ||
225 | } | ||
226 | |||
227 | // after: | ||
228 | enum A { | ||
229 | As, | ||
230 | Bs, | ||
231 | Cs(String), | ||
232 | Ds(String, String), | ||
233 | Es{x: usize, y: usize} | ||
234 | } | ||
235 | |||
236 | fn main() { | ||
237 | let a = A::As; | ||
238 | match <|>a { | ||
239 | A::As => (), | ||
240 | A::Bs => (), | ||
241 | A::Cs(_) => (), | ||
242 | A::Ds(_, _) => (), | ||
243 | A::Es{x, y} => (), | ||
244 | } | ||
245 | } | ||
246 | ``` | ||
247 | |||
248 | - Fill struct fields | ||
249 | |||
250 | ```rust | ||
251 | // before: | ||
252 | struct S<'a, D> { | ||
253 | a: u32, | ||
254 | b: String, | ||
255 | c: (i32, i32), | ||
256 | d: D, | ||
257 | r: &'a str, | ||
258 | } | ||
259 | |||
260 | fn main() { | ||
261 | let s = S<|> {} | ||
262 | } | ||
263 | |||
264 | // after: | ||
265 | struct S<'a, D> { | ||
266 | a: u32, | ||
267 | b: String, | ||
268 | c: (i32, i32), | ||
269 | d: D, | ||
270 | r: &'a str, | ||
271 | } | ||
272 | |||
273 | fn main() { | ||
274 | let s = <|>S { | ||
275 | a: (), | ||
276 | b: (), | ||
277 | c: (), | ||
278 | d: (), | ||
279 | r: (), | ||
280 | } | ||
281 | } | ||
282 | ``` | ||
283 | |||
284 | - Flip `,` | ||
285 | |||
286 | ```rust | ||
287 | // before: | ||
288 | fn foo(x: usize,<|> dim: (usize, usize)) {} | ||
289 | // after: | ||
290 | fn foo(dim: (usize, usize), x: usize) {} | ||
291 | ``` | ||
292 | |||
293 | - Introduce variable: | ||
294 | |||
295 | ```rust | ||
296 | // before: | ||
297 | fn foo() { | ||
298 | foo(<|>1 + 1<|>); | ||
299 | } | ||
300 | |||
301 | // after: | ||
302 | fn foo() { | ||
303 | let var_name = 1 + 1; | ||
304 | foo(var_name); | ||
305 | } | ||
306 | ``` | ||
307 | |||
308 | - Inline local variable: | ||
309 | |||
310 | ```rust | ||
311 | // before: | ||
312 | fn foo() { | ||
313 | let a<|> = 1 + 1; | ||
314 | let b = a * 10; | ||
315 | } | ||
316 | |||
317 | // after: | ||
318 | fn foo() { | ||
319 | let b = (1 + 1) * 10; | ||
320 | } | ||
321 | ``` | ||
322 | |||
323 | - Remove `dbg!` | ||
324 | |||
325 | ```rust | ||
326 | // before: | ||
327 | fn foo(n: usize) { | ||
328 | if let Some(_) = dbg!(n.<|>checked_sub(4)) { | ||
329 | // ... | ||
330 | } | ||
331 | } | ||
332 | |||
333 | // after: | ||
334 | fn foo(n: usize) { | ||
335 | if let Some(_) = n.<|>checked_sub(4) { | ||
336 | // ... | ||
337 | } | ||
338 | } | ||
339 | ``` | ||
340 | |||
341 | - Replace if-let with match: | ||
342 | |||
343 | ```rust | ||
344 | // before: | ||
345 | impl VariantData { | ||
346 | pub fn is_struct(&self) -> bool { | ||
347 | if <|>let VariantData::Struct(..) = *self { | ||
348 | true | ||
349 | } else { | ||
350 | false | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | |||
355 | // after: | ||
356 | impl VariantData { | ||
357 | pub fn is_struct(&self) -> bool { | ||
358 | <|>match *self { | ||
359 | VariantData::Struct(..) => true, | ||
360 | _ => false, | ||
361 | } | ||
362 | } | ||
363 | } | ||
364 | ``` | ||
365 | |||
366 | - Split import | ||
367 | |||
368 | ```rust | ||
369 | // before: | ||
370 | use crate:<|>:db::{RootDatabase, FileSymbol}; | ||
371 | // after: | ||
372 | use crate::{<|>db::{RootDatabase, FileSymbol}}; | ||
373 | ``` | ||
374 | |||
375 | - Flip binary expression | ||
376 | |||
377 | ```rust | ||
378 | // before: | ||
379 | fn foo() { | ||
380 | if 1 <<|> 2 { | ||
381 | println!("Who would have thought?"); | ||
382 | } | ||
383 | } | ||
384 | // after: | ||
385 | fn foo() { | ||
386 | if 2 ><|> 1 { | ||
387 | println!("Who would have thought?"); | ||
388 | } | ||
389 | } | ||
390 | ``` | ||
391 | |||
392 | - Add explicit type | ||
393 | |||
394 | ```rust | ||
395 | // before: | ||
396 | fn foo() { | ||
397 | let t<|> = (&2, Some(1)); | ||
398 | } | ||
399 | // after: | ||
400 | fn foo() { | ||
401 | let t<|>: (&i32, Option<i32>) = (&2, Some(1)); | ||
402 | } | ||
403 | ``` | ||
404 | |||
405 | - Move guard expression to match arm body | ||
406 | ```rust | ||
407 | // before: | ||
408 | fn f() { | ||
409 | match x { | ||
410 | <|>y @ 4 | y @ 5 if y > 5 => true, | ||
411 | _ => false | ||
412 | } | ||
413 | } | ||
414 | // after: | ||
415 | fn f() { | ||
416 | match x { | ||
417 | y @ 4 | y @ 5 => if y > 5 { <|>true }, | ||
418 | _ => false | ||
419 | } | ||
420 | } | ||
421 | ``` | ||
422 | |||
423 | - Move if condition to match arm guard | ||
424 | ```rust | ||
425 | // before: | ||
426 | fn f() { | ||
427 | let mut t = 'a'; | ||
428 | let chars = "abcd"; | ||
429 | match t { | ||
430 | '\r' => if chars.clone().next().is_some() { | ||
431 | t = 'e';<|> | ||
432 | false | ||
433 | }, | ||
434 | _ => true | ||
435 | } | ||
436 | } | ||
437 | |||
438 | // after: | ||
439 | fn f() { | ||
440 | let mut t = 'a'; | ||
441 | let chars = "abcd"; | ||
442 | match t { | ||
443 | '\r' <|>if chars.clone().next().is_some() => { | ||
444 | t = 'e'; | ||
445 | false | ||
446 | }, | ||
447 | _ => true | ||
448 | } | ||
449 | } | ||
450 | ``` | ||
451 | |||
452 | - Move type bounds to where clause | ||
453 | |||
454 | ```rust | ||
455 | // before: | ||
456 | fn foo<T: u32, F: FnOnce(T) -> T>() {} | ||
457 | |||
458 | // after: | ||
459 | fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {} | ||
460 | ``` | ||
461 | |||
462 | - Make raw string unescaped | ||
463 | |||
464 | ```rust | ||
465 | // before: | ||
466 | fn f() { | ||
467 | let s = <|>"ab\ncd"; | ||
468 | } | ||
469 | |||
470 | // after: | ||
471 | fn f() { | ||
472 | let s = <|>r#"ab | ||
473 | cd"#; | ||
474 | } | ||
475 | ``` | ||
476 | |||
477 | - Make usual string | ||
478 | |||
479 | ```rust | ||
480 | // before: | ||
481 | fn f() { | ||
482 | let s = <|>r#"abcd"#; | ||
483 | } | ||
484 | |||
485 | // after: | ||
486 | fn f() { | ||
487 | let s = <|>"abcd"; | ||
488 | } | ||
489 | ``` | ||
490 | |||
491 | - Add hash | ||
492 | |||
493 | ```rust | ||
494 | // before: | ||
495 | fn f() { | ||
496 | let s = <|>r"abcd"; | ||
497 | } | ||
498 | |||
499 | // after: | ||
500 | fn f() { | ||
501 | let s = <|>r#"abcd"#; | ||
502 | } | ||
503 | ``` | ||
504 | |||
505 | - Remove hash | ||
506 | |||
507 | ```rust | ||
508 | // before: | ||
509 | fn f() { | ||
510 | let s = <|>r#"abcd"#; | ||
511 | } | ||
512 | |||
513 | // after: | ||
514 | fn f() { | ||
515 | let s = <|>r"abcd"; | ||
516 | } | ||
517 | ``` | ||
518 | 106 | ||
519 | ### Magic Completions | 107 | ### Magic Completions |
520 | 108 | ||