diff options
60 files changed, 2339 insertions, 755 deletions
diff --git a/crates/ra_cargo_watch/src/conv.rs b/crates/ra_cargo_watch/src/conv.rs index 0246adfb5..c6f8ca329 100644 --- a/crates/ra_cargo_watch/src/conv.rs +++ b/crates/ra_cargo_watch/src/conv.rs | |||
@@ -8,6 +8,7 @@ use lsp_types::{ | |||
8 | Location, NumberOrString, Position, Range, TextEdit, Url, WorkspaceEdit, | 8 | Location, NumberOrString, Position, Range, TextEdit, Url, WorkspaceEdit, |
9 | }; | 9 | }; |
10 | use std::{ | 10 | use std::{ |
11 | collections::HashMap, | ||
11 | fmt::Write, | 12 | fmt::Write, |
12 | path::{Component, Path, PathBuf, Prefix}, | 13 | path::{Component, Path, PathBuf, Prefix}, |
13 | str::FromStr, | 14 | str::FromStr, |
@@ -126,44 +127,34 @@ fn map_rust_child_diagnostic( | |||
126 | rd: &RustDiagnostic, | 127 | rd: &RustDiagnostic, |
127 | workspace_root: &PathBuf, | 128 | workspace_root: &PathBuf, |
128 | ) -> MappedRustChildDiagnostic { | 129 | ) -> MappedRustChildDiagnostic { |
129 | let span: &DiagnosticSpan = match rd.spans.iter().find(|s| s.is_primary) { | 130 | let spans: Vec<&DiagnosticSpan> = rd.spans.iter().filter(|s| s.is_primary).collect(); |
130 | Some(span) => span, | 131 | if spans.is_empty() { |
131 | None => { | 132 | // `rustc` uses these spanless children as a way to print multi-line |
132 | // `rustc` uses these spanless children as a way to print multi-line | 133 | // messages |
133 | // messages | 134 | return MappedRustChildDiagnostic::MessageLine(rd.message.clone()); |
134 | return MappedRustChildDiagnostic::MessageLine(rd.message.clone()); | 135 | } |
136 | |||
137 | let mut edit_map: HashMap<Url, Vec<TextEdit>> = HashMap::new(); | ||
138 | for &span in &spans { | ||
139 | if let Some(suggested_replacement) = &span.suggested_replacement { | ||
140 | let location = map_span_to_location(span, workspace_root); | ||
141 | let edit = TextEdit::new(location.range, suggested_replacement.clone()); | ||
142 | edit_map.entry(location.uri).or_default().push(edit); | ||
135 | } | 143 | } |
136 | }; | 144 | } |
137 | |||
138 | // If we have a primary span use its location, otherwise use the parent | ||
139 | let location = map_span_to_location(&span, workspace_root); | ||
140 | |||
141 | if let Some(suggested_replacement) = &span.suggested_replacement { | ||
142 | // Include our replacement in the title unless it's empty | ||
143 | let title = if !suggested_replacement.is_empty() { | ||
144 | format!("{}: '{}'", rd.message, suggested_replacement) | ||
145 | } else { | ||
146 | rd.message.clone() | ||
147 | }; | ||
148 | |||
149 | let edit = { | ||
150 | let edits = vec![TextEdit::new(location.range, suggested_replacement.clone())]; | ||
151 | let mut edit_map = std::collections::HashMap::new(); | ||
152 | edit_map.insert(location.uri, edits); | ||
153 | WorkspaceEdit::new(edit_map) | ||
154 | }; | ||
155 | 145 | ||
146 | if !edit_map.is_empty() { | ||
156 | MappedRustChildDiagnostic::SuggestedFix(CodeAction { | 147 | MappedRustChildDiagnostic::SuggestedFix(CodeAction { |
157 | title, | 148 | title: rd.message.clone(), |
158 | kind: Some("quickfix".to_string()), | 149 | kind: Some("quickfix".to_string()), |
159 | diagnostics: None, | 150 | diagnostics: None, |
160 | edit: Some(edit), | 151 | edit: Some(WorkspaceEdit::new(edit_map)), |
161 | command: None, | 152 | command: None, |
162 | is_preferred: None, | 153 | is_preferred: None, |
163 | }) | 154 | }) |
164 | } else { | 155 | } else { |
165 | MappedRustChildDiagnostic::Related(DiagnosticRelatedInformation { | 156 | MappedRustChildDiagnostic::Related(DiagnosticRelatedInformation { |
166 | location, | 157 | location: map_span_to_location(spans[0], workspace_root), |
167 | message: rd.message.clone(), | 158 | message: rd.message.clone(), |
168 | }) | 159 | }) |
169 | } | 160 | } |
@@ -189,13 +180,13 @@ pub(crate) struct MappedRustDiagnostic { | |||
189 | pub(crate) fn map_rust_diagnostic_to_lsp( | 180 | pub(crate) fn map_rust_diagnostic_to_lsp( |
190 | rd: &RustDiagnostic, | 181 | rd: &RustDiagnostic, |
191 | workspace_root: &PathBuf, | 182 | workspace_root: &PathBuf, |
192 | ) -> Option<MappedRustDiagnostic> { | 183 | ) -> Vec<MappedRustDiagnostic> { |
193 | let primary_span = rd.spans.iter().find(|s| s.is_primary)?; | 184 | let primary_spans: Vec<&DiagnosticSpan> = rd.spans.iter().filter(|s| s.is_primary).collect(); |
194 | 185 | if primary_spans.is_empty() { | |
195 | let location = map_span_to_location(&primary_span, workspace_root); | 186 | return vec![]; |
187 | } | ||
196 | 188 | ||
197 | let severity = map_level_to_severity(rd.level); | 189 | let severity = map_level_to_severity(rd.level); |
198 | let mut primary_span_label = primary_span.label.as_ref(); | ||
199 | 190 | ||
200 | let mut source = String::from("rustc"); | 191 | let mut source = String::from("rustc"); |
201 | let mut code = rd.code.as_ref().map(|c| c.code.clone()); | 192 | let mut code = rd.code.as_ref().map(|c| c.code.clone()); |
@@ -208,19 +199,10 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
208 | } | 199 | } |
209 | } | 200 | } |
210 | 201 | ||
202 | let mut needs_primary_span_label = true; | ||
211 | let mut related_information = vec![]; | 203 | let mut related_information = vec![]; |
212 | let mut tags = vec![]; | 204 | let mut tags = vec![]; |
213 | 205 | ||
214 | // If error occurs from macro expansion, add related info pointing to | ||
215 | // where the error originated | ||
216 | if !is_from_macro(&primary_span.file_name) && primary_span.expansion.is_some() { | ||
217 | let def_loc = map_span_to_location_naive(&primary_span, workspace_root); | ||
218 | related_information.push(DiagnosticRelatedInformation { | ||
219 | location: def_loc, | ||
220 | message: "Error originated from macro here".to_string(), | ||
221 | }); | ||
222 | } | ||
223 | |||
224 | for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { | 206 | for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { |
225 | let related = map_secondary_span_to_related(secondary_span, workspace_root); | 207 | let related = map_secondary_span_to_related(secondary_span, workspace_root); |
226 | if let Some(related) = related { | 208 | if let Some(related) = related { |
@@ -240,15 +222,11 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
240 | 222 | ||
241 | // These secondary messages usually duplicate the content of the | 223 | // These secondary messages usually duplicate the content of the |
242 | // primary span label. | 224 | // primary span label. |
243 | primary_span_label = None; | 225 | needs_primary_span_label = false; |
244 | } | 226 | } |
245 | } | 227 | } |
246 | } | 228 | } |
247 | 229 | ||
248 | if let Some(primary_span_label) = primary_span_label { | ||
249 | write!(&mut message, "\n{}", primary_span_label).unwrap(); | ||
250 | } | ||
251 | |||
252 | if is_unused_or_unnecessary(rd) { | 230 | if is_unused_or_unnecessary(rd) { |
253 | tags.push(DiagnosticTag::Unnecessary); | 231 | tags.push(DiagnosticTag::Unnecessary); |
254 | } | 232 | } |
@@ -257,21 +235,45 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
257 | tags.push(DiagnosticTag::Deprecated); | 235 | tags.push(DiagnosticTag::Deprecated); |
258 | } | 236 | } |
259 | 237 | ||
260 | let diagnostic = Diagnostic { | 238 | primary_spans |
261 | range: location.range, | 239 | .iter() |
262 | severity, | 240 | .map(|primary_span| { |
263 | code: code.map(NumberOrString::String), | 241 | let location = map_span_to_location(&primary_span, workspace_root); |
264 | source: Some(source), | 242 | |
265 | message, | 243 | let mut message = message.clone(); |
266 | related_information: if !related_information.is_empty() { | 244 | if needs_primary_span_label { |
267 | Some(related_information) | 245 | if let Some(primary_span_label) = &primary_span.label { |
268 | } else { | 246 | write!(&mut message, "\n{}", primary_span_label).unwrap(); |
269 | None | 247 | } |
270 | }, | 248 | } |
271 | tags: if !tags.is_empty() { Some(tags) } else { None }, | 249 | |
272 | }; | 250 | // If error occurs from macro expansion, add related info pointing to |
273 | 251 | // where the error originated | |
274 | Some(MappedRustDiagnostic { location, diagnostic, fixes }) | 252 | if !is_from_macro(&primary_span.file_name) && primary_span.expansion.is_some() { |
253 | let def_loc = map_span_to_location_naive(&primary_span, workspace_root); | ||
254 | related_information.push(DiagnosticRelatedInformation { | ||
255 | location: def_loc, | ||
256 | message: "Error originated from macro here".to_string(), | ||
257 | }); | ||
258 | } | ||
259 | |||
260 | let diagnostic = Diagnostic { | ||
261 | range: location.range, | ||
262 | severity, | ||
263 | code: code.clone().map(NumberOrString::String), | ||
264 | source: Some(source.clone()), | ||
265 | message, | ||
266 | related_information: if !related_information.is_empty() { | ||
267 | Some(related_information.clone()) | ||
268 | } else { | ||
269 | None | ||
270 | }, | ||
271 | tags: if !tags.is_empty() { Some(tags.clone()) } else { None }, | ||
272 | }; | ||
273 | |||
274 | MappedRustDiagnostic { location, diagnostic, fixes: fixes.clone() } | ||
275 | }) | ||
276 | .collect() | ||
275 | } | 277 | } |
276 | 278 | ||
277 | /// Returns a `Url` object from a given path, will lowercase drive letters if present. | 279 | /// Returns a `Url` object from a given path, will lowercase drive letters if present. |
diff --git a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap index 95ca163dc..9e8f4eff4 100644 --- a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap +++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap | |||
@@ -2,98 +2,100 @@ | |||
2 | source: crates/ra_cargo_watch/src/conv/test.rs | 2 | source: crates/ra_cargo_watch/src/conv/test.rs |
3 | expression: diag | 3 | expression: diag |
4 | --- | 4 | --- |
5 | MappedRustDiagnostic { | 5 | [ |
6 | location: Location { | 6 | MappedRustDiagnostic { |
7 | uri: "file:///test/compiler/mir/tagset.rs", | 7 | location: Location { |
8 | range: Range { | 8 | uri: "file:///test/compiler/mir/tagset.rs", |
9 | start: Position { | 9 | range: Range { |
10 | line: 41, | 10 | start: Position { |
11 | character: 23, | 11 | line: 41, |
12 | }, | 12 | character: 23, |
13 | end: Position { | 13 | }, |
14 | line: 41, | 14 | end: Position { |
15 | character: 28, | 15 | line: 41, |
16 | character: 28, | ||
17 | }, | ||
16 | }, | 18 | }, |
17 | }, | 19 | }, |
18 | }, | 20 | diagnostic: Diagnostic { |
19 | diagnostic: Diagnostic { | 21 | range: Range { |
20 | range: Range { | 22 | start: Position { |
21 | start: Position { | 23 | line: 41, |
22 | line: 41, | 24 | character: 23, |
23 | character: 23, | 25 | }, |
24 | }, | 26 | end: Position { |
25 | end: Position { | 27 | line: 41, |
26 | line: 41, | 28 | character: 28, |
27 | character: 28, | 29 | }, |
28 | }, | 30 | }, |
29 | }, | 31 | severity: Some( |
30 | severity: Some( | 32 | Warning, |
31 | Warning, | ||
32 | ), | ||
33 | code: Some( | ||
34 | String( | ||
35 | "trivially_copy_pass_by_ref", | ||
36 | ), | 33 | ), |
37 | ), | 34 | code: Some( |
38 | source: Some( | 35 | String( |
39 | "clippy", | 36 | "trivially_copy_pass_by_ref", |
40 | ), | 37 | ), |
41 | message: "this argument is passed by reference, but would be more efficient if passed by value\n#[warn(clippy::trivially_copy_pass_by_ref)] implied by #[warn(clippy::all)]\nfor further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref", | 38 | ), |
42 | related_information: Some( | 39 | source: Some( |
43 | [ | 40 | "clippy", |
44 | DiagnosticRelatedInformation { | 41 | ), |
45 | location: Location { | 42 | message: "this argument is passed by reference, but would be more efficient if passed by value\n#[warn(clippy::trivially_copy_pass_by_ref)] implied by #[warn(clippy::all)]\nfor further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref", |
46 | uri: "file:///test/compiler/lib.rs", | 43 | related_information: Some( |
47 | range: Range { | 44 | [ |
48 | start: Position { | 45 | DiagnosticRelatedInformation { |
49 | line: 0, | 46 | location: Location { |
50 | character: 8, | 47 | uri: "file:///test/compiler/lib.rs", |
51 | }, | 48 | range: Range { |
52 | end: Position { | 49 | start: Position { |
53 | line: 0, | 50 | line: 0, |
54 | character: 19, | 51 | character: 8, |
52 | }, | ||
53 | end: Position { | ||
54 | line: 0, | ||
55 | character: 19, | ||
56 | }, | ||
55 | }, | 57 | }, |
56 | }, | 58 | }, |
59 | message: "lint level defined here", | ||
57 | }, | 60 | }, |
58 | message: "lint level defined here", | 61 | ], |
59 | }, | ||
60 | ], | ||
61 | ), | ||
62 | tags: None, | ||
63 | }, | ||
64 | fixes: [ | ||
65 | CodeAction { | ||
66 | title: "consider passing by value instead: \'self\'", | ||
67 | kind: Some( | ||
68 | "quickfix", | ||
69 | ), | 62 | ), |
70 | diagnostics: None, | 63 | tags: None, |
71 | edit: Some( | 64 | }, |
72 | WorkspaceEdit { | 65 | fixes: [ |
73 | changes: Some( | 66 | CodeAction { |
74 | { | 67 | title: "consider passing by value instead", |
75 | "file:///test/compiler/mir/tagset.rs": [ | 68 | kind: Some( |
76 | TextEdit { | 69 | "quickfix", |
77 | range: Range { | 70 | ), |
78 | start: Position { | 71 | diagnostics: None, |
79 | line: 41, | 72 | edit: Some( |
80 | character: 23, | 73 | WorkspaceEdit { |
81 | }, | 74 | changes: Some( |
82 | end: Position { | 75 | { |
83 | line: 41, | 76 | "file:///test/compiler/mir/tagset.rs": [ |
84 | character: 28, | 77 | TextEdit { |
78 | range: Range { | ||
79 | start: Position { | ||
80 | line: 41, | ||
81 | character: 23, | ||
82 | }, | ||
83 | end: Position { | ||
84 | line: 41, | ||
85 | character: 28, | ||
86 | }, | ||
85 | }, | 87 | }, |
88 | new_text: "self", | ||
86 | }, | 89 | }, |
87 | new_text: "self", | 90 | ], |
88 | }, | 91 | }, |
89 | ], | 92 | ), |
90 | }, | 93 | document_changes: None, |
91 | ), | 94 | }, |
92 | document_changes: None, | 95 | ), |
93 | }, | 96 | command: None, |
94 | ), | 97 | is_preferred: None, |
95 | command: None, | 98 | }, |
96 | is_preferred: None, | 99 | ], |
97 | }, | 100 | }, |
98 | ], | 101 | ] |
99 | } | ||
diff --git a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap index 12eb32df4..61ae0c9ae 100644 --- a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap +++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap | |||
@@ -2,45 +2,47 @@ | |||
2 | source: crates/ra_cargo_watch/src/conv/test.rs | 2 | source: crates/ra_cargo_watch/src/conv/test.rs |
3 | expression: diag | 3 | expression: diag |
4 | --- | 4 | --- |
5 | MappedRustDiagnostic { | 5 | [ |
6 | location: Location { | 6 | MappedRustDiagnostic { |
7 | uri: "file:///test/src/main.rs", | 7 | location: Location { |
8 | range: Range { | 8 | uri: "file:///test/src/main.rs", |
9 | start: Position { | 9 | range: Range { |
10 | line: 1, | 10 | start: Position { |
11 | character: 4, | 11 | line: 1, |
12 | }, | 12 | character: 4, |
13 | end: Position { | 13 | }, |
14 | line: 1, | 14 | end: Position { |
15 | character: 26, | 15 | line: 1, |
16 | character: 26, | ||
17 | }, | ||
16 | }, | 18 | }, |
17 | }, | 19 | }, |
18 | }, | 20 | diagnostic: Diagnostic { |
19 | diagnostic: Diagnostic { | 21 | range: Range { |
20 | range: Range { | 22 | start: Position { |
21 | start: Position { | 23 | line: 1, |
22 | line: 1, | 24 | character: 4, |
23 | character: 4, | 25 | }, |
26 | end: Position { | ||
27 | line: 1, | ||
28 | character: 26, | ||
29 | }, | ||
24 | }, | 30 | }, |
25 | end: Position { | 31 | severity: Some( |
26 | line: 1, | 32 | Error, |
27 | character: 26, | ||
28 | }, | ||
29 | }, | ||
30 | severity: Some( | ||
31 | Error, | ||
32 | ), | ||
33 | code: Some( | ||
34 | String( | ||
35 | "E0277", | ||
36 | ), | 33 | ), |
37 | ), | 34 | code: Some( |
38 | source: Some( | 35 | String( |
39 | "rustc", | 36 | "E0277", |
40 | ), | 37 | ), |
41 | message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`", | 38 | ), |
42 | related_information: None, | 39 | source: Some( |
43 | tags: None, | 40 | "rustc", |
41 | ), | ||
42 | message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`", | ||
43 | related_information: None, | ||
44 | tags: None, | ||
45 | }, | ||
46 | fixes: [], | ||
44 | }, | 47 | }, |
45 | fixes: [], | 48 | ] |
46 | } | ||
diff --git a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap index 7b83a7cd0..641da1a58 100644 --- a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap +++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap | |||
@@ -2,60 +2,62 @@ | |||
2 | source: crates/ra_cargo_watch/src/conv/test.rs | 2 | source: crates/ra_cargo_watch/src/conv/test.rs |
3 | expression: diag | 3 | expression: diag |
4 | --- | 4 | --- |
5 | MappedRustDiagnostic { | 5 | [ |
6 | location: Location { | 6 | MappedRustDiagnostic { |
7 | uri: "file:///test/crates/ra_hir_def/src/data.rs", | 7 | location: Location { |
8 | range: Range { | 8 | uri: "file:///test/crates/ra_hir_def/src/data.rs", |
9 | start: Position { | 9 | range: Range { |
10 | line: 79, | 10 | start: Position { |
11 | character: 15, | 11 | line: 79, |
12 | }, | 12 | character: 15, |
13 | end: Position { | 13 | }, |
14 | line: 79, | 14 | end: Position { |
15 | character: 41, | 15 | line: 79, |
16 | character: 41, | ||
17 | }, | ||
16 | }, | 18 | }, |
17 | }, | 19 | }, |
18 | }, | 20 | diagnostic: Diagnostic { |
19 | diagnostic: Diagnostic { | 21 | range: Range { |
20 | range: Range { | 22 | start: Position { |
21 | start: Position { | 23 | line: 79, |
22 | line: 79, | 24 | character: 15, |
23 | character: 15, | 25 | }, |
24 | }, | 26 | end: Position { |
25 | end: Position { | 27 | line: 79, |
26 | line: 79, | 28 | character: 41, |
27 | character: 41, | 29 | }, |
28 | }, | 30 | }, |
29 | }, | 31 | severity: Some( |
30 | severity: Some( | 32 | Error, |
31 | Error, | 33 | ), |
32 | ), | 34 | code: None, |
33 | code: None, | 35 | source: Some( |
34 | source: Some( | 36 | "rustc", |
35 | "rustc", | 37 | ), |
36 | ), | 38 | message: "Please register your known path in the path module", |
37 | message: "Please register your known path in the path module", | 39 | related_information: Some( |
38 | related_information: Some( | 40 | [ |
39 | [ | 41 | DiagnosticRelatedInformation { |
40 | DiagnosticRelatedInformation { | 42 | location: Location { |
41 | location: Location { | 43 | uri: "file:///test/crates/ra_hir_def/src/path.rs", |
42 | uri: "file:///test/crates/ra_hir_def/src/path.rs", | 44 | range: Range { |
43 | range: Range { | 45 | start: Position { |
44 | start: Position { | 46 | line: 264, |
45 | line: 264, | 47 | character: 8, |
46 | character: 8, | 48 | }, |
47 | }, | 49 | end: Position { |
48 | end: Position { | 50 | line: 264, |
49 | line: 264, | 51 | character: 76, |
50 | character: 76, | 52 | }, |
51 | }, | 53 | }, |
52 | }, | 54 | }, |
55 | message: "Error originated from macro here", | ||
53 | }, | 56 | }, |
54 | message: "Error originated from macro here", | 57 | ], |
55 | }, | 58 | ), |
56 | ], | 59 | tags: None, |
57 | ), | 60 | }, |
58 | tags: None, | 61 | fixes: [], |
59 | }, | 62 | }, |
60 | fixes: [], | 63 | ] |
61 | } | ||
diff --git a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_multi_line_fix.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_multi_line_fix.snap new file mode 100644 index 000000000..0557a2e79 --- /dev/null +++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_multi_line_fix.snap | |||
@@ -0,0 +1,114 @@ | |||
1 | --- | ||
2 | source: crates/ra_cargo_watch/src/conv/test.rs | ||
3 | expression: diag | ||
4 | --- | ||
5 | [ | ||
6 | MappedRustDiagnostic { | ||
7 | location: Location { | ||
8 | uri: "file:///test/src/main.rs", | ||
9 | range: Range { | ||
10 | start: Position { | ||
11 | line: 3, | ||
12 | character: 4, | ||
13 | }, | ||
14 | end: Position { | ||
15 | line: 3, | ||
16 | character: 5, | ||
17 | }, | ||
18 | }, | ||
19 | }, | ||
20 | diagnostic: Diagnostic { | ||
21 | range: Range { | ||
22 | start: Position { | ||
23 | line: 3, | ||
24 | character: 4, | ||
25 | }, | ||
26 | end: Position { | ||
27 | line: 3, | ||
28 | character: 5, | ||
29 | }, | ||
30 | }, | ||
31 | severity: Some( | ||
32 | Warning, | ||
33 | ), | ||
34 | code: Some( | ||
35 | String( | ||
36 | "let_and_return", | ||
37 | ), | ||
38 | ), | ||
39 | source: Some( | ||
40 | "clippy", | ||
41 | ), | ||
42 | message: "returning the result of a let binding from a block\n`#[warn(clippy::let_and_return)]` on by default\nfor further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return", | ||
43 | related_information: Some( | ||
44 | [ | ||
45 | DiagnosticRelatedInformation { | ||
46 | location: Location { | ||
47 | uri: "file:///test/src/main.rs", | ||
48 | range: Range { | ||
49 | start: Position { | ||
50 | line: 2, | ||
51 | character: 4, | ||
52 | }, | ||
53 | end: Position { | ||
54 | line: 2, | ||
55 | character: 30, | ||
56 | }, | ||
57 | }, | ||
58 | }, | ||
59 | message: "unnecessary let binding", | ||
60 | }, | ||
61 | ], | ||
62 | ), | ||
63 | tags: None, | ||
64 | }, | ||
65 | fixes: [ | ||
66 | CodeAction { | ||
67 | title: "return the expression directly", | ||
68 | kind: Some( | ||
69 | "quickfix", | ||
70 | ), | ||
71 | diagnostics: None, | ||
72 | edit: Some( | ||
73 | WorkspaceEdit { | ||
74 | changes: Some( | ||
75 | { | ||
76 | "file:///test/src/main.rs": [ | ||
77 | TextEdit { | ||
78 | range: Range { | ||
79 | start: Position { | ||
80 | line: 2, | ||
81 | character: 4, | ||
82 | }, | ||
83 | end: Position { | ||
84 | line: 2, | ||
85 | character: 30, | ||
86 | }, | ||
87 | }, | ||
88 | new_text: "", | ||
89 | }, | ||
90 | TextEdit { | ||
91 | range: Range { | ||
92 | start: Position { | ||
93 | line: 3, | ||
94 | character: 4, | ||
95 | }, | ||
96 | end: Position { | ||
97 | line: 3, | ||
98 | character: 5, | ||
99 | }, | ||
100 | }, | ||
101 | new_text: "(0..10).collect()", | ||
102 | }, | ||
103 | ], | ||
104 | }, | ||
105 | ), | ||
106 | document_changes: None, | ||
107 | }, | ||
108 | ), | ||
109 | command: None, | ||
110 | is_preferred: None, | ||
111 | }, | ||
112 | ], | ||
113 | }, | ||
114 | ] | ||
diff --git a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap index 54679c5db..754bc33a4 100644 --- a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap +++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap | |||
@@ -2,45 +2,47 @@ | |||
2 | source: crates/ra_cargo_watch/src/conv/test.rs | 2 | source: crates/ra_cargo_watch/src/conv/test.rs |
3 | expression: diag | 3 | expression: diag |
4 | --- | 4 | --- |
5 | MappedRustDiagnostic { | 5 | [ |
6 | location: Location { | 6 | MappedRustDiagnostic { |
7 | uri: "file:///test/compiler/ty/list_iter.rs", | 7 | location: Location { |
8 | range: Range { | 8 | uri: "file:///test/compiler/ty/list_iter.rs", |
9 | start: Position { | 9 | range: Range { |
10 | line: 51, | 10 | start: Position { |
11 | character: 4, | 11 | line: 51, |
12 | }, | 12 | character: 4, |
13 | end: Position { | 13 | }, |
14 | line: 51, | 14 | end: Position { |
15 | character: 47, | 15 | line: 51, |
16 | character: 47, | ||
17 | }, | ||
16 | }, | 18 | }, |
17 | }, | 19 | }, |
18 | }, | 20 | diagnostic: Diagnostic { |
19 | diagnostic: Diagnostic { | 21 | range: Range { |
20 | range: Range { | 22 | start: Position { |
21 | start: Position { | 23 | line: 51, |
22 | line: 51, | 24 | character: 4, |
23 | character: 4, | 25 | }, |
26 | end: Position { | ||
27 | line: 51, | ||
28 | character: 47, | ||
29 | }, | ||
24 | }, | 30 | }, |
25 | end: Position { | 31 | severity: Some( |
26 | line: 51, | 32 | Error, |
27 | character: 47, | ||
28 | }, | ||
29 | }, | ||
30 | severity: Some( | ||
31 | Error, | ||
32 | ), | ||
33 | code: Some( | ||
34 | String( | ||
35 | "E0053", | ||
36 | ), | 33 | ), |
37 | ), | 34 | code: Some( |
38 | source: Some( | 35 | String( |
39 | "rustc", | 36 | "E0053", |
40 | ), | 37 | ), |
41 | message: "method `next` has an incompatible type for trait\nexpected type `fn(&mut ty::list_iter::ListIterator<\'list, M>) -> std::option::Option<&ty::Ref<M>>`\n found type `fn(&ty::list_iter::ListIterator<\'list, M>) -> std::option::Option<&\'list ty::Ref<M>>`", | 38 | ), |
42 | related_information: None, | 39 | source: Some( |
43 | tags: None, | 40 | "rustc", |
41 | ), | ||
42 | message: "method `next` has an incompatible type for trait\nexpected type `fn(&mut ty::list_iter::ListIterator<\'list, M>) -> std::option::Option<&ty::Ref<M>>`\n found type `fn(&ty::list_iter::ListIterator<\'list, M>) -> std::option::Option<&\'list ty::Ref<M>>`", | ||
43 | related_information: None, | ||
44 | tags: None, | ||
45 | }, | ||
46 | fixes: [], | ||
44 | }, | 47 | }, |
45 | fixes: [], | 48 | ] |
46 | } | ||
diff --git a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap index 57df4ceaf..78b7f7cc8 100644 --- a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap +++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap | |||
@@ -2,45 +2,47 @@ | |||
2 | source: crates/ra_cargo_watch/src/conv/test.rs | 2 | source: crates/ra_cargo_watch/src/conv/test.rs |
3 | expression: diag | 3 | expression: diag |
4 | --- | 4 | --- |
5 | MappedRustDiagnostic { | 5 | [ |
6 | location: Location { | 6 | MappedRustDiagnostic { |
7 | uri: "file:///test/runtime/compiler_support.rs", | 7 | location: Location { |
8 | range: Range { | 8 | uri: "file:///test/runtime/compiler_support.rs", |
9 | start: Position { | 9 | range: Range { |
10 | line: 47, | 10 | start: Position { |
11 | character: 64, | 11 | line: 47, |
12 | }, | 12 | character: 64, |
13 | end: Position { | 13 | }, |
14 | line: 47, | 14 | end: Position { |
15 | character: 69, | 15 | line: 47, |
16 | character: 69, | ||
17 | }, | ||
16 | }, | 18 | }, |
17 | }, | 19 | }, |
18 | }, | 20 | diagnostic: Diagnostic { |
19 | diagnostic: Diagnostic { | 21 | range: Range { |
20 | range: Range { | 22 | start: Position { |
21 | start: Position { | 23 | line: 47, |
22 | line: 47, | 24 | character: 64, |
23 | character: 64, | 25 | }, |
26 | end: Position { | ||
27 | line: 47, | ||
28 | character: 69, | ||
29 | }, | ||
24 | }, | 30 | }, |
25 | end: Position { | 31 | severity: Some( |
26 | line: 47, | 32 | Error, |
27 | character: 69, | ||
28 | }, | ||
29 | }, | ||
30 | severity: Some( | ||
31 | Error, | ||
32 | ), | ||
33 | code: Some( | ||
34 | String( | ||
35 | "E0308", | ||
36 | ), | 33 | ), |
37 | ), | 34 | code: Some( |
38 | source: Some( | 35 | String( |
39 | "rustc", | 36 | "E0308", |
40 | ), | 37 | ), |
41 | message: "mismatched types\nexpected usize, found u32", | 38 | ), |
42 | related_information: None, | 39 | source: Some( |
43 | tags: None, | 40 | "rustc", |
41 | ), | ||
42 | message: "mismatched types\nexpected usize, found u32", | ||
43 | related_information: None, | ||
44 | tags: None, | ||
45 | }, | ||
46 | fixes: [], | ||
44 | }, | 47 | }, |
45 | fixes: [], | 48 | ] |
46 | } | ||
diff --git a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap index 3e1fe736c..5989ed202 100644 --- a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap +++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap | |||
@@ -2,83 +2,85 @@ | |||
2 | source: crates/ra_cargo_watch/src/conv/test.rs | 2 | source: crates/ra_cargo_watch/src/conv/test.rs |
3 | expression: diag | 3 | expression: diag |
4 | --- | 4 | --- |
5 | MappedRustDiagnostic { | 5 | [ |
6 | location: Location { | 6 | MappedRustDiagnostic { |
7 | uri: "file:///test/driver/subcommand/repl.rs", | 7 | location: Location { |
8 | range: Range { | 8 | uri: "file:///test/driver/subcommand/repl.rs", |
9 | start: Position { | 9 | range: Range { |
10 | line: 290, | 10 | start: Position { |
11 | character: 8, | 11 | line: 290, |
12 | }, | 12 | character: 8, |
13 | end: Position { | 13 | }, |
14 | line: 290, | 14 | end: Position { |
15 | character: 11, | 15 | line: 290, |
16 | character: 11, | ||
17 | }, | ||
16 | }, | 18 | }, |
17 | }, | 19 | }, |
18 | }, | 20 | diagnostic: Diagnostic { |
19 | diagnostic: Diagnostic { | 21 | range: Range { |
20 | range: Range { | 22 | start: Position { |
21 | start: Position { | 23 | line: 290, |
22 | line: 290, | 24 | character: 8, |
23 | character: 8, | 25 | }, |
24 | }, | 26 | end: Position { |
25 | end: Position { | 27 | line: 290, |
26 | line: 290, | 28 | character: 11, |
27 | character: 11, | 29 | }, |
28 | }, | 30 | }, |
29 | }, | 31 | severity: Some( |
30 | severity: Some( | 32 | Warning, |
31 | Warning, | ||
32 | ), | ||
33 | code: Some( | ||
34 | String( | ||
35 | "unused_variables", | ||
36 | ), | 33 | ), |
37 | ), | 34 | code: Some( |
38 | source: Some( | 35 | String( |
39 | "rustc", | 36 | "unused_variables", |
40 | ), | 37 | ), |
41 | message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", | ||
42 | related_information: None, | ||
43 | tags: Some( | ||
44 | [ | ||
45 | Unnecessary, | ||
46 | ], | ||
47 | ), | ||
48 | }, | ||
49 | fixes: [ | ||
50 | CodeAction { | ||
51 | title: "consider prefixing with an underscore: \'_foo\'", | ||
52 | kind: Some( | ||
53 | "quickfix", | ||
54 | ), | 38 | ), |
55 | diagnostics: None, | 39 | source: Some( |
56 | edit: Some( | 40 | "rustc", |
57 | WorkspaceEdit { | 41 | ), |
58 | changes: Some( | 42 | message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", |
59 | { | 43 | related_information: None, |
60 | "file:///test/driver/subcommand/repl.rs": [ | 44 | tags: Some( |
61 | TextEdit { | 45 | [ |
62 | range: Range { | 46 | Unnecessary, |
63 | start: Position { | 47 | ], |
64 | line: 290, | ||
65 | character: 8, | ||
66 | }, | ||
67 | end: Position { | ||
68 | line: 290, | ||
69 | character: 11, | ||
70 | }, | ||
71 | }, | ||
72 | new_text: "_foo", | ||
73 | }, | ||
74 | ], | ||
75 | }, | ||
76 | ), | ||
77 | document_changes: None, | ||
78 | }, | ||
79 | ), | 48 | ), |
80 | command: None, | ||
81 | is_preferred: None, | ||
82 | }, | 49 | }, |
83 | ], | 50 | fixes: [ |
84 | } | 51 | CodeAction { |
52 | title: "consider prefixing with an underscore", | ||
53 | kind: Some( | ||
54 | "quickfix", | ||
55 | ), | ||
56 | diagnostics: None, | ||
57 | edit: Some( | ||
58 | WorkspaceEdit { | ||
59 | changes: Some( | ||
60 | { | ||
61 | "file:///test/driver/subcommand/repl.rs": [ | ||
62 | TextEdit { | ||
63 | range: Range { | ||
64 | start: Position { | ||
65 | line: 290, | ||
66 | character: 8, | ||
67 | }, | ||
68 | end: Position { | ||
69 | line: 290, | ||
70 | character: 11, | ||
71 | }, | ||
72 | }, | ||
73 | new_text: "_foo", | ||
74 | }, | ||
75 | ], | ||
76 | }, | ||
77 | ), | ||
78 | document_changes: None, | ||
79 | }, | ||
80 | ), | ||
81 | command: None, | ||
82 | is_preferred: None, | ||
83 | }, | ||
84 | ], | ||
85 | }, | ||
86 | ] | ||
diff --git a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap index 69301078d..e34b546dc 100644 --- a/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap +++ b/crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap | |||
@@ -2,64 +2,66 @@ | |||
2 | source: crates/ra_cargo_watch/src/conv/test.rs | 2 | source: crates/ra_cargo_watch/src/conv/test.rs |
3 | expression: diag | 3 | expression: diag |
4 | --- | 4 | --- |
5 | MappedRustDiagnostic { | 5 | [ |
6 | location: Location { | 6 | MappedRustDiagnostic { |
7 | uri: "file:///test/compiler/ty/select.rs", | 7 | location: Location { |
8 | range: Range { | 8 | uri: "file:///test/compiler/ty/select.rs", |
9 | start: Position { | 9 | range: Range { |
10 | line: 103, | 10 | start: Position { |
11 | character: 17, | 11 | line: 103, |
12 | }, | 12 | character: 17, |
13 | end: Position { | 13 | }, |
14 | line: 103, | 14 | end: Position { |
15 | character: 29, | 15 | line: 103, |
16 | character: 29, | ||
17 | }, | ||
16 | }, | 18 | }, |
17 | }, | 19 | }, |
18 | }, | 20 | diagnostic: Diagnostic { |
19 | diagnostic: Diagnostic { | 21 | range: Range { |
20 | range: Range { | 22 | start: Position { |
21 | start: Position { | 23 | line: 103, |
22 | line: 103, | 24 | character: 17, |
23 | character: 17, | 25 | }, |
24 | }, | 26 | end: Position { |
25 | end: Position { | 27 | line: 103, |
26 | line: 103, | 28 | character: 29, |
27 | character: 29, | 29 | }, |
28 | }, | 30 | }, |
29 | }, | 31 | severity: Some( |
30 | severity: Some( | 32 | Error, |
31 | Error, | ||
32 | ), | ||
33 | code: Some( | ||
34 | String( | ||
35 | "E0061", | ||
36 | ), | 33 | ), |
37 | ), | 34 | code: Some( |
38 | source: Some( | 35 | String( |
39 | "rustc", | 36 | "E0061", |
40 | ), | 37 | ), |
41 | message: "this function takes 2 parameters but 3 parameters were supplied\nexpected 2 parameters", | 38 | ), |
42 | related_information: Some( | 39 | source: Some( |
43 | [ | 40 | "rustc", |
44 | DiagnosticRelatedInformation { | 41 | ), |
45 | location: Location { | 42 | message: "this function takes 2 parameters but 3 parameters were supplied\nexpected 2 parameters", |
46 | uri: "file:///test/compiler/ty/select.rs", | 43 | related_information: Some( |
47 | range: Range { | 44 | [ |
48 | start: Position { | 45 | DiagnosticRelatedInformation { |
49 | line: 218, | 46 | location: Location { |
50 | character: 4, | 47 | uri: "file:///test/compiler/ty/select.rs", |
51 | }, | 48 | range: Range { |
52 | end: Position { | 49 | start: Position { |
53 | line: 230, | 50 | line: 218, |
54 | character: 5, | 51 | character: 4, |
52 | }, | ||
53 | end: Position { | ||
54 | line: 230, | ||
55 | character: 5, | ||
56 | }, | ||
55 | }, | 57 | }, |
56 | }, | 58 | }, |
59 | message: "defined here", | ||
57 | }, | 60 | }, |
58 | message: "defined here", | 61 | ], |
59 | }, | 62 | ), |
60 | ], | 63 | tags: None, |
61 | ), | 64 | }, |
62 | tags: None, | 65 | fixes: [], |
63 | }, | 66 | }, |
64 | fixes: [], | 67 | ] |
65 | } | ||
diff --git a/crates/ra_cargo_watch/src/conv/test.rs b/crates/ra_cargo_watch/src/conv/test.rs index 6b86525b8..4e81455ca 100644 --- a/crates/ra_cargo_watch/src/conv/test.rs +++ b/crates/ra_cargo_watch/src/conv/test.rs | |||
@@ -58,7 +58,7 @@ fn snap_rustc_incompatible_type_for_trait() { | |||
58 | ); | 58 | ); |
59 | 59 | ||
60 | let workspace_root = PathBuf::from("/test/"); | 60 | let workspace_root = PathBuf::from("/test/"); |
61 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root).expect("couldn't map diagnostic"); | 61 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root); |
62 | insta::assert_debug_snapshot!(diag); | 62 | insta::assert_debug_snapshot!(diag); |
63 | } | 63 | } |
64 | 64 | ||
@@ -141,7 +141,7 @@ fn snap_rustc_unused_variable() { | |||
141 | ); | 141 | ); |
142 | 142 | ||
143 | let workspace_root = PathBuf::from("/test/"); | 143 | let workspace_root = PathBuf::from("/test/"); |
144 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root).expect("couldn't map diagnostic"); | 144 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root); |
145 | insta::assert_debug_snapshot!(diag); | 145 | insta::assert_debug_snapshot!(diag); |
146 | } | 146 | } |
147 | 147 | ||
@@ -266,7 +266,7 @@ fn snap_rustc_wrong_number_of_parameters() { | |||
266 | ); | 266 | ); |
267 | 267 | ||
268 | let workspace_root = PathBuf::from("/test/"); | 268 | let workspace_root = PathBuf::from("/test/"); |
269 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root).expect("couldn't map diagnostic"); | 269 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root); |
270 | insta::assert_debug_snapshot!(diag); | 270 | insta::assert_debug_snapshot!(diag); |
271 | } | 271 | } |
272 | 272 | ||
@@ -387,7 +387,7 @@ fn snap_clippy_pass_by_ref() { | |||
387 | ); | 387 | ); |
388 | 388 | ||
389 | let workspace_root = PathBuf::from("/test/"); | 389 | let workspace_root = PathBuf::from("/test/"); |
390 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root).expect("couldn't map diagnostic"); | 390 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root); |
391 | insta::assert_debug_snapshot!(diag); | 391 | insta::assert_debug_snapshot!(diag); |
392 | } | 392 | } |
393 | 393 | ||
@@ -431,7 +431,7 @@ fn snap_rustc_mismatched_type() { | |||
431 | ); | 431 | ); |
432 | 432 | ||
433 | let workspace_root = PathBuf::from("/test/"); | 433 | let workspace_root = PathBuf::from("/test/"); |
434 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root).expect("couldn't map diagnostic"); | 434 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root); |
435 | insta::assert_debug_snapshot!(diag); | 435 | insta::assert_debug_snapshot!(diag); |
436 | } | 436 | } |
437 | 437 | ||
@@ -703,7 +703,7 @@ fn snap_handles_macro_location() { | |||
703 | ); | 703 | ); |
704 | 704 | ||
705 | let workspace_root = PathBuf::from("/test/"); | 705 | let workspace_root = PathBuf::from("/test/"); |
706 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root).expect("couldn't map diagnostic"); | 706 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root); |
707 | insta::assert_debug_snapshot!(diag); | 707 | insta::assert_debug_snapshot!(diag); |
708 | } | 708 | } |
709 | 709 | ||
@@ -933,6 +933,140 @@ fn snap_macro_compiler_error() { | |||
933 | ); | 933 | ); |
934 | 934 | ||
935 | let workspace_root = PathBuf::from("/test/"); | 935 | let workspace_root = PathBuf::from("/test/"); |
936 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root).expect("couldn't map diagnostic"); | 936 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root); |
937 | insta::assert_debug_snapshot!(diag); | ||
938 | } | ||
939 | |||
940 | #[test] | ||
941 | #[cfg(not(windows))] | ||
942 | fn snap_multi_line_fix() { | ||
943 | let diag = parse_diagnostic( | ||
944 | r##"{ | ||
945 | "rendered": "warning: returning the result of a let binding from a block\n --> src/main.rs:4:5\n |\n3 | let a = (0..10).collect();\n | -------------------------- unnecessary let binding\n4 | a\n | ^\n |\n = note: `#[warn(clippy::let_and_return)]` on by default\n = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return\nhelp: return the expression directly\n |\n3 | \n4 | (0..10).collect()\n |\n\n", | ||
946 | "children": [ | ||
947 | { | ||
948 | "children": [], | ||
949 | "code": null, | ||
950 | "level": "note", | ||
951 | "message": "`#[warn(clippy::let_and_return)]` on by default", | ||
952 | "rendered": null, | ||
953 | "spans": [] | ||
954 | }, | ||
955 | { | ||
956 | "children": [], | ||
957 | "code": null, | ||
958 | "level": "help", | ||
959 | "message": "for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return", | ||
960 | "rendered": null, | ||
961 | "spans": [] | ||
962 | }, | ||
963 | { | ||
964 | "children": [], | ||
965 | "code": null, | ||
966 | "level": "help", | ||
967 | "message": "return the expression directly", | ||
968 | "rendered": null, | ||
969 | "spans": [ | ||
970 | { | ||
971 | "byte_end": 55, | ||
972 | "byte_start": 29, | ||
973 | "column_end": 31, | ||
974 | "column_start": 5, | ||
975 | "expansion": null, | ||
976 | "file_name": "src/main.rs", | ||
977 | "is_primary": true, | ||
978 | "label": null, | ||
979 | "line_end": 3, | ||
980 | "line_start": 3, | ||
981 | "suggested_replacement": "", | ||
982 | "suggestion_applicability": "MachineApplicable", | ||
983 | "text": [ | ||
984 | { | ||
985 | "highlight_end": 31, | ||
986 | "highlight_start": 5, | ||
987 | "text": " let a = (0..10).collect();" | ||
988 | } | ||
989 | ] | ||
990 | }, | ||
991 | { | ||
992 | "byte_end": 61, | ||
993 | "byte_start": 60, | ||
994 | "column_end": 6, | ||
995 | "column_start": 5, | ||
996 | "expansion": null, | ||
997 | "file_name": "src/main.rs", | ||
998 | "is_primary": true, | ||
999 | "label": null, | ||
1000 | "line_end": 4, | ||
1001 | "line_start": 4, | ||
1002 | "suggested_replacement": "(0..10).collect()", | ||
1003 | "suggestion_applicability": "MachineApplicable", | ||
1004 | "text": [ | ||
1005 | { | ||
1006 | "highlight_end": 6, | ||
1007 | "highlight_start": 5, | ||
1008 | "text": " a" | ||
1009 | } | ||
1010 | ] | ||
1011 | } | ||
1012 | ] | ||
1013 | } | ||
1014 | ], | ||
1015 | "code": { | ||
1016 | "code": "clippy::let_and_return", | ||
1017 | "explanation": null | ||
1018 | }, | ||
1019 | "level": "warning", | ||
1020 | "message": "returning the result of a let binding from a block", | ||
1021 | "spans": [ | ||
1022 | { | ||
1023 | "byte_end": 55, | ||
1024 | "byte_start": 29, | ||
1025 | "column_end": 31, | ||
1026 | "column_start": 5, | ||
1027 | "expansion": null, | ||
1028 | "file_name": "src/main.rs", | ||
1029 | "is_primary": false, | ||
1030 | "label": "unnecessary let binding", | ||
1031 | "line_end": 3, | ||
1032 | "line_start": 3, | ||
1033 | "suggested_replacement": null, | ||
1034 | "suggestion_applicability": null, | ||
1035 | "text": [ | ||
1036 | { | ||
1037 | "highlight_end": 31, | ||
1038 | "highlight_start": 5, | ||
1039 | "text": " let a = (0..10).collect();" | ||
1040 | } | ||
1041 | ] | ||
1042 | }, | ||
1043 | { | ||
1044 | "byte_end": 61, | ||
1045 | "byte_start": 60, | ||
1046 | "column_end": 6, | ||
1047 | "column_start": 5, | ||
1048 | "expansion": null, | ||
1049 | "file_name": "src/main.rs", | ||
1050 | "is_primary": true, | ||
1051 | "label": null, | ||
1052 | "line_end": 4, | ||
1053 | "line_start": 4, | ||
1054 | "suggested_replacement": null, | ||
1055 | "suggestion_applicability": null, | ||
1056 | "text": [ | ||
1057 | { | ||
1058 | "highlight_end": 6, | ||
1059 | "highlight_start": 5, | ||
1060 | "text": " a" | ||
1061 | } | ||
1062 | ] | ||
1063 | } | ||
1064 | ] | ||
1065 | } | ||
1066 | "##, | ||
1067 | ); | ||
1068 | |||
1069 | let workspace_root = PathBuf::from("/test/"); | ||
1070 | let diag = map_rust_diagnostic_to_lsp(&diag, &workspace_root); | ||
937 | insta::assert_debug_snapshot!(diag); | 1071 | insta::assert_debug_snapshot!(diag); |
938 | } | 1072 | } |
diff --git a/crates/ra_cargo_watch/src/lib.rs b/crates/ra_cargo_watch/src/lib.rs index f07c34549..94b9c03d0 100644 --- a/crates/ra_cargo_watch/src/lib.rs +++ b/crates/ra_cargo_watch/src/lib.rs | |||
@@ -197,23 +197,23 @@ impl CheckWatcherThread { | |||
197 | } | 197 | } |
198 | 198 | ||
199 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { | 199 | CheckEvent::Msg(Message::CompilerMessage(msg)) => { |
200 | let map_result = | 200 | let map_result = map_rust_diagnostic_to_lsp(&msg.message, &self.workspace_root); |
201 | match map_rust_diagnostic_to_lsp(&msg.message, &self.workspace_root) { | 201 | if map_result.is_empty() { |
202 | Some(map_result) => map_result, | 202 | return; |
203 | None => return, | 203 | } |
204 | }; | ||
205 | |||
206 | let MappedRustDiagnostic { location, diagnostic, fixes } = map_result; | ||
207 | let fixes = fixes | ||
208 | .into_iter() | ||
209 | .map(|fix| { | ||
210 | CodeAction { diagnostics: Some(vec![diagnostic.clone()]), ..fix }.into() | ||
211 | }) | ||
212 | .collect(); | ||
213 | 204 | ||
214 | task_send | 205 | for MappedRustDiagnostic { location, diagnostic, fixes } in map_result { |
215 | .send(CheckTask::AddDiagnostic { url: location.uri, diagnostic, fixes }) | 206 | let fixes = fixes |
216 | .unwrap(); | 207 | .into_iter() |
208 | .map(|fix| { | ||
209 | CodeAction { diagnostics: Some(vec![diagnostic.clone()]), ..fix }.into() | ||
210 | }) | ||
211 | .collect(); | ||
212 | |||
213 | task_send | ||
214 | .send(CheckTask::AddDiagnostic { url: location.uri, diagnostic, fixes }) | ||
215 | .unwrap(); | ||
216 | } | ||
217 | } | 217 | } |
218 | 218 | ||
219 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} | 219 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} |
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index 7f43c2971..3dc86ca2d 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs | |||
@@ -61,7 +61,14 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | let mut crate_graph = CrateGraph::default(); | 63 | let mut crate_graph = CrateGraph::default(); |
64 | crate_graph.add_crate_root(file_id, meta.edition, meta.krate, meta.cfg, meta.env); | 64 | crate_graph.add_crate_root( |
65 | file_id, | ||
66 | meta.edition, | ||
67 | meta.krate, | ||
68 | meta.cfg, | ||
69 | meta.env, | ||
70 | Default::default(), | ||
71 | ); | ||
65 | crate_graph | 72 | crate_graph |
66 | } else { | 73 | } else { |
67 | let mut crate_graph = CrateGraph::default(); | 74 | let mut crate_graph = CrateGraph::default(); |
@@ -71,6 +78,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId | |||
71 | None, | 78 | None, |
72 | CfgOptions::default(), | 79 | CfgOptions::default(), |
73 | Env::default(), | 80 | Env::default(), |
81 | Default::default(), | ||
74 | ); | 82 | ); |
75 | crate_graph | 83 | crate_graph |
76 | }; | 84 | }; |
@@ -119,6 +127,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
119 | Some(krate.clone()), | 127 | Some(krate.clone()), |
120 | meta.cfg, | 128 | meta.cfg, |
121 | meta.env, | 129 | meta.env, |
130 | Default::default(), | ||
122 | ); | 131 | ); |
123 | let prev = crates.insert(krate.clone(), crate_id); | 132 | let prev = crates.insert(krate.clone(), crate_id); |
124 | assert!(prev.is_none()); | 133 | assert!(prev.is_none()); |
@@ -155,6 +164,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit | |||
155 | None, | 164 | None, |
156 | CfgOptions::default(), | 165 | CfgOptions::default(), |
157 | Env::default(), | 166 | Env::default(), |
167 | Default::default(), | ||
158 | ); | 168 | ); |
159 | } else { | 169 | } else { |
160 | for (from, to) in crate_deps { | 170 | for (from, to) in crate_deps { |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 1a1c64202..06d40db96 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -113,6 +113,7 @@ pub struct CrateData { | |||
113 | pub display_name: Option<String>, | 113 | pub display_name: Option<String>, |
114 | pub cfg_options: CfgOptions, | 114 | pub cfg_options: CfgOptions, |
115 | pub env: Env, | 115 | pub env: Env, |
116 | pub extern_source: ExternSource, | ||
116 | pub dependencies: Vec<Dependency>, | 117 | pub dependencies: Vec<Dependency>, |
117 | } | 118 | } |
118 | 119 | ||
@@ -122,11 +123,22 @@ pub enum Edition { | |||
122 | Edition2015, | 123 | Edition2015, |
123 | } | 124 | } |
124 | 125 | ||
126 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
127 | pub struct ExternSourceId(pub u32); | ||
128 | |||
125 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | 129 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
126 | pub struct Env { | 130 | pub struct Env { |
127 | entries: FxHashMap<String, String>, | 131 | entries: FxHashMap<String, String>, |
128 | } | 132 | } |
129 | 133 | ||
134 | // FIXME: Redesign vfs for solve the following limitation ? | ||
135 | // Note: Some env variables (e.g. OUT_DIR) are located outside of the | ||
136 | // crate. We store a map to allow remap it to ExternSourceId | ||
137 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | ||
138 | pub struct ExternSource { | ||
139 | extern_paths: FxHashMap<String, ExternSourceId>, | ||
140 | } | ||
141 | |||
130 | #[derive(Debug, Clone, PartialEq, Eq)] | 142 | #[derive(Debug, Clone, PartialEq, Eq)] |
131 | pub struct Dependency { | 143 | pub struct Dependency { |
132 | pub crate_id: CrateId, | 144 | pub crate_id: CrateId, |
@@ -141,6 +153,7 @@ impl CrateGraph { | |||
141 | display_name: Option<String>, | 153 | display_name: Option<String>, |
142 | cfg_options: CfgOptions, | 154 | cfg_options: CfgOptions, |
143 | env: Env, | 155 | env: Env, |
156 | extern_source: ExternSource, | ||
144 | ) -> CrateId { | 157 | ) -> CrateId { |
145 | let data = CrateData { | 158 | let data = CrateData { |
146 | root_file_id: file_id, | 159 | root_file_id: file_id, |
@@ -148,6 +161,7 @@ impl CrateGraph { | |||
148 | display_name, | 161 | display_name, |
149 | cfg_options, | 162 | cfg_options, |
150 | env, | 163 | env, |
164 | extern_source, | ||
151 | dependencies: Vec::new(), | 165 | dependencies: Vec::new(), |
152 | }; | 166 | }; |
153 | let crate_id = CrateId(self.arena.len() as u32); | 167 | let crate_id = CrateId(self.arena.len() as u32); |
@@ -271,6 +285,27 @@ impl Env { | |||
271 | } | 285 | } |
272 | } | 286 | } |
273 | 287 | ||
288 | impl ExternSource { | ||
289 | pub fn extern_path(&self, path: &str) -> Option<(ExternSourceId, RelativePathBuf)> { | ||
290 | self.extern_paths.iter().find_map(|(root_path, id)| { | ||
291 | if path.starts_with(root_path) { | ||
292 | let mut rel_path = &path[root_path.len()..]; | ||
293 | if rel_path.starts_with("/") { | ||
294 | rel_path = &rel_path[1..]; | ||
295 | } | ||
296 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | ||
297 | Some((id.clone(), rel_path)) | ||
298 | } else { | ||
299 | None | ||
300 | } | ||
301 | }) | ||
302 | } | ||
303 | |||
304 | pub fn set_extern_path(&mut self, root_path: &str, root: ExternSourceId) { | ||
305 | self.extern_paths.insert(root_path.to_owned(), root); | ||
306 | } | ||
307 | } | ||
308 | |||
274 | #[derive(Debug)] | 309 | #[derive(Debug)] |
275 | pub struct ParseEditionError { | 310 | pub struct ParseEditionError { |
276 | invalid_input: String, | 311 | invalid_input: String, |
@@ -300,6 +335,7 @@ mod tests { | |||
300 | None, | 335 | None, |
301 | CfgOptions::default(), | 336 | CfgOptions::default(), |
302 | Env::default(), | 337 | Env::default(), |
338 | Default::default(), | ||
303 | ); | 339 | ); |
304 | let crate2 = graph.add_crate_root( | 340 | let crate2 = graph.add_crate_root( |
305 | FileId(2u32), | 341 | FileId(2u32), |
@@ -307,6 +343,7 @@ mod tests { | |||
307 | None, | 343 | None, |
308 | CfgOptions::default(), | 344 | CfgOptions::default(), |
309 | Env::default(), | 345 | Env::default(), |
346 | Default::default(), | ||
310 | ); | 347 | ); |
311 | let crate3 = graph.add_crate_root( | 348 | let crate3 = graph.add_crate_root( |
312 | FileId(3u32), | 349 | FileId(3u32), |
@@ -314,6 +351,7 @@ mod tests { | |||
314 | None, | 351 | None, |
315 | CfgOptions::default(), | 352 | CfgOptions::default(), |
316 | Env::default(), | 353 | Env::default(), |
354 | Default::default(), | ||
317 | ); | 355 | ); |
318 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); | 356 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); |
319 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); | 357 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); |
@@ -329,6 +367,7 @@ mod tests { | |||
329 | None, | 367 | None, |
330 | CfgOptions::default(), | 368 | CfgOptions::default(), |
331 | Env::default(), | 369 | Env::default(), |
370 | Default::default(), | ||
332 | ); | 371 | ); |
333 | let crate2 = graph.add_crate_root( | 372 | let crate2 = graph.add_crate_root( |
334 | FileId(2u32), | 373 | FileId(2u32), |
@@ -336,6 +375,7 @@ mod tests { | |||
336 | None, | 375 | None, |
337 | CfgOptions::default(), | 376 | CfgOptions::default(), |
338 | Env::default(), | 377 | Env::default(), |
378 | Default::default(), | ||
339 | ); | 379 | ); |
340 | let crate3 = graph.add_crate_root( | 380 | let crate3 = graph.add_crate_root( |
341 | FileId(3u32), | 381 | FileId(3u32), |
@@ -343,6 +383,7 @@ mod tests { | |||
343 | None, | 383 | None, |
344 | CfgOptions::default(), | 384 | CfgOptions::default(), |
345 | Env::default(), | 385 | Env::default(), |
386 | Default::default(), | ||
346 | ); | 387 | ); |
347 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); | 388 | assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); |
348 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); | 389 | assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); |
@@ -357,6 +398,7 @@ mod tests { | |||
357 | None, | 398 | None, |
358 | CfgOptions::default(), | 399 | CfgOptions::default(), |
359 | Env::default(), | 400 | Env::default(), |
401 | Default::default(), | ||
360 | ); | 402 | ); |
361 | let crate2 = graph.add_crate_root( | 403 | let crate2 = graph.add_crate_root( |
362 | FileId(2u32), | 404 | FileId(2u32), |
@@ -364,6 +406,7 @@ mod tests { | |||
364 | None, | 406 | None, |
365 | CfgOptions::default(), | 407 | CfgOptions::default(), |
366 | Env::default(), | 408 | Env::default(), |
409 | Default::default(), | ||
367 | ); | 410 | ); |
368 | assert!(graph | 411 | assert!(graph |
369 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) | 412 | .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index fb002d717..d500d5e85 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -11,7 +11,8 @@ use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; | |||
11 | pub use crate::{ | 11 | pub use crate::{ |
12 | cancellation::Canceled, | 12 | cancellation::Canceled, |
13 | input::{ | 13 | input::{ |
14 | CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, SourceRoot, SourceRootId, | 14 | CrateGraph, CrateId, CrateName, Dependency, Edition, Env, ExternSource, ExternSourceId, |
15 | FileId, SourceRoot, SourceRootId, | ||
15 | }, | 16 | }, |
16 | }; | 17 | }; |
17 | pub use relative_path::{RelativePath, RelativePathBuf}; | 18 | pub use relative_path::{RelativePath, RelativePathBuf}; |
@@ -87,6 +88,12 @@ pub trait FileLoader { | |||
87 | fn resolve_relative_path(&self, anchor: FileId, relative_path: &RelativePath) | 88 | fn resolve_relative_path(&self, anchor: FileId, relative_path: &RelativePath) |
88 | -> Option<FileId>; | 89 | -> Option<FileId>; |
89 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>>; | 90 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>>; |
91 | |||
92 | fn resolve_extern_path( | ||
93 | &self, | ||
94 | extern_id: ExternSourceId, | ||
95 | relative_path: &RelativePath, | ||
96 | ) -> Option<FileId>; | ||
90 | } | 97 | } |
91 | 98 | ||
92 | /// Database which stores all significant input facts: source code and project | 99 | /// Database which stores all significant input facts: source code and project |
@@ -164,4 +171,13 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> { | |||
164 | let source_root = self.0.file_source_root(file_id); | 171 | let source_root = self.0.file_source_root(file_id); |
165 | self.0.source_root_crates(source_root) | 172 | self.0.source_root_crates(source_root) |
166 | } | 173 | } |
174 | |||
175 | fn resolve_extern_path( | ||
176 | &self, | ||
177 | extern_id: ExternSourceId, | ||
178 | relative_path: &RelativePath, | ||
179 | ) -> Option<FileId> { | ||
180 | let source_root = self.0.source_root(SourceRootId(extern_id.0)); | ||
181 | source_root.file_by_relative_path(&relative_path) | ||
182 | } | ||
167 | } | 183 | } |
diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs index 1568820e9..0756916a8 100644 --- a/crates/ra_hir_def/src/test_db.rs +++ b/crates/ra_hir_def/src/test_db.rs | |||
@@ -6,7 +6,7 @@ use std::{ | |||
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::db::DefDatabase; | 8 | use crate::db::DefDatabase; |
9 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath}; | 9 | use ra_db::{salsa, CrateId, ExternSourceId, FileId, FileLoader, FileLoaderDelegate, RelativePath}; |
10 | 10 | ||
11 | #[salsa::database( | 11 | #[salsa::database( |
12 | ra_db::SourceDatabaseExtStorage, | 12 | ra_db::SourceDatabaseExtStorage, |
@@ -52,6 +52,14 @@ impl FileLoader for TestDB { | |||
52 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { | 52 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { |
53 | FileLoaderDelegate(self).relevant_crates(file_id) | 53 | FileLoaderDelegate(self).relevant_crates(file_id) |
54 | } | 54 | } |
55 | |||
56 | fn resolve_extern_path( | ||
57 | &self, | ||
58 | extern_id: ExternSourceId, | ||
59 | relative_path: &RelativePath, | ||
60 | ) -> Option<FileId> { | ||
61 | FileLoaderDelegate(self).resolve_extern_path(extern_id, relative_path) | ||
62 | } | ||
55 | } | 63 | } |
56 | 64 | ||
57 | impl TestDB { | 65 | impl TestDB { |
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index 3f60b1cca..f9d3787f6 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs | |||
@@ -88,17 +88,18 @@ register_builtin! { | |||
88 | (compile_error, CompileError) => compile_error_expand, | 88 | (compile_error, CompileError) => compile_error_expand, |
89 | (file, File) => file_expand, | 89 | (file, File) => file_expand, |
90 | (line, Line) => line_expand, | 90 | (line, Line) => line_expand, |
91 | (assert, Assert) => assert_expand, | ||
91 | (stringify, Stringify) => stringify_expand, | 92 | (stringify, Stringify) => stringify_expand, |
92 | (format_args, FormatArgs) => format_args_expand, | 93 | (format_args, FormatArgs) => format_args_expand, |
93 | (env, Env) => env_expand, | ||
94 | (option_env, OptionEnv) => option_env_expand, | ||
95 | // format_args_nl only differs in that it adds a newline in the end, | 94 | // format_args_nl only differs in that it adds a newline in the end, |
96 | // so we use the same stub expansion for now | 95 | // so we use the same stub expansion for now |
97 | (format_args_nl, FormatArgsNl) => format_args_expand, | 96 | (format_args_nl, FormatArgsNl) => format_args_expand, |
98 | 97 | ||
99 | EAGER: | 98 | EAGER: |
100 | (concat, Concat) => concat_expand, | 99 | (concat, Concat) => concat_expand, |
101 | (include, Include) => include_expand | 100 | (include, Include) => include_expand, |
101 | (env, Env) => env_expand, | ||
102 | (option_env, OptionEnv) => option_env_expand | ||
102 | } | 103 | } |
103 | 104 | ||
104 | fn line_expand( | 105 | fn line_expand( |
@@ -137,42 +138,56 @@ fn stringify_expand( | |||
137 | Ok(expanded) | 138 | Ok(expanded) |
138 | } | 139 | } |
139 | 140 | ||
140 | fn env_expand( | 141 | fn column_expand( |
141 | _db: &dyn AstDatabase, | 142 | _db: &dyn AstDatabase, |
142 | _id: LazyMacroId, | 143 | _id: LazyMacroId, |
143 | _tt: &tt::Subtree, | 144 | _tt: &tt::Subtree, |
144 | ) -> Result<tt::Subtree, mbe::ExpandError> { | 145 | ) -> Result<tt::Subtree, mbe::ExpandError> { |
145 | // dummy implementation for type-checking purposes | 146 | // dummy implementation for type-checking purposes |
146 | // we cannot use an empty string here, because for | 147 | let col_num = 0; |
147 | // `include!(concat!(env!("OUT_DIR"), "/foo.rs"))` will become | 148 | let expanded = quote! { |
148 | // `include!("foo.rs"), which maybe infinite loop | 149 | #col_num |
149 | let expanded = quote! { "__RA_UNIMPLEMENTATED__" }; | 150 | }; |
150 | 151 | ||
151 | Ok(expanded) | 152 | Ok(expanded) |
152 | } | 153 | } |
153 | 154 | ||
154 | fn option_env_expand( | 155 | fn assert_expand( |
155 | _db: &dyn AstDatabase, | 156 | _db: &dyn AstDatabase, |
156 | _id: LazyMacroId, | 157 | _id: LazyMacroId, |
157 | _tt: &tt::Subtree, | 158 | tt: &tt::Subtree, |
158 | ) -> Result<tt::Subtree, mbe::ExpandError> { | 159 | ) -> Result<tt::Subtree, mbe::ExpandError> { |
159 | // dummy implementation for type-checking purposes | 160 | // A hacky implementation for goto def and hover |
160 | let expanded = quote! { std::option::Option::None::<&str> }; | 161 | // We expand `assert!(cond, arg1, arg2)` to |
162 | // ``` | ||
163 | // {(cond, &(arg1), &(arg2));} | ||
164 | // ```, | ||
165 | // which is wrong but useful. | ||
161 | 166 | ||
162 | Ok(expanded) | 167 | let mut args = Vec::new(); |
163 | } | 168 | let mut current = Vec::new(); |
169 | for tt in tt.token_trees.iter().cloned() { | ||
170 | match tt { | ||
171 | tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => { | ||
172 | args.push(current); | ||
173 | current = Vec::new(); | ||
174 | } | ||
175 | _ => { | ||
176 | current.push(tt); | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | if !current.is_empty() { | ||
181 | args.push(current); | ||
182 | } | ||
183 | |||
184 | let arg_tts = args.into_iter().flat_map(|arg| { | ||
185 | quote! { &(##arg), } | ||
186 | }.token_trees).collect::<Vec<_>>(); | ||
164 | 187 | ||
165 | fn column_expand( | ||
166 | _db: &dyn AstDatabase, | ||
167 | _id: LazyMacroId, | ||
168 | _tt: &tt::Subtree, | ||
169 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
170 | // dummy implementation for type-checking purposes | ||
171 | let col_num = 0; | ||
172 | let expanded = quote! { | 188 | let expanded = quote! { |
173 | #col_num | 189 | { { (##arg_tts); } } |
174 | }; | 190 | }; |
175 | |||
176 | Ok(expanded) | 191 | Ok(expanded) |
177 | } | 192 | } |
178 | 193 | ||
@@ -278,30 +293,37 @@ fn concat_expand( | |||
278 | 293 | ||
279 | fn relative_file(db: &dyn AstDatabase, call_id: MacroCallId, path: &str) -> Option<FileId> { | 294 | fn relative_file(db: &dyn AstDatabase, call_id: MacroCallId, path: &str) -> Option<FileId> { |
280 | let call_site = call_id.as_file().original_file(db); | 295 | let call_site = call_id.as_file().original_file(db); |
281 | let path = RelativePath::new(&path); | ||
282 | 296 | ||
283 | let res = db.resolve_relative_path(call_site, &path)?; | 297 | // Handle trivial case |
284 | // Prevent include itself | 298 | if let Some(res) = db.resolve_relative_path(call_site, &RelativePath::new(&path)) { |
285 | if res == call_site { | 299 | // Prevent include itself |
286 | return None; | 300 | return if res == call_site { None } else { Some(res) }; |
287 | } | 301 | } |
288 | Some(res) | 302 | |
303 | // Extern paths ? | ||
304 | let krate = db.relevant_crates(call_site).get(0)?.clone(); | ||
305 | let (extern_source_id, relative_file) = | ||
306 | db.crate_graph()[krate].extern_source.extern_path(path)?; | ||
307 | |||
308 | db.resolve_extern_path(extern_source_id, &relative_file) | ||
289 | } | 309 | } |
290 | 310 | ||
291 | fn include_expand( | 311 | fn parse_string(tt: &tt::Subtree) -> Result<String, mbe::ExpandError> { |
292 | db: &dyn AstDatabase, | 312 | tt.token_trees |
293 | arg_id: EagerMacroId, | ||
294 | tt: &tt::Subtree, | ||
295 | ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { | ||
296 | let path = tt | ||
297 | .token_trees | ||
298 | .get(0) | 313 | .get(0) |
299 | .and_then(|tt| match tt { | 314 | .and_then(|tt| match tt { |
300 | tt::TokenTree::Leaf(tt::Leaf::Literal(it)) => unquote_str(&it), | 315 | tt::TokenTree::Leaf(tt::Leaf::Literal(it)) => unquote_str(&it), |
301 | _ => None, | 316 | _ => None, |
302 | }) | 317 | }) |
303 | .ok_or_else(|| mbe::ExpandError::ConversionError)?; | 318 | .ok_or_else(|| mbe::ExpandError::ConversionError) |
319 | } | ||
304 | 320 | ||
321 | fn include_expand( | ||
322 | db: &dyn AstDatabase, | ||
323 | arg_id: EagerMacroId, | ||
324 | tt: &tt::Subtree, | ||
325 | ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { | ||
326 | let path = parse_string(tt)?; | ||
305 | let file_id = | 327 | let file_id = |
306 | relative_file(db, arg_id.into(), &path).ok_or_else(|| mbe::ExpandError::ConversionError)?; | 328 | relative_file(db, arg_id.into(), &path).ok_or_else(|| mbe::ExpandError::ConversionError)?; |
307 | 329 | ||
@@ -314,12 +336,58 @@ fn include_expand( | |||
314 | Ok((res, FragmentKind::Items)) | 336 | Ok((res, FragmentKind::Items)) |
315 | } | 337 | } |
316 | 338 | ||
339 | fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { | ||
340 | let call_id: MacroCallId = arg_id.into(); | ||
341 | let original_file = call_id.as_file().original_file(db); | ||
342 | |||
343 | let krate = db.relevant_crates(original_file).get(0)?.clone(); | ||
344 | db.crate_graph()[krate].env.get(key) | ||
345 | } | ||
346 | |||
347 | fn env_expand( | ||
348 | db: &dyn AstDatabase, | ||
349 | arg_id: EagerMacroId, | ||
350 | tt: &tt::Subtree, | ||
351 | ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { | ||
352 | let key = parse_string(tt)?; | ||
353 | |||
354 | // FIXME: | ||
355 | // If the environment variable is not defined int rustc, then a compilation error will be emitted. | ||
356 | // We might do the same if we fully support all other stuffs. | ||
357 | // But for now on, we should return some dummy string for better type infer purpose. | ||
358 | // However, we cannot use an empty string here, because for | ||
359 | // `include!(concat!(env!("OUT_DIR"), "/foo.rs"))` will become | ||
360 | // `include!("foo.rs"), which might go to infinite loop | ||
361 | let s = get_env_inner(db, arg_id, &key).unwrap_or("__RA_UNIMPLEMENTATED__".to_string()); | ||
362 | let expanded = quote! { #s }; | ||
363 | |||
364 | Ok((expanded, FragmentKind::Expr)) | ||
365 | } | ||
366 | |||
367 | fn option_env_expand( | ||
368 | db: &dyn AstDatabase, | ||
369 | arg_id: EagerMacroId, | ||
370 | tt: &tt::Subtree, | ||
371 | ) -> Result<(tt::Subtree, FragmentKind), mbe::ExpandError> { | ||
372 | let key = parse_string(tt)?; | ||
373 | let expanded = match get_env_inner(db, arg_id, &key) { | ||
374 | None => quote! { std::option::Option::None::<&str> }, | ||
375 | Some(s) => quote! { std::option::Some(#s) }, | ||
376 | }; | ||
377 | |||
378 | Ok((expanded, FragmentKind::Expr)) | ||
379 | } | ||
380 | |||
317 | #[cfg(test)] | 381 | #[cfg(test)] |
318 | mod tests { | 382 | mod tests { |
319 | use super::*; | 383 | use super::*; |
320 | use crate::{name::AsName, test_db::TestDB, AstNode, MacroCallId, MacroCallKind, MacroCallLoc}; | 384 | use crate::{ |
385 | name::AsName, test_db::TestDB, AstNode, EagerCallLoc, MacroCallId, MacroCallKind, | ||
386 | MacroCallLoc, | ||
387 | }; | ||
321 | use ra_db::{fixture::WithFixture, SourceDatabase}; | 388 | use ra_db::{fixture::WithFixture, SourceDatabase}; |
322 | use ra_syntax::ast::NameOwner; | 389 | use ra_syntax::ast::NameOwner; |
390 | use std::sync::Arc; | ||
323 | 391 | ||
324 | fn expand_builtin_macro(ra_fixture: &str) -> String { | 392 | fn expand_builtin_macro(ra_fixture: &str) -> String { |
325 | let (db, file_id) = TestDB::with_single_file(&ra_fixture); | 393 | let (db, file_id) = TestDB::with_single_file(&ra_fixture); |
@@ -330,27 +398,61 @@ mod tests { | |||
330 | let ast_id_map = db.ast_id_map(file_id.into()); | 398 | let ast_id_map = db.ast_id_map(file_id.into()); |
331 | 399 | ||
332 | let expander = find_by_name(¯o_calls[0].name().unwrap().as_name()).unwrap(); | 400 | let expander = find_by_name(¯o_calls[0].name().unwrap().as_name()).unwrap(); |
333 | let expander = expander.left().unwrap(); | ||
334 | 401 | ||
335 | // the first one should be a macro_rules | 402 | let file_id = match expander { |
336 | let def = MacroDefId { | 403 | Either::Left(expander) => { |
337 | krate: Some(CrateId(0)), | 404 | // the first one should be a macro_rules |
338 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), | 405 | let def = MacroDefId { |
339 | kind: MacroDefKind::BuiltIn(expander), | 406 | krate: Some(CrateId(0)), |
340 | }; | 407 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), |
408 | kind: MacroDefKind::BuiltIn(expander), | ||
409 | }; | ||
341 | 410 | ||
342 | let loc = MacroCallLoc { | 411 | let loc = MacroCallLoc { |
343 | def, | 412 | def, |
344 | kind: MacroCallKind::FnLike(AstId::new( | 413 | kind: MacroCallKind::FnLike(AstId::new( |
345 | file_id.into(), | 414 | file_id.into(), |
346 | ast_id_map.ast_id(¯o_calls[1]), | 415 | ast_id_map.ast_id(¯o_calls[1]), |
347 | )), | 416 | )), |
348 | }; | 417 | }; |
418 | |||
419 | let id: MacroCallId = db.intern_macro(loc).into(); | ||
420 | id.as_file() | ||
421 | } | ||
422 | Either::Right(expander) => { | ||
423 | // the first one should be a macro_rules | ||
424 | let def = MacroDefId { | ||
425 | krate: Some(CrateId(0)), | ||
426 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), | ||
427 | kind: MacroDefKind::BuiltInEager(expander), | ||
428 | }; | ||
349 | 429 | ||
350 | let id: MacroCallId = db.intern_macro(loc).into(); | 430 | let args = macro_calls[1].token_tree().unwrap(); |
351 | let parsed = db.parse_or_expand(id.as_file()).unwrap(); | 431 | let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; |
432 | |||
433 | let arg_id = db.intern_eager_expansion({ | ||
434 | EagerCallLoc { | ||
435 | def, | ||
436 | fragment: FragmentKind::Expr, | ||
437 | subtree: Arc::new(parsed_args.clone()), | ||
438 | file_id: file_id.into(), | ||
439 | } | ||
440 | }); | ||
441 | |||
442 | let (subtree, fragment) = expander.expand(&db, arg_id, &parsed_args).unwrap(); | ||
443 | let eager = EagerCallLoc { | ||
444 | def, | ||
445 | fragment, | ||
446 | subtree: Arc::new(subtree), | ||
447 | file_id: file_id.into(), | ||
448 | }; | ||
352 | 449 | ||
353 | parsed.text().to_string() | 450 | let id: MacroCallId = db.intern_eager_expansion(eager.into()).into(); |
451 | id.as_file() | ||
452 | } | ||
453 | }; | ||
454 | |||
455 | db.parse_or_expand(file_id).unwrap().to_string() | ||
354 | } | 456 | } |
355 | 457 | ||
356 | #[test] | 458 | #[test] |
@@ -432,6 +534,22 @@ mod tests { | |||
432 | } | 534 | } |
433 | 535 | ||
434 | #[test] | 536 | #[test] |
537 | fn test_assert_expand() { | ||
538 | let expanded = expand_builtin_macro( | ||
539 | r#" | ||
540 | #[rustc_builtin_macro] | ||
541 | macro_rules! assert { | ||
542 | ($cond:expr) => ({ /* compiler built-in */ }); | ||
543 | ($cond:expr, $($args:tt)*) => ({ /* compiler built-in */ }) | ||
544 | } | ||
545 | assert!(true, "{} {:?}", arg1(a, b, c), arg2); | ||
546 | "#, | ||
547 | ); | ||
548 | |||
549 | assert_eq!(expanded, "{{(&(true), &(\"{} {:?}\"), &(arg1(a,b,c)), &(arg2),);}}"); | ||
550 | } | ||
551 | |||
552 | #[test] | ||
435 | fn test_compile_error_expand() { | 553 | fn test_compile_error_expand() { |
436 | let expanded = expand_builtin_macro( | 554 | let expanded = expand_builtin_macro( |
437 | r#" | 555 | r#" |
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs index 6d201256f..25cc1e9fc 100644 --- a/crates/ra_hir_expand/src/name.rs +++ b/crates/ra_hir_expand/src/name.rs | |||
@@ -172,6 +172,7 @@ pub mod known { | |||
172 | column, | 172 | column, |
173 | compile_error, | 173 | compile_error, |
174 | line, | 174 | line, |
175 | assert, | ||
175 | stringify, | 176 | stringify, |
176 | concat, | 177 | concat, |
177 | include, | 178 | include, |
diff --git a/crates/ra_hir_expand/src/quote.rs b/crates/ra_hir_expand/src/quote.rs index 57e7eebf9..3fd4233da 100644 --- a/crates/ra_hir_expand/src/quote.rs +++ b/crates/ra_hir_expand/src/quote.rs | |||
@@ -99,6 +99,7 @@ macro_rules! __quote { | |||
99 | ( & ) => {$crate::__quote!(@PUNCT '&')}; | 99 | ( & ) => {$crate::__quote!(@PUNCT '&')}; |
100 | ( , ) => {$crate::__quote!(@PUNCT ',')}; | 100 | ( , ) => {$crate::__quote!(@PUNCT ',')}; |
101 | ( : ) => {$crate::__quote!(@PUNCT ':')}; | 101 | ( : ) => {$crate::__quote!(@PUNCT ':')}; |
102 | ( ; ) => {$crate::__quote!(@PUNCT ';')}; | ||
102 | ( :: ) => {$crate::__quote!(@PUNCT ':', ':')}; | 103 | ( :: ) => {$crate::__quote!(@PUNCT ':', ':')}; |
103 | ( . ) => {$crate::__quote!(@PUNCT '.')}; | 104 | ( . ) => {$crate::__quote!(@PUNCT '.')}; |
104 | ( < ) => {$crate::__quote!(@PUNCT '<')}; | 105 | ( < ) => {$crate::__quote!(@PUNCT '<')}; |
diff --git a/crates/ra_hir_expand/src/test_db.rs b/crates/ra_hir_expand/src/test_db.rs index 918736e2a..c1fb762de 100644 --- a/crates/ra_hir_expand/src/test_db.rs +++ b/crates/ra_hir_expand/src/test_db.rs | |||
@@ -5,7 +5,7 @@ use std::{ | |||
5 | sync::{Arc, Mutex}, | 5 | sync::{Arc, Mutex}, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath}; | 8 | use ra_db::{salsa, CrateId, ExternSourceId, FileId, FileLoader, FileLoaderDelegate, RelativePath}; |
9 | 9 | ||
10 | #[salsa::database( | 10 | #[salsa::database( |
11 | ra_db::SourceDatabaseExtStorage, | 11 | ra_db::SourceDatabaseExtStorage, |
@@ -51,4 +51,11 @@ impl FileLoader for TestDB { | |||
51 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { | 51 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { |
52 | FileLoaderDelegate(self).relevant_crates(file_id) | 52 | FileLoaderDelegate(self).relevant_crates(file_id) |
53 | } | 53 | } |
54 | fn resolve_extern_path( | ||
55 | &self, | ||
56 | anchor: ExternSourceId, | ||
57 | relative_path: &RelativePath, | ||
58 | ) -> Option<FileId> { | ||
59 | FileLoaderDelegate(self).resolve_extern_path(anchor, relative_path) | ||
60 | } | ||
54 | } | 61 | } |
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs index c794f7b84..0be2fea4b 100644 --- a/crates/ra_hir_ty/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs | |||
@@ -67,6 +67,13 @@ impl FileLoader for TestDB { | |||
67 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { | 67 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { |
68 | FileLoaderDelegate(self).relevant_crates(file_id) | 68 | FileLoaderDelegate(self).relevant_crates(file_id) |
69 | } | 69 | } |
70 | fn resolve_extern_path( | ||
71 | &self, | ||
72 | extern_id: ra_db::ExternSourceId, | ||
73 | relative_path: &RelativePath, | ||
74 | ) -> Option<FileId> { | ||
75 | FileLoaderDelegate(self).resolve_extern_path(extern_id, relative_path) | ||
76 | } | ||
70 | } | 77 | } |
71 | 78 | ||
72 | impl TestDB { | 79 | impl TestDB { |
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs index ffa78b046..32457bbf7 100644 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ b/crates/ra_hir_ty/src/tests/macros.rs | |||
@@ -550,6 +550,26 @@ fn main() { | |||
550 | } | 550 | } |
551 | 551 | ||
552 | #[test] | 552 | #[test] |
553 | fn infer_builtin_macros_env() { | ||
554 | assert_snapshot!( | ||
555 | infer(r#" | ||
556 | //- /main.rs env:foo=bar | ||
557 | #[rustc_builtin_macro] | ||
558 | macro_rules! env {() => {}} | ||
559 | |||
560 | fn main() { | ||
561 | let x = env!("foo"); | ||
562 | } | ||
563 | "#), | ||
564 | @r###" | ||
565 | ![0; 5) '"bar"': &str | ||
566 | [88; 116) '{ ...o"); }': () | ||
567 | [98; 99) 'x': &str | ||
568 | "### | ||
569 | ); | ||
570 | } | ||
571 | |||
572 | #[test] | ||
553 | fn infer_derive_clone_simple() { | 573 | fn infer_derive_clone_simple() { |
554 | let (db, pos) = TestDB::with_position( | 574 | let (db, pos) = TestDB::with_position( |
555 | r#" | 575 | r#" |
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs index a27e0fc15..93e53c921 100644 --- a/crates/ra_ide/src/completion.rs +++ b/crates/ra_ide/src/completion.rs | |||
@@ -16,11 +16,11 @@ mod complete_scope; | |||
16 | mod complete_postfix; | 16 | mod complete_postfix; |
17 | mod complete_macro_in_item_position; | 17 | mod complete_macro_in_item_position; |
18 | mod complete_trait_impl; | 18 | mod complete_trait_impl; |
19 | #[cfg(test)] | ||
20 | mod test_utils; | ||
19 | 21 | ||
20 | use ra_ide_db::RootDatabase; | 22 | use ra_ide_db::RootDatabase; |
21 | 23 | ||
22 | #[cfg(test)] | ||
23 | use crate::completion::completion_item::do_completion; | ||
24 | use crate::{ | 24 | use crate::{ |
25 | completion::{ | 25 | completion::{ |
26 | completion_context::CompletionContext, | 26 | completion_context::CompletionContext, |
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs index d8f6f0d9d..81e5037aa 100644 --- a/crates/ra_ide/src/completion/complete_dot.rs +++ b/crates/ra_ide/src/completion/complete_dot.rs | |||
@@ -70,7 +70,7 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &T | |||
70 | 70 | ||
71 | #[cfg(test)] | 71 | #[cfg(test)] |
72 | mod tests { | 72 | mod tests { |
73 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 73 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
74 | use insta::assert_debug_snapshot; | 74 | use insta::assert_debug_snapshot; |
75 | 75 | ||
76 | fn do_ref_completion(code: &str) -> Vec<CompletionItem> { | 76 | fn do_ref_completion(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/complete_fn_param.rs b/crates/ra_ide/src/completion/complete_fn_param.rs index 502458706..9226ac055 100644 --- a/crates/ra_ide/src/completion/complete_fn_param.rs +++ b/crates/ra_ide/src/completion/complete_fn_param.rs | |||
@@ -52,7 +52,7 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) | |||
52 | 52 | ||
53 | #[cfg(test)] | 53 | #[cfg(test)] |
54 | mod tests { | 54 | mod tests { |
55 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 55 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
56 | use insta::assert_debug_snapshot; | 56 | use insta::assert_debug_snapshot; |
57 | 57 | ||
58 | fn do_magic_completion(code: &str) -> Vec<CompletionItem> { | 58 | fn do_magic_completion(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs index e1c0ffb1f..1e053ea4a 100644 --- a/crates/ra_ide/src/completion/complete_keyword.rs +++ b/crates/ra_ide/src/completion/complete_keyword.rs | |||
@@ -117,7 +117,7 @@ fn complete_return( | |||
117 | 117 | ||
118 | #[cfg(test)] | 118 | #[cfg(test)] |
119 | mod tests { | 119 | mod tests { |
120 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 120 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
121 | use insta::assert_debug_snapshot; | 121 | use insta::assert_debug_snapshot; |
122 | 122 | ||
123 | fn do_keyword_completion(code: &str) -> Vec<CompletionItem> { | 123 | fn do_keyword_completion(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs index 1866d9e6c..270e96df0 100644 --- a/crates/ra_ide/src/completion/complete_macro_in_item_position.rs +++ b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs | |||
@@ -15,9 +15,10 @@ pub(super) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &Compl | |||
15 | 15 | ||
16 | #[cfg(test)] | 16 | #[cfg(test)] |
17 | mod tests { | 17 | mod tests { |
18 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | ||
19 | use insta::assert_debug_snapshot; | 18 | use insta::assert_debug_snapshot; |
20 | 19 | ||
20 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; | ||
21 | |||
21 | fn do_reference_completion(code: &str) -> Vec<CompletionItem> { | 22 | fn do_reference_completion(code: &str) -> Vec<CompletionItem> { |
22 | do_completion(code, CompletionKind::Reference) | 23 | do_completion(code, CompletionKind::Reference) |
23 | } | 24 | } |
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs index 3c4a70561..d588ee364 100644 --- a/crates/ra_ide/src/completion/complete_path.rs +++ b/crates/ra_ide/src/completion/complete_path.rs | |||
@@ -103,7 +103,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
103 | mod tests { | 103 | mod tests { |
104 | use test_utils::covers; | 104 | use test_utils::covers; |
105 | 105 | ||
106 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 106 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
107 | use insta::assert_debug_snapshot; | 107 | use insta::assert_debug_snapshot; |
108 | 108 | ||
109 | fn do_reference_completion(code: &str) -> Vec<CompletionItem> { | 109 | fn do_reference_completion(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/complete_pattern.rs b/crates/ra_ide/src/completion/complete_pattern.rs index fa8aeceda..6a1a66ef1 100644 --- a/crates/ra_ide/src/completion/complete_pattern.rs +++ b/crates/ra_ide/src/completion/complete_pattern.rs | |||
@@ -27,7 +27,7 @@ pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
27 | 27 | ||
28 | #[cfg(test)] | 28 | #[cfg(test)] |
29 | mod tests { | 29 | mod tests { |
30 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 30 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
31 | use insta::assert_debug_snapshot; | 31 | use insta::assert_debug_snapshot; |
32 | 32 | ||
33 | fn complete(code: &str) -> Vec<CompletionItem> { | 33 | fn complete(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs index 6d000548d..0ba382165 100644 --- a/crates/ra_ide/src/completion/complete_postfix.rs +++ b/crates/ra_ide/src/completion/complete_postfix.rs | |||
@@ -81,7 +81,7 @@ fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: | |||
81 | mod tests { | 81 | mod tests { |
82 | use insta::assert_debug_snapshot; | 82 | use insta::assert_debug_snapshot; |
83 | 83 | ||
84 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 84 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
85 | 85 | ||
86 | fn do_postfix_completion(code: &str) -> Vec<CompletionItem> { | 86 | fn do_postfix_completion(code: &str) -> Vec<CompletionItem> { |
87 | do_completion(code, CompletionKind::Postfix) | 87 | do_completion(code, CompletionKind::Postfix) |
diff --git a/crates/ra_ide/src/completion/complete_record_literal.rs b/crates/ra_ide/src/completion/complete_record_literal.rs index be6e4194f..83ed1d52c 100644 --- a/crates/ra_ide/src/completion/complete_record_literal.rs +++ b/crates/ra_ide/src/completion/complete_record_literal.rs | |||
@@ -18,7 +18,7 @@ pub(super) fn complete_record_literal(acc: &mut Completions, ctx: &CompletionCon | |||
18 | 18 | ||
19 | #[cfg(test)] | 19 | #[cfg(test)] |
20 | mod tests { | 20 | mod tests { |
21 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 21 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
22 | use insta::assert_debug_snapshot; | 22 | use insta::assert_debug_snapshot; |
23 | 23 | ||
24 | fn complete(code: &str) -> Vec<CompletionItem> { | 24 | fn complete(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/complete_record_pattern.rs b/crates/ra_ide/src/completion/complete_record_pattern.rs index 687c57d3e..962376428 100644 --- a/crates/ra_ide/src/completion/complete_record_pattern.rs +++ b/crates/ra_ide/src/completion/complete_record_pattern.rs | |||
@@ -17,7 +17,7 @@ pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionCon | |||
17 | 17 | ||
18 | #[cfg(test)] | 18 | #[cfg(test)] |
19 | mod tests { | 19 | mod tests { |
20 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 20 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
21 | use insta::assert_debug_snapshot; | 21 | use insta::assert_debug_snapshot; |
22 | 22 | ||
23 | fn complete(code: &str) -> Vec<CompletionItem> { | 23 | fn complete(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs index eb3c8cf1b..bd4adf23a 100644 --- a/crates/ra_ide/src/completion/complete_scope.rs +++ b/crates/ra_ide/src/completion/complete_scope.rs | |||
@@ -14,10 +14,10 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
14 | mod tests { | 14 | mod tests { |
15 | use insta::assert_debug_snapshot; | 15 | use insta::assert_debug_snapshot; |
16 | 16 | ||
17 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 17 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
18 | 18 | ||
19 | fn do_reference_completion(code: &str) -> Vec<CompletionItem> { | 19 | fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> { |
20 | do_completion(code, CompletionKind::Reference) | 20 | do_completion(ra_fixture, CompletionKind::Reference) |
21 | } | 21 | } |
22 | 22 | ||
23 | #[test] | 23 | #[test] |
diff --git a/crates/ra_ide/src/completion/complete_snippet.rs b/crates/ra_ide/src/completion/complete_snippet.rs index 731b4fd82..f731e9b9a 100644 --- a/crates/ra_ide/src/completion/complete_snippet.rs +++ b/crates/ra_ide/src/completion/complete_snippet.rs | |||
@@ -42,7 +42,7 @@ fn ${1:feature}() { | |||
42 | 42 | ||
43 | #[cfg(test)] | 43 | #[cfg(test)] |
44 | mod tests { | 44 | mod tests { |
45 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 45 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
46 | use insta::assert_debug_snapshot; | 46 | use insta::assert_debug_snapshot; |
47 | 47 | ||
48 | fn do_snippet_completion(code: &str) -> Vec<CompletionItem> { | 48 | fn do_snippet_completion(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/complete_trait_impl.rs b/crates/ra_ide/src/completion/complete_trait_impl.rs index 2bf654a57..7fefa2c7a 100644 --- a/crates/ra_ide/src/completion/complete_trait_impl.rs +++ b/crates/ra_ide/src/completion/complete_trait_impl.rs | |||
@@ -217,7 +217,7 @@ fn make_const_compl_syntax(const_: &ast::ConstDef) -> String { | |||
217 | 217 | ||
218 | #[cfg(test)] | 218 | #[cfg(test)] |
219 | mod tests { | 219 | mod tests { |
220 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 220 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
221 | use insta::assert_debug_snapshot; | 221 | use insta::assert_debug_snapshot; |
222 | 222 | ||
223 | fn complete(code: &str) -> Vec<CompletionItem> { | 223 | fn complete(code: &str) -> Vec<CompletionItem> { |
diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs index 1d14e9636..ef0eb43b2 100644 --- a/crates/ra_ide/src/completion/completion_item.rs +++ b/crates/ra_ide/src/completion/completion_item.rs | |||
@@ -13,7 +13,7 @@ pub struct CompletionItem { | |||
13 | /// Used only internally in tests, to check only specific kind of | 13 | /// Used only internally in tests, to check only specific kind of |
14 | /// completion (postfix, keyword, reference, etc). | 14 | /// completion (postfix, keyword, reference, etc). |
15 | #[allow(unused)] | 15 | #[allow(unused)] |
16 | completion_kind: CompletionKind, | 16 | pub(crate) completion_kind: CompletionKind, |
17 | /// Label in the completion pop up which identifies completion. | 17 | /// Label in the completion pop up which identifies completion. |
18 | label: String, | 18 | label: String, |
19 | /// Range of identifier that is being completed. | 19 | /// Range of identifier that is being completed. |
@@ -318,24 +318,3 @@ impl Into<Vec<CompletionItem>> for Completions { | |||
318 | self.buf | 318 | self.buf |
319 | } | 319 | } |
320 | } | 320 | } |
321 | |||
322 | #[cfg(test)] | ||
323 | pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> { | ||
324 | use crate::{ | ||
325 | completion::{completions, CompletionOptions}, | ||
326 | mock_analysis::{analysis_and_position, single_file_with_position}, | ||
327 | }; | ||
328 | |||
329 | let (analysis, position) = if code.contains("//-") { | ||
330 | analysis_and_position(code) | ||
331 | } else { | ||
332 | single_file_with_position(code) | ||
333 | }; | ||
334 | let options = CompletionOptions::default(); | ||
335 | let completions = completions(&analysis.db, position, &options).unwrap(); | ||
336 | let completion_items: Vec<CompletionItem> = completions.into(); | ||
337 | let mut kind_completions: Vec<CompletionItem> = | ||
338 | completion_items.into_iter().filter(|c| c.completion_kind == kind).collect(); | ||
339 | kind_completions.sort_by_key(|c| c.label.clone()); | ||
340 | kind_completions | ||
341 | } | ||
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 3dc56e4a3..5213def20 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -307,12 +307,22 @@ mod tests { | |||
307 | use insta::assert_debug_snapshot; | 307 | use insta::assert_debug_snapshot; |
308 | use test_utils::covers; | 308 | use test_utils::covers; |
309 | 309 | ||
310 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | 310 | use crate::completion::{ |
311 | test_utils::{do_completion, do_completion_with_options}, | ||
312 | CompletionItem, CompletionKind, CompletionOptions, | ||
313 | }; | ||
311 | 314 | ||
312 | fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> { | 315 | fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> { |
313 | do_completion(ra_fixture, CompletionKind::Reference) | 316 | do_completion(ra_fixture, CompletionKind::Reference) |
314 | } | 317 | } |
315 | 318 | ||
319 | fn do_reference_completion_with_options( | ||
320 | ra_fixture: &str, | ||
321 | options: CompletionOptions, | ||
322 | ) -> Vec<CompletionItem> { | ||
323 | do_completion_with_options(ra_fixture, CompletionKind::Reference, &options) | ||
324 | } | ||
325 | |||
316 | #[test] | 326 | #[test] |
317 | fn enum_detail_includes_names_for_record() { | 327 | fn enum_detail_includes_names_for_record() { |
318 | assert_debug_snapshot!( | 328 | assert_debug_snapshot!( |
@@ -533,7 +543,7 @@ mod tests { | |||
533 | } | 543 | } |
534 | 544 | ||
535 | #[test] | 545 | #[test] |
536 | fn parens_for_method_call() { | 546 | fn arg_snippets_for_method_call() { |
537 | assert_debug_snapshot!( | 547 | assert_debug_snapshot!( |
538 | do_reference_completion( | 548 | do_reference_completion( |
539 | r" | 549 | r" |
@@ -563,6 +573,40 @@ mod tests { | |||
563 | } | 573 | } |
564 | 574 | ||
565 | #[test] | 575 | #[test] |
576 | fn no_arg_snippets_for_method_call() { | ||
577 | assert_debug_snapshot!( | ||
578 | do_reference_completion_with_options( | ||
579 | r" | ||
580 | struct S {} | ||
581 | impl S { | ||
582 | fn foo(&self, x: i32) {} | ||
583 | } | ||
584 | fn bar(s: &S) { | ||
585 | s.f<|> | ||
586 | } | ||
587 | ", | ||
588 | CompletionOptions { | ||
589 | add_call_argument_snippets: false, | ||
590 | .. Default::default() | ||
591 | } | ||
592 | ), | ||
593 | @r###" | ||
594 | [ | ||
595 | CompletionItem { | ||
596 | label: "foo(…)", | ||
597 | source_range: [171; 172), | ||
598 | delete: [171; 172), | ||
599 | insert: "foo($0)", | ||
600 | kind: Method, | ||
601 | lookup: "foo", | ||
602 | detail: "fn foo(&self, x: i32)", | ||
603 | }, | ||
604 | ] | ||
605 | "### | ||
606 | ) | ||
607 | } | ||
608 | |||
609 | #[test] | ||
566 | fn dont_render_function_parens_in_use_item() { | 610 | fn dont_render_function_parens_in_use_item() { |
567 | assert_debug_snapshot!( | 611 | assert_debug_snapshot!( |
568 | do_reference_completion( | 612 | do_reference_completion( |
diff --git a/crates/ra_ide/src/completion/test_utils.rs b/crates/ra_ide/src/completion/test_utils.rs new file mode 100644 index 000000000..136857315 --- /dev/null +++ b/crates/ra_ide/src/completion/test_utils.rs | |||
@@ -0,0 +1,29 @@ | |||
1 | //! Runs completion for testing purposes. | ||
2 | |||
3 | use crate::{ | ||
4 | completion::{completion_item::CompletionKind, CompletionOptions}, | ||
5 | mock_analysis::{analysis_and_position, single_file_with_position}, | ||
6 | CompletionItem, | ||
7 | }; | ||
8 | |||
9 | pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> { | ||
10 | do_completion_with_options(code, kind, &CompletionOptions::default()) | ||
11 | } | ||
12 | |||
13 | pub(crate) fn do_completion_with_options( | ||
14 | code: &str, | ||
15 | kind: CompletionKind, | ||
16 | options: &CompletionOptions, | ||
17 | ) -> Vec<CompletionItem> { | ||
18 | let (analysis, position) = if code.contains("//-") { | ||
19 | analysis_and_position(code) | ||
20 | } else { | ||
21 | single_file_with_position(code) | ||
22 | }; | ||
23 | let completions = analysis.completions(position, options).unwrap().unwrap(); | ||
24 | let completion_items: Vec<CompletionItem> = completions.into(); | ||
25 | let mut kind_completions: Vec<CompletionItem> = | ||
26 | completion_items.into_iter().filter(|c| c.completion_kind == kind).collect(); | ||
27 | kind_completions.sort_by_key(|c| c.label().to_owned()); | ||
28 | kind_completions | ||
29 | } | ||
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 25e038a55..0bbba4855 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -833,19 +833,34 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
833 | } | 833 | } |
834 | 834 | ||
835 | #[test] | 835 | #[test] |
836 | fn test_hover_through_assert_macro() { | ||
837 | let hover_on = check_hover_result( | ||
838 | r#" | ||
839 | //- /lib.rs | ||
840 | #[rustc_builtin_macro] | ||
841 | macro_rules! assert {} | ||
842 | |||
843 | fn bar() -> bool { true } | ||
844 | fn foo() { | ||
845 | assert!(ba<|>r()); | ||
846 | } | ||
847 | "#, | ||
848 | &["fn bar() -> bool"], | ||
849 | ); | ||
850 | |||
851 | assert_eq!(hover_on, "bar"); | ||
852 | } | ||
853 | |||
854 | #[test] | ||
836 | fn test_hover_through_literal_string_in_builtin_macro() { | 855 | fn test_hover_through_literal_string_in_builtin_macro() { |
837 | check_hover_no_result( | 856 | check_hover_no_result( |
838 | r#" | 857 | r#" |
839 | //- /lib.rs | 858 | //- /lib.rs |
840 | #[rustc_builtin_macro] | 859 | #[rustc_builtin_macro] |
841 | macro_rules! assert { | 860 | macro_rules! format {} |
842 | ($cond:expr) => {{ /* compiler built-in */ }}; | ||
843 | ($cond:expr,) => {{ /* compiler built-in */ }}; | ||
844 | ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }}; | ||
845 | } | ||
846 | 861 | ||
847 | fn foo() { | 862 | fn foo() { |
848 | assert!("hel<|>lo"); | 863 | format!("hel<|>lo {}", 0); |
849 | } | 864 | } |
850 | "#, | 865 | "#, |
851 | ); | 866 | ); |
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index a3acfd225..922e4caa8 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs | |||
@@ -212,6 +212,7 @@ impl Analysis { | |||
212 | None, | 212 | None, |
213 | cfg_options, | 213 | cfg_options, |
214 | Env::default(), | 214 | Env::default(), |
215 | Default::default(), | ||
215 | ); | 216 | ); |
216 | change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text)); | 217 | change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text)); |
217 | change.set_crate_graph(crate_graph); | 218 | change.set_crate_graph(crate_graph); |
diff --git a/crates/ra_ide/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs index 90f84b052..25816cf6f 100644 --- a/crates/ra_ide/src/mock_analysis.rs +++ b/crates/ra_ide/src/mock_analysis.rs | |||
@@ -102,6 +102,7 @@ impl MockAnalysis { | |||
102 | None, | 102 | None, |
103 | cfg_options, | 103 | cfg_options, |
104 | Env::default(), | 104 | Env::default(), |
105 | Default::default(), | ||
105 | )); | 106 | )); |
106 | } else if path.ends_with("/lib.rs") { | 107 | } else if path.ends_with("/lib.rs") { |
107 | let crate_name = path.parent().unwrap().file_name().unwrap(); | 108 | let crate_name = path.parent().unwrap().file_name().unwrap(); |
@@ -111,6 +112,7 @@ impl MockAnalysis { | |||
111 | Some(crate_name.to_owned()), | 112 | Some(crate_name.to_owned()), |
112 | cfg_options, | 113 | cfg_options, |
113 | Env::default(), | 114 | Env::default(), |
115 | Default::default(), | ||
114 | ); | 116 | ); |
115 | if let Some(root_crate) = root_crate { | 117 | if let Some(root_crate) = root_crate { |
116 | crate_graph | 118 | crate_graph |
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs index b73cefd97..76d130b9b 100644 --- a/crates/ra_ide/src/parent_module.rs +++ b/crates/ra_ide/src/parent_module.rs | |||
@@ -136,6 +136,7 @@ mod tests { | |||
136 | None, | 136 | None, |
137 | CfgOptions::default(), | 137 | CfgOptions::default(), |
138 | Env::default(), | 138 | Env::default(), |
139 | Default::default(), | ||
139 | ); | 140 | ); |
140 | let mut change = AnalysisChange::new(); | 141 | let mut change = AnalysisChange::new(); |
141 | change.set_crate_graph(crate_graph); | 142 | change.set_crate_graph(crate_graph); |
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 5b4bcf434..7d1190af9 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs | |||
@@ -9,7 +9,8 @@ use ra_syntax::{ | |||
9 | use ra_text_edit::TextEdit; | 9 | use ra_text_edit::TextEdit; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | FileId, FilePosition, FileSystemEdit, RangeInfo, SourceChange, SourceFileEdit, TextRange, | 12 | FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, SourceChange, |
13 | SourceFileEdit, TextRange, | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | use super::find_all_refs; | 16 | use super::find_all_refs; |
@@ -46,12 +47,29 @@ fn find_name_and_module_at_offset( | |||
46 | Some((ast_name, ast_module)) | 47 | Some((ast_name, ast_module)) |
47 | } | 48 | } |
48 | 49 | ||
49 | fn source_edit_from_file_id_range( | 50 | fn source_edit_from_reference(reference: Reference, new_name: &str) -> SourceFileEdit { |
50 | file_id: FileId, | 51 | let mut replacement_text = String::new(); |
51 | range: TextRange, | 52 | let file_id = reference.file_range.file_id; |
52 | new_name: &str, | 53 | let range = match reference.kind { |
53 | ) -> SourceFileEdit { | 54 | ReferenceKind::StructFieldShorthandForField => { |
54 | SourceFileEdit { file_id, edit: TextEdit::replace(range, new_name.into()) } | 55 | replacement_text.push_str(new_name); |
56 | replacement_text.push_str(": "); | ||
57 | TextRange::from_to( | ||
58 | reference.file_range.range.start(), | ||
59 | reference.file_range.range.start(), | ||
60 | ) | ||
61 | } | ||
62 | ReferenceKind::StructFieldShorthandForLocal => { | ||
63 | replacement_text.push_str(": "); | ||
64 | replacement_text.push_str(new_name); | ||
65 | TextRange::from_to(reference.file_range.range.end(), reference.file_range.range.end()) | ||
66 | } | ||
67 | _ => { | ||
68 | replacement_text.push_str(new_name); | ||
69 | reference.file_range.range | ||
70 | } | ||
71 | }; | ||
72 | SourceFileEdit { file_id, edit: TextEdit::replace(range, replacement_text) } | ||
55 | } | 73 | } |
56 | 74 | ||
57 | fn rename_mod( | 75 | fn rename_mod( |
@@ -99,13 +117,10 @@ fn rename_mod( | |||
99 | source_file_edits.push(edit); | 117 | source_file_edits.push(edit); |
100 | 118 | ||
101 | if let Some(RangeInfo { range: _, info: refs }) = find_all_refs(sema.db, position, None) { | 119 | if let Some(RangeInfo { range: _, info: refs }) = find_all_refs(sema.db, position, None) { |
102 | let ref_edits = refs.references.into_iter().map(|reference| { | 120 | let ref_edits = refs |
103 | source_edit_from_file_id_range( | 121 | .references |
104 | reference.file_range.file_id, | 122 | .into_iter() |
105 | reference.file_range.range, | 123 | .map(|reference| source_edit_from_reference(reference, new_name)); |
106 | new_name, | ||
107 | ) | ||
108 | }); | ||
109 | source_file_edits.extend(ref_edits); | 124 | source_file_edits.extend(ref_edits); |
110 | } | 125 | } |
111 | 126 | ||
@@ -121,13 +136,7 @@ fn rename_reference( | |||
121 | 136 | ||
122 | let edit = refs | 137 | let edit = refs |
123 | .into_iter() | 138 | .into_iter() |
124 | .map(|reference| { | 139 | .map(|reference| source_edit_from_reference(reference, new_name)) |
125 | source_edit_from_file_id_range( | ||
126 | reference.file_range.file_id, | ||
127 | reference.file_range.range, | ||
128 | new_name, | ||
129 | ) | ||
130 | }) | ||
131 | .collect::<Vec<_>>(); | 140 | .collect::<Vec<_>>(); |
132 | 141 | ||
133 | if edit.is_empty() { | 142 | if edit.is_empty() { |
@@ -286,6 +295,163 @@ mod tests { | |||
286 | } | 295 | } |
287 | 296 | ||
288 | #[test] | 297 | #[test] |
298 | fn test_rename_struct_field() { | ||
299 | test_rename( | ||
300 | r#" | ||
301 | struct Foo { | ||
302 | i<|>: i32, | ||
303 | } | ||
304 | |||
305 | impl Foo { | ||
306 | fn new(i: i32) -> Self { | ||
307 | Self { i: i } | ||
308 | } | ||
309 | } | ||
310 | "#, | ||
311 | "j", | ||
312 | r#" | ||
313 | struct Foo { | ||
314 | j: i32, | ||
315 | } | ||
316 | |||
317 | impl Foo { | ||
318 | fn new(i: i32) -> Self { | ||
319 | Self { j: i } | ||
320 | } | ||
321 | } | ||
322 | "#, | ||
323 | ); | ||
324 | } | ||
325 | |||
326 | #[test] | ||
327 | fn test_rename_struct_field_for_shorthand() { | ||
328 | test_rename( | ||
329 | r#" | ||
330 | struct Foo { | ||
331 | i<|>: i32, | ||
332 | } | ||
333 | |||
334 | impl Foo { | ||
335 | fn new(i: i32) -> Self { | ||
336 | Self { i } | ||
337 | } | ||
338 | } | ||
339 | "#, | ||
340 | "j", | ||
341 | r#" | ||
342 | struct Foo { | ||
343 | j: i32, | ||
344 | } | ||
345 | |||
346 | impl Foo { | ||
347 | fn new(i: i32) -> Self { | ||
348 | Self { j: i } | ||
349 | } | ||
350 | } | ||
351 | "#, | ||
352 | ); | ||
353 | } | ||
354 | |||
355 | #[test] | ||
356 | fn test_rename_local_for_field_shorthand() { | ||
357 | test_rename( | ||
358 | r#" | ||
359 | struct Foo { | ||
360 | i: i32, | ||
361 | } | ||
362 | |||
363 | impl Foo { | ||
364 | fn new(i<|>: i32) -> Self { | ||
365 | Self { i } | ||
366 | } | ||
367 | } | ||
368 | "#, | ||
369 | "j", | ||
370 | r#" | ||
371 | struct Foo { | ||
372 | i: i32, | ||
373 | } | ||
374 | |||
375 | impl Foo { | ||
376 | fn new(j: i32) -> Self { | ||
377 | Self { i: j } | ||
378 | } | ||
379 | } | ||
380 | "#, | ||
381 | ); | ||
382 | } | ||
383 | |||
384 | #[test] | ||
385 | fn test_field_shorthand_correct_struct() { | ||
386 | test_rename( | ||
387 | r#" | ||
388 | struct Foo { | ||
389 | i<|>: i32, | ||
390 | } | ||
391 | |||
392 | struct Bar { | ||
393 | i: i32, | ||
394 | } | ||
395 | |||
396 | impl Bar { | ||
397 | fn new(i: i32) -> Self { | ||
398 | Self { i } | ||
399 | } | ||
400 | } | ||
401 | "#, | ||
402 | "j", | ||
403 | r#" | ||
404 | struct Foo { | ||
405 | j: i32, | ||
406 | } | ||
407 | |||
408 | struct Bar { | ||
409 | i: i32, | ||
410 | } | ||
411 | |||
412 | impl Bar { | ||
413 | fn new(i: i32) -> Self { | ||
414 | Self { i } | ||
415 | } | ||
416 | } | ||
417 | "#, | ||
418 | ); | ||
419 | } | ||
420 | |||
421 | #[test] | ||
422 | fn test_shadow_local_for_struct_shorthand() { | ||
423 | test_rename( | ||
424 | r#" | ||
425 | struct Foo { | ||
426 | i: i32, | ||
427 | } | ||
428 | |||
429 | fn baz(i<|>: i32) -> Self { | ||
430 | let x = Foo { i }; | ||
431 | { | ||
432 | let i = 0; | ||
433 | Foo { i } | ||
434 | } | ||
435 | } | ||
436 | "#, | ||
437 | "j", | ||
438 | r#" | ||
439 | struct Foo { | ||
440 | i: i32, | ||
441 | } | ||
442 | |||
443 | fn baz(j: i32) -> Self { | ||
444 | let x = Foo { i: j }; | ||
445 | { | ||
446 | let i = 0; | ||
447 | Foo { i } | ||
448 | } | ||
449 | } | ||
450 | "#, | ||
451 | ); | ||
452 | } | ||
453 | |||
454 | #[test] | ||
289 | fn test_rename_mod() { | 455 | fn test_rename_mod() { |
290 | let (analysis, position) = analysis_and_position( | 456 | let (analysis, position) = analysis_and_position( |
291 | " | 457 | " |
diff --git a/crates/ra_ide/src/typing.rs b/crates/ra_ide/src/typing.rs index 7f1b9150f..53c65f8bc 100644 --- a/crates/ra_ide/src/typing.rs +++ b/crates/ra_ide/src/typing.rs | |||
@@ -13,77 +13,21 @@ | |||
13 | //! Language server executes such typing assists synchronously. That is, they | 13 | //! Language server executes such typing assists synchronously. That is, they |
14 | //! block user's typing and should be pretty fast for this reason! | 14 | //! block user's typing and should be pretty fast for this reason! |
15 | 15 | ||
16 | mod on_enter; | ||
17 | |||
16 | use ra_db::{FilePosition, SourceDatabase}; | 18 | use ra_db::{FilePosition, SourceDatabase}; |
17 | use ra_fmt::leading_indent; | 19 | use ra_fmt::leading_indent; |
18 | use ra_ide_db::RootDatabase; | 20 | use ra_ide_db::RootDatabase; |
19 | use ra_syntax::{ | 21 | use ra_syntax::{ |
20 | algo::find_node_at_offset, | 22 | algo::find_node_at_offset, |
21 | ast::{self, AstToken}, | 23 | ast::{self, AstToken}, |
22 | AstNode, SmolStr, SourceFile, | 24 | AstNode, SourceFile, TextRange, TextUnit, |
23 | SyntaxKind::*, | ||
24 | SyntaxToken, TextRange, TextUnit, TokenAtOffset, | ||
25 | }; | 25 | }; |
26 | use ra_text_edit::TextEdit; | 26 | use ra_text_edit::TextEdit; |
27 | 27 | ||
28 | use crate::{source_change::SingleFileChange, SourceChange, SourceFileEdit}; | 28 | use crate::{source_change::SingleFileChange, SourceChange}; |
29 | |||
30 | pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { | ||
31 | let parse = db.parse(position.file_id); | ||
32 | let file = parse.tree(); | ||
33 | let comment = file | ||
34 | .syntax() | ||
35 | .token_at_offset(position.offset) | ||
36 | .left_biased() | ||
37 | .and_then(ast::Comment::cast)?; | ||
38 | |||
39 | if comment.kind().shape.is_block() { | ||
40 | return None; | ||
41 | } | ||
42 | |||
43 | let prefix = comment.prefix(); | ||
44 | let comment_range = comment.syntax().text_range(); | ||
45 | if position.offset < comment_range.start() + TextUnit::of_str(prefix) { | ||
46 | return None; | ||
47 | } | ||
48 | |||
49 | // Continuing non-doc line comments (like this one :) ) is annoying | ||
50 | if prefix == "//" && comment_range.end() == position.offset { | ||
51 | return None; | ||
52 | } | ||
53 | |||
54 | let indent = node_indent(&file, comment.syntax())?; | ||
55 | let inserted = format!("\n{}{} ", indent, prefix); | ||
56 | let cursor_position = position.offset + TextUnit::of_str(&inserted); | ||
57 | let edit = TextEdit::insert(position.offset, inserted); | ||
58 | 29 | ||
59 | Some( | 30 | pub(crate) use on_enter::on_enter; |
60 | SourceChange::source_file_edit( | ||
61 | "on enter", | ||
62 | SourceFileEdit { edit, file_id: position.file_id }, | ||
63 | ) | ||
64 | .with_cursor(FilePosition { offset: cursor_position, file_id: position.file_id }), | ||
65 | ) | ||
66 | } | ||
67 | |||
68 | fn node_indent(file: &SourceFile, token: &SyntaxToken) -> Option<SmolStr> { | ||
69 | let ws = match file.syntax().token_at_offset(token.text_range().start()) { | ||
70 | TokenAtOffset::Between(l, r) => { | ||
71 | assert!(r == *token); | ||
72 | l | ||
73 | } | ||
74 | TokenAtOffset::Single(n) => { | ||
75 | assert!(n == *token); | ||
76 | return Some("".into()); | ||
77 | } | ||
78 | TokenAtOffset::None => unreachable!(), | ||
79 | }; | ||
80 | if ws.kind() != WHITESPACE { | ||
81 | return None; | ||
82 | } | ||
83 | let text = ws.text(); | ||
84 | let pos = text.rfind('\n').map(|it| it + 1).unwrap_or(0); | ||
85 | Some(text[pos..].into()) | ||
86 | } | ||
87 | 31 | ||
88 | pub(crate) const TRIGGER_CHARS: &str = ".=>"; | 32 | pub(crate) const TRIGGER_CHARS: &str = ".=>"; |
89 | 33 | ||
@@ -196,102 +140,10 @@ fn on_arrow_typed(file: &SourceFile, offset: TextUnit) -> Option<SingleFileChang | |||
196 | 140 | ||
197 | #[cfg(test)] | 141 | #[cfg(test)] |
198 | mod tests { | 142 | mod tests { |
199 | use test_utils::{add_cursor, assert_eq_text, extract_offset}; | 143 | use test_utils::{assert_eq_text, extract_offset}; |
200 | |||
201 | use crate::mock_analysis::single_file; | ||
202 | 144 | ||
203 | use super::*; | 145 | use super::*; |
204 | 146 | ||
205 | #[test] | ||
206 | fn test_on_enter() { | ||
207 | fn apply_on_enter(before: &str) -> Option<String> { | ||
208 | let (offset, before) = extract_offset(before); | ||
209 | let (analysis, file_id) = single_file(&before); | ||
210 | let result = analysis.on_enter(FilePosition { offset, file_id }).unwrap()?; | ||
211 | |||
212 | assert_eq!(result.source_file_edits.len(), 1); | ||
213 | let actual = result.source_file_edits[0].edit.apply(&before); | ||
214 | let actual = add_cursor(&actual, result.cursor_position.unwrap().offset); | ||
215 | Some(actual) | ||
216 | } | ||
217 | |||
218 | fn do_check(before: &str, after: &str) { | ||
219 | let actual = apply_on_enter(before).unwrap(); | ||
220 | assert_eq_text!(after, &actual); | ||
221 | } | ||
222 | |||
223 | fn do_check_noop(text: &str) { | ||
224 | assert!(apply_on_enter(text).is_none()) | ||
225 | } | ||
226 | |||
227 | do_check( | ||
228 | r" | ||
229 | /// Some docs<|> | ||
230 | fn foo() { | ||
231 | } | ||
232 | ", | ||
233 | r" | ||
234 | /// Some docs | ||
235 | /// <|> | ||
236 | fn foo() { | ||
237 | } | ||
238 | ", | ||
239 | ); | ||
240 | do_check( | ||
241 | r" | ||
242 | impl S { | ||
243 | /// Some<|> docs. | ||
244 | fn foo() {} | ||
245 | } | ||
246 | ", | ||
247 | r" | ||
248 | impl S { | ||
249 | /// Some | ||
250 | /// <|> docs. | ||
251 | fn foo() {} | ||
252 | } | ||
253 | ", | ||
254 | ); | ||
255 | do_check( | ||
256 | r" | ||
257 | fn main() { | ||
258 | // Fix<|> me | ||
259 | let x = 1 + 1; | ||
260 | } | ||
261 | ", | ||
262 | r" | ||
263 | fn main() { | ||
264 | // Fix | ||
265 | // <|> me | ||
266 | let x = 1 + 1; | ||
267 | } | ||
268 | ", | ||
269 | ); | ||
270 | do_check( | ||
271 | r" | ||
272 | ///<|> Some docs | ||
273 | fn foo() { | ||
274 | } | ||
275 | ", | ||
276 | r" | ||
277 | /// | ||
278 | /// <|> Some docs | ||
279 | fn foo() { | ||
280 | } | ||
281 | ", | ||
282 | ); | ||
283 | do_check_noop( | ||
284 | r" | ||
285 | fn main() { | ||
286 | // Fix me<|> | ||
287 | let x = 1 + 1; | ||
288 | } | ||
289 | ", | ||
290 | ); | ||
291 | |||
292 | do_check_noop(r"<|>//! docz"); | ||
293 | } | ||
294 | |||
295 | fn do_type_char(char_typed: char, before: &str) -> Option<(String, SingleFileChange)> { | 147 | fn do_type_char(char_typed: char, before: &str) -> Option<(String, SingleFileChange)> { |
296 | let (offset, before) = extract_offset(before); | 148 | let (offset, before) = extract_offset(before); |
297 | let edit = TextEdit::insert(offset, char_typed.to_string()); | 149 | let edit = TextEdit::insert(offset, char_typed.to_string()); |
diff --git a/crates/ra_ide/src/typing/on_enter.rs b/crates/ra_ide/src/typing/on_enter.rs new file mode 100644 index 000000000..6bcf2d72b --- /dev/null +++ b/crates/ra_ide/src/typing/on_enter.rs | |||
@@ -0,0 +1,216 @@ | |||
1 | //! Handles the `Enter` key press. At the momently, this only continues | ||
2 | //! comments, but should handle indent some time in the future as well. | ||
3 | |||
4 | use ra_db::{FilePosition, SourceDatabase}; | ||
5 | use ra_ide_db::RootDatabase; | ||
6 | use ra_syntax::{ | ||
7 | ast::{self, AstToken}, | ||
8 | AstNode, SmolStr, SourceFile, | ||
9 | SyntaxKind::*, | ||
10 | SyntaxToken, TextUnit, TokenAtOffset, | ||
11 | }; | ||
12 | use ra_text_edit::TextEdit; | ||
13 | |||
14 | use crate::{SourceChange, SourceFileEdit}; | ||
15 | |||
16 | pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { | ||
17 | let parse = db.parse(position.file_id); | ||
18 | let file = parse.tree(); | ||
19 | let comment = file | ||
20 | .syntax() | ||
21 | .token_at_offset(position.offset) | ||
22 | .left_biased() | ||
23 | .and_then(ast::Comment::cast)?; | ||
24 | |||
25 | if comment.kind().shape.is_block() { | ||
26 | return None; | ||
27 | } | ||
28 | |||
29 | let prefix = comment.prefix(); | ||
30 | let comment_range = comment.syntax().text_range(); | ||
31 | if position.offset < comment_range.start() + TextUnit::of_str(prefix) { | ||
32 | return None; | ||
33 | } | ||
34 | |||
35 | // Continuing single-line non-doc comments (like this one :) ) is annoying | ||
36 | if prefix == "//" && comment_range.end() == position.offset && !followed_by_comment(&comment) { | ||
37 | return None; | ||
38 | } | ||
39 | |||
40 | let indent = node_indent(&file, comment.syntax())?; | ||
41 | let inserted = format!("\n{}{} ", indent, prefix); | ||
42 | let cursor_position = position.offset + TextUnit::of_str(&inserted); | ||
43 | let edit = TextEdit::insert(position.offset, inserted); | ||
44 | |||
45 | Some( | ||
46 | SourceChange::source_file_edit( | ||
47 | "on enter", | ||
48 | SourceFileEdit { edit, file_id: position.file_id }, | ||
49 | ) | ||
50 | .with_cursor(FilePosition { offset: cursor_position, file_id: position.file_id }), | ||
51 | ) | ||
52 | } | ||
53 | |||
54 | fn followed_by_comment(comment: &ast::Comment) -> bool { | ||
55 | let ws = match comment.syntax().next_token().and_then(ast::Whitespace::cast) { | ||
56 | Some(it) => it, | ||
57 | None => return false, | ||
58 | }; | ||
59 | if ws.spans_multiple_lines() { | ||
60 | return false; | ||
61 | } | ||
62 | ws.syntax().next_token().and_then(ast::Comment::cast).is_some() | ||
63 | } | ||
64 | |||
65 | fn node_indent(file: &SourceFile, token: &SyntaxToken) -> Option<SmolStr> { | ||
66 | let ws = match file.syntax().token_at_offset(token.text_range().start()) { | ||
67 | TokenAtOffset::Between(l, r) => { | ||
68 | assert!(r == *token); | ||
69 | l | ||
70 | } | ||
71 | TokenAtOffset::Single(n) => { | ||
72 | assert!(n == *token); | ||
73 | return Some("".into()); | ||
74 | } | ||
75 | TokenAtOffset::None => unreachable!(), | ||
76 | }; | ||
77 | if ws.kind() != WHITESPACE { | ||
78 | return None; | ||
79 | } | ||
80 | let text = ws.text(); | ||
81 | let pos = text.rfind('\n').map(|it| it + 1).unwrap_or(0); | ||
82 | Some(text[pos..].into()) | ||
83 | } | ||
84 | |||
85 | #[cfg(test)] | ||
86 | mod tests { | ||
87 | use test_utils::{add_cursor, assert_eq_text, extract_offset}; | ||
88 | |||
89 | use crate::mock_analysis::single_file; | ||
90 | |||
91 | use super::*; | ||
92 | |||
93 | fn apply_on_enter(before: &str) -> Option<String> { | ||
94 | let (offset, before) = extract_offset(before); | ||
95 | let (analysis, file_id) = single_file(&before); | ||
96 | let result = analysis.on_enter(FilePosition { offset, file_id }).unwrap()?; | ||
97 | |||
98 | assert_eq!(result.source_file_edits.len(), 1); | ||
99 | let actual = result.source_file_edits[0].edit.apply(&before); | ||
100 | let actual = add_cursor(&actual, result.cursor_position.unwrap().offset); | ||
101 | Some(actual) | ||
102 | } | ||
103 | |||
104 | fn do_check(ra_fixture_before: &str, ra_fixture_after: &str) { | ||
105 | let actual = apply_on_enter(ra_fixture_before).unwrap(); | ||
106 | assert_eq_text!(ra_fixture_after, &actual); | ||
107 | } | ||
108 | |||
109 | fn do_check_noop(ra_fixture_text: &str) { | ||
110 | assert!(apply_on_enter(ra_fixture_text).is_none()) | ||
111 | } | ||
112 | |||
113 | #[test] | ||
114 | fn continues_doc_comment() { | ||
115 | do_check( | ||
116 | r" | ||
117 | /// Some docs<|> | ||
118 | fn foo() { | ||
119 | } | ||
120 | ", | ||
121 | r" | ||
122 | /// Some docs | ||
123 | /// <|> | ||
124 | fn foo() { | ||
125 | } | ||
126 | ", | ||
127 | ); | ||
128 | |||
129 | do_check( | ||
130 | r" | ||
131 | impl S { | ||
132 | /// Some<|> docs. | ||
133 | fn foo() {} | ||
134 | } | ||
135 | ", | ||
136 | r" | ||
137 | impl S { | ||
138 | /// Some | ||
139 | /// <|> docs. | ||
140 | fn foo() {} | ||
141 | } | ||
142 | ", | ||
143 | ); | ||
144 | |||
145 | do_check( | ||
146 | r" | ||
147 | ///<|> Some docs | ||
148 | fn foo() { | ||
149 | } | ||
150 | ", | ||
151 | r" | ||
152 | /// | ||
153 | /// <|> Some docs | ||
154 | fn foo() { | ||
155 | } | ||
156 | ", | ||
157 | ); | ||
158 | } | ||
159 | |||
160 | #[test] | ||
161 | fn does_not_continue_before_doc_comment() { | ||
162 | do_check_noop(r"<|>//! docz"); | ||
163 | } | ||
164 | |||
165 | #[test] | ||
166 | fn continues_code_comment_in_the_middle_of_line() { | ||
167 | do_check( | ||
168 | r" | ||
169 | fn main() { | ||
170 | // Fix<|> me | ||
171 | let x = 1 + 1; | ||
172 | } | ||
173 | ", | ||
174 | r" | ||
175 | fn main() { | ||
176 | // Fix | ||
177 | // <|> me | ||
178 | let x = 1 + 1; | ||
179 | } | ||
180 | ", | ||
181 | ); | ||
182 | } | ||
183 | |||
184 | #[test] | ||
185 | fn continues_code_comment_in_the_middle_several_lines() { | ||
186 | do_check( | ||
187 | r" | ||
188 | fn main() { | ||
189 | // Fix<|> | ||
190 | // me | ||
191 | let x = 1 + 1; | ||
192 | } | ||
193 | ", | ||
194 | r" | ||
195 | fn main() { | ||
196 | // Fix | ||
197 | // <|> | ||
198 | // me | ||
199 | let x = 1 + 1; | ||
200 | } | ||
201 | ", | ||
202 | ); | ||
203 | } | ||
204 | |||
205 | #[test] | ||
206 | fn does_not_continue_end_of_code_comment() { | ||
207 | do_check_noop( | ||
208 | r" | ||
209 | fn main() { | ||
210 | // Fix me<|> | ||
211 | let x = 1 + 1; | ||
212 | } | ||
213 | ", | ||
214 | ); | ||
215 | } | ||
216 | } | ||
diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs index 6bcccc848..fc1b19def 100644 --- a/crates/ra_ide_db/src/lib.rs +++ b/crates/ra_ide_db/src/lib.rs | |||
@@ -55,6 +55,13 @@ impl FileLoader for RootDatabase { | |||
55 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { | 55 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { |
56 | FileLoaderDelegate(self).relevant_crates(file_id) | 56 | FileLoaderDelegate(self).relevant_crates(file_id) |
57 | } | 57 | } |
58 | fn resolve_extern_path( | ||
59 | &self, | ||
60 | extern_id: ra_db::ExternSourceId, | ||
61 | relative_path: &RelativePath, | ||
62 | ) -> Option<FileId> { | ||
63 | FileLoaderDelegate(self).resolve_extern_path(extern_id, relative_path) | ||
64 | } | ||
58 | } | 65 | } |
59 | 66 | ||
60 | impl salsa::Database for RootDatabase { | 67 | impl salsa::Database for RootDatabase { |
diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs index 6f198df04..cf78d3e41 100644 --- a/crates/ra_ide_db/src/search.rs +++ b/crates/ra_ide_db/src/search.rs | |||
@@ -17,7 +17,7 @@ use rustc_hash::FxHashMap; | |||
17 | use test_utils::tested_by; | 17 | use test_utils::tested_by; |
18 | 18 | ||
19 | use crate::{ | 19 | use crate::{ |
20 | defs::{classify_name_ref, Definition}, | 20 | defs::{classify_name_ref, Definition, NameRefClass}, |
21 | RootDatabase, | 21 | RootDatabase, |
22 | }; | 22 | }; |
23 | 23 | ||
@@ -30,6 +30,8 @@ pub struct Reference { | |||
30 | 30 | ||
31 | #[derive(Debug, Clone, PartialEq)] | 31 | #[derive(Debug, Clone, PartialEq)] |
32 | pub enum ReferenceKind { | 32 | pub enum ReferenceKind { |
33 | StructFieldShorthandForField, | ||
34 | StructFieldShorthandForLocal, | ||
33 | StructLiteral, | 35 | StructLiteral, |
34 | Other, | 36 | Other, |
35 | } | 37 | } |
@@ -237,9 +239,8 @@ impl Definition { | |||
237 | // FIXME: reuse sb | 239 | // FIXME: reuse sb |
238 | // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 | 240 | // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 |
239 | 241 | ||
240 | if let Some(d) = classify_name_ref(&sema, &name_ref) { | 242 | match classify_name_ref(&sema, &name_ref) { |
241 | let d = d.definition(); | 243 | Some(NameRefClass::Definition(def)) if &def == self => { |
242 | if &d == self { | ||
243 | let kind = if is_record_lit_name_ref(&name_ref) | 244 | let kind = if is_record_lit_name_ref(&name_ref) |
244 | || is_call_expr_name_ref(&name_ref) | 245 | || is_call_expr_name_ref(&name_ref) |
245 | { | 246 | { |
@@ -252,9 +253,26 @@ impl Definition { | |||
252 | refs.push(Reference { | 253 | refs.push(Reference { |
253 | file_range, | 254 | file_range, |
254 | kind, | 255 | kind, |
255 | access: reference_access(&d, &name_ref), | 256 | access: reference_access(&def, &name_ref), |
256 | }); | 257 | }); |
257 | } | 258 | } |
259 | Some(NameRefClass::FieldShorthand { local, field }) => { | ||
260 | match self { | ||
261 | Definition::StructField(_) if &field == self => refs.push(Reference { | ||
262 | file_range: sema.original_range(name_ref.syntax()), | ||
263 | kind: ReferenceKind::StructFieldShorthandForField, | ||
264 | access: reference_access(&field, &name_ref), | ||
265 | }), | ||
266 | Definition::Local(l) if &local == l => refs.push(Reference { | ||
267 | file_range: sema.original_range(name_ref.syntax()), | ||
268 | kind: ReferenceKind::StructFieldShorthandForLocal, | ||
269 | access: reference_access(&Definition::Local(local), &name_ref), | ||
270 | }), | ||
271 | |||
272 | _ => {} // not a usage | ||
273 | }; | ||
274 | } | ||
275 | _ => {} // not a usage | ||
258 | } | 276 | } |
259 | } | 277 | } |
260 | } | 278 | } |
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 4163a2cf5..0c170ac5e 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -278,7 +278,7 @@ fn current_op(p: &Parser) -> (u8, SyntaxKind) { | |||
278 | } | 278 | } |
279 | 279 | ||
280 | // Parses expression with binding power of at least bp. | 280 | // Parses expression with binding power of at least bp. |
281 | fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option<CompletedMarker>, BlockLike) { | 281 | fn expr_bp(p: &mut Parser, mut r: Restrictions, bp: u8) -> (Option<CompletedMarker>, BlockLike) { |
282 | let mut lhs = match lhs(p, r) { | 282 | let mut lhs = match lhs(p, r) { |
283 | Some((lhs, blocklike)) => { | 283 | Some((lhs, blocklike)) => { |
284 | // test stmt_bin_expr_ambiguity | 284 | // test stmt_bin_expr_ambiguity |
@@ -311,6 +311,12 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option<CompletedMarker>, | |||
311 | let m = lhs.precede(p); | 311 | let m = lhs.precede(p); |
312 | p.bump(op); | 312 | p.bump(op); |
313 | 313 | ||
314 | // test binop_resets_statementness | ||
315 | // fn foo() { | ||
316 | // v = {1}&2; | ||
317 | // } | ||
318 | r = Restrictions { prefer_stmt: false, ..r }; | ||
319 | |||
314 | if is_range { | 320 | if is_range { |
315 | // test postfix_range | 321 | // test postfix_range |
316 | // fn foo() { | 322 | // fn foo() { |
@@ -327,7 +333,7 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> (Option<CompletedMarker>, | |||
327 | } | 333 | } |
328 | } | 334 | } |
329 | 335 | ||
330 | expr_bp(p, r, op_bp + 1); | 336 | expr_bp(p, Restrictions { prefer_stmt: false, ..r }, op_bp + 1); |
331 | lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); | 337 | lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); |
332 | } | 338 | } |
333 | (Some(lhs), BlockLike::NotBlock) | 339 | (Some(lhs), BlockLike::NotBlock) |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 37845ca56..a6274709d 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -14,7 +14,7 @@ use std::{ | |||
14 | 14 | ||
15 | use anyhow::{bail, Context, Result}; | 15 | use anyhow::{bail, Context, Result}; |
16 | use ra_cfg::CfgOptions; | 16 | use ra_cfg::CfgOptions; |
17 | use ra_db::{CrateGraph, CrateName, Edition, Env, FileId}; | 17 | use ra_db::{CrateGraph, CrateName, Edition, Env, ExternSource, ExternSourceId, FileId}; |
18 | use rustc_hash::FxHashMap; | 18 | use rustc_hash::FxHashMap; |
19 | use serde_json::from_reader; | 19 | use serde_json::from_reader; |
20 | 20 | ||
@@ -162,6 +162,7 @@ impl ProjectWorkspace { | |||
162 | pub fn to_crate_graph( | 162 | pub fn to_crate_graph( |
163 | &self, | 163 | &self, |
164 | default_cfg_options: &CfgOptions, | 164 | default_cfg_options: &CfgOptions, |
165 | outdirs: &FxHashMap<String, (ExternSourceId, String)>, | ||
165 | load: &mut dyn FnMut(&Path) -> Option<FileId>, | 166 | load: &mut dyn FnMut(&Path) -> Option<FileId>, |
166 | ) -> CrateGraph { | 167 | ) -> CrateGraph { |
167 | let mut crate_graph = CrateGraph::default(); | 168 | let mut crate_graph = CrateGraph::default(); |
@@ -185,6 +186,8 @@ impl ProjectWorkspace { | |||
185 | } | 186 | } |
186 | opts | 187 | opts |
187 | }; | 188 | }; |
189 | |||
190 | // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env | ||
188 | crates.insert( | 191 | crates.insert( |
189 | crate_id, | 192 | crate_id, |
190 | crate_graph.add_crate_root( | 193 | crate_graph.add_crate_root( |
@@ -194,6 +197,7 @@ impl ProjectWorkspace { | |||
194 | None, | 197 | None, |
195 | cfg_options, | 198 | cfg_options, |
196 | Env::default(), | 199 | Env::default(), |
200 | Default::default(), | ||
197 | ), | 201 | ), |
198 | ); | 202 | ); |
199 | } | 203 | } |
@@ -231,12 +235,20 @@ impl ProjectWorkspace { | |||
231 | opts | 235 | opts |
232 | }; | 236 | }; |
233 | 237 | ||
238 | let mut env = Env::default(); | ||
239 | let mut extern_source = ExternSource::default(); | ||
240 | if let Some((id, path)) = outdirs.get(krate.name(&sysroot)) { | ||
241 | env.set("OUT_DIR", path.clone()); | ||
242 | extern_source.set_extern_path(&path, *id); | ||
243 | } | ||
244 | |||
234 | let crate_id = crate_graph.add_crate_root( | 245 | let crate_id = crate_graph.add_crate_root( |
235 | file_id, | 246 | file_id, |
236 | Edition::Edition2018, | 247 | Edition::Edition2018, |
237 | Some(krate.name(&sysroot).to_string()), | 248 | Some(krate.name(&sysroot).to_string()), |
238 | cfg_options, | 249 | cfg_options, |
239 | Env::default(), | 250 | env, |
251 | extern_source, | ||
240 | ); | 252 | ); |
241 | sysroot_crates.insert(krate, crate_id); | 253 | sysroot_crates.insert(krate, crate_id); |
242 | } | 254 | } |
@@ -275,12 +287,19 @@ impl ProjectWorkspace { | |||
275 | opts.insert_features(pkg.features(&cargo).iter().map(Into::into)); | 287 | opts.insert_features(pkg.features(&cargo).iter().map(Into::into)); |
276 | opts | 288 | opts |
277 | }; | 289 | }; |
290 | let mut env = Env::default(); | ||
291 | let mut extern_source = ExternSource::default(); | ||
292 | if let Some((id, path)) = outdirs.get(pkg.name(&cargo)) { | ||
293 | env.set("OUT_DIR", path.clone()); | ||
294 | extern_source.set_extern_path(&path, *id); | ||
295 | } | ||
278 | let crate_id = crate_graph.add_crate_root( | 296 | let crate_id = crate_graph.add_crate_root( |
279 | file_id, | 297 | file_id, |
280 | edition, | 298 | edition, |
281 | Some(pkg.name(&cargo).to_string()), | 299 | Some(pkg.name(&cargo).to_string()), |
282 | cfg_options, | 300 | cfg_options, |
283 | Env::default(), | 301 | env, |
302 | extern_source, | ||
284 | ); | 303 | ); |
285 | if tgt.kind(&cargo) == TargetKind::Lib { | 304 | if tgt.kind(&cargo) == TargetKind::Lib { |
286 | lib_tgt = Some(crate_id); | 305 | lib_tgt = Some(crate_id); |
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 4a70c712f..26fafb469 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -30,7 +30,7 @@ pub use self::{ | |||
30 | /// conversion itself has zero runtime cost: ast and syntax nodes have exactly | 30 | /// conversion itself has zero runtime cost: ast and syntax nodes have exactly |
31 | /// the same representation: a pointer to the tree root and a pointer to the | 31 | /// the same representation: a pointer to the tree root and a pointer to the |
32 | /// node itself. | 32 | /// node itself. |
33 | pub trait AstNode { | 33 | pub trait AstNode: std::fmt::Display { |
34 | fn can_cast(kind: SyntaxKind) -> bool | 34 | fn can_cast(kind: SyntaxKind) -> bool |
35 | where | 35 | where |
36 | Self: Sized; | 36 | Self: Sized; |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 150893e39..002f453cd 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -9,6 +9,11 @@ use crate::{ | |||
9 | pub struct SourceFile { | 9 | pub struct SourceFile { |
10 | pub(crate) syntax: SyntaxNode, | 10 | pub(crate) syntax: SyntaxNode, |
11 | } | 11 | } |
12 | impl std::fmt::Display for SourceFile { | ||
13 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
14 | std::fmt::Display::fmt(self.syntax(), f) | ||
15 | } | ||
16 | } | ||
12 | impl AstNode for SourceFile { | 17 | impl AstNode for SourceFile { |
13 | fn can_cast(kind: SyntaxKind) -> bool { | 18 | fn can_cast(kind: SyntaxKind) -> bool { |
14 | match kind { | 19 | match kind { |
@@ -38,6 +43,11 @@ impl SourceFile { | |||
38 | pub struct FnDef { | 43 | pub struct FnDef { |
39 | pub(crate) syntax: SyntaxNode, | 44 | pub(crate) syntax: SyntaxNode, |
40 | } | 45 | } |
46 | impl std::fmt::Display for FnDef { | ||
47 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
48 | std::fmt::Display::fmt(self.syntax(), f) | ||
49 | } | ||
50 | } | ||
41 | impl AstNode for FnDef { | 51 | impl AstNode for FnDef { |
42 | fn can_cast(kind: SyntaxKind) -> bool { | 52 | fn can_cast(kind: SyntaxKind) -> bool { |
43 | match kind { | 53 | match kind { |
@@ -76,6 +86,11 @@ impl FnDef { | |||
76 | pub struct RetType { | 86 | pub struct RetType { |
77 | pub(crate) syntax: SyntaxNode, | 87 | pub(crate) syntax: SyntaxNode, |
78 | } | 88 | } |
89 | impl std::fmt::Display for RetType { | ||
90 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
91 | std::fmt::Display::fmt(self.syntax(), f) | ||
92 | } | ||
93 | } | ||
79 | impl AstNode for RetType { | 94 | impl AstNode for RetType { |
80 | fn can_cast(kind: SyntaxKind) -> bool { | 95 | fn can_cast(kind: SyntaxKind) -> bool { |
81 | match kind { | 96 | match kind { |
@@ -103,6 +118,11 @@ impl RetType { | |||
103 | pub struct StructDef { | 118 | pub struct StructDef { |
104 | pub(crate) syntax: SyntaxNode, | 119 | pub(crate) syntax: SyntaxNode, |
105 | } | 120 | } |
121 | impl std::fmt::Display for StructDef { | ||
122 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
123 | std::fmt::Display::fmt(self.syntax(), f) | ||
124 | } | ||
125 | } | ||
106 | impl AstNode for StructDef { | 126 | impl AstNode for StructDef { |
107 | fn can_cast(kind: SyntaxKind) -> bool { | 127 | fn can_cast(kind: SyntaxKind) -> bool { |
108 | match kind { | 128 | match kind { |
@@ -131,6 +151,11 @@ impl StructDef {} | |||
131 | pub struct UnionDef { | 151 | pub struct UnionDef { |
132 | pub(crate) syntax: SyntaxNode, | 152 | pub(crate) syntax: SyntaxNode, |
133 | } | 153 | } |
154 | impl std::fmt::Display for UnionDef { | ||
155 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
156 | std::fmt::Display::fmt(self.syntax(), f) | ||
157 | } | ||
158 | } | ||
134 | impl AstNode for UnionDef { | 159 | impl AstNode for UnionDef { |
135 | fn can_cast(kind: SyntaxKind) -> bool { | 160 | fn can_cast(kind: SyntaxKind) -> bool { |
136 | match kind { | 161 | match kind { |
@@ -163,6 +188,11 @@ impl UnionDef { | |||
163 | pub struct RecordFieldDefList { | 188 | pub struct RecordFieldDefList { |
164 | pub(crate) syntax: SyntaxNode, | 189 | pub(crate) syntax: SyntaxNode, |
165 | } | 190 | } |
191 | impl std::fmt::Display for RecordFieldDefList { | ||
192 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
193 | std::fmt::Display::fmt(self.syntax(), f) | ||
194 | } | ||
195 | } | ||
166 | impl AstNode for RecordFieldDefList { | 196 | impl AstNode for RecordFieldDefList { |
167 | fn can_cast(kind: SyntaxKind) -> bool { | 197 | fn can_cast(kind: SyntaxKind) -> bool { |
168 | match kind { | 198 | match kind { |
@@ -190,6 +220,11 @@ impl RecordFieldDefList { | |||
190 | pub struct RecordFieldDef { | 220 | pub struct RecordFieldDef { |
191 | pub(crate) syntax: SyntaxNode, | 221 | pub(crate) syntax: SyntaxNode, |
192 | } | 222 | } |
223 | impl std::fmt::Display for RecordFieldDef { | ||
224 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
225 | std::fmt::Display::fmt(self.syntax(), f) | ||
226 | } | ||
227 | } | ||
193 | impl AstNode for RecordFieldDef { | 228 | impl AstNode for RecordFieldDef { |
194 | fn can_cast(kind: SyntaxKind) -> bool { | 229 | fn can_cast(kind: SyntaxKind) -> bool { |
195 | match kind { | 230 | match kind { |
@@ -218,6 +253,11 @@ impl RecordFieldDef {} | |||
218 | pub struct TupleFieldDefList { | 253 | pub struct TupleFieldDefList { |
219 | pub(crate) syntax: SyntaxNode, | 254 | pub(crate) syntax: SyntaxNode, |
220 | } | 255 | } |
256 | impl std::fmt::Display for TupleFieldDefList { | ||
257 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
258 | std::fmt::Display::fmt(self.syntax(), f) | ||
259 | } | ||
260 | } | ||
221 | impl AstNode for TupleFieldDefList { | 261 | impl AstNode for TupleFieldDefList { |
222 | fn can_cast(kind: SyntaxKind) -> bool { | 262 | fn can_cast(kind: SyntaxKind) -> bool { |
223 | match kind { | 263 | match kind { |
@@ -245,6 +285,11 @@ impl TupleFieldDefList { | |||
245 | pub struct TupleFieldDef { | 285 | pub struct TupleFieldDef { |
246 | pub(crate) syntax: SyntaxNode, | 286 | pub(crate) syntax: SyntaxNode, |
247 | } | 287 | } |
288 | impl std::fmt::Display for TupleFieldDef { | ||
289 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
290 | std::fmt::Display::fmt(self.syntax(), f) | ||
291 | } | ||
292 | } | ||
248 | impl AstNode for TupleFieldDef { | 293 | impl AstNode for TupleFieldDef { |
249 | fn can_cast(kind: SyntaxKind) -> bool { | 294 | fn can_cast(kind: SyntaxKind) -> bool { |
250 | match kind { | 295 | match kind { |
@@ -274,6 +319,11 @@ impl TupleFieldDef { | |||
274 | pub struct EnumDef { | 319 | pub struct EnumDef { |
275 | pub(crate) syntax: SyntaxNode, | 320 | pub(crate) syntax: SyntaxNode, |
276 | } | 321 | } |
322 | impl std::fmt::Display for EnumDef { | ||
323 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
324 | std::fmt::Display::fmt(self.syntax(), f) | ||
325 | } | ||
326 | } | ||
277 | impl AstNode for EnumDef { | 327 | impl AstNode for EnumDef { |
278 | fn can_cast(kind: SyntaxKind) -> bool { | 328 | fn can_cast(kind: SyntaxKind) -> bool { |
279 | match kind { | 329 | match kind { |
@@ -306,6 +356,11 @@ impl EnumDef { | |||
306 | pub struct EnumVariantList { | 356 | pub struct EnumVariantList { |
307 | pub(crate) syntax: SyntaxNode, | 357 | pub(crate) syntax: SyntaxNode, |
308 | } | 358 | } |
359 | impl std::fmt::Display for EnumVariantList { | ||
360 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
361 | std::fmt::Display::fmt(self.syntax(), f) | ||
362 | } | ||
363 | } | ||
309 | impl AstNode for EnumVariantList { | 364 | impl AstNode for EnumVariantList { |
310 | fn can_cast(kind: SyntaxKind) -> bool { | 365 | fn can_cast(kind: SyntaxKind) -> bool { |
311 | match kind { | 366 | match kind { |
@@ -333,6 +388,11 @@ impl EnumVariantList { | |||
333 | pub struct EnumVariant { | 388 | pub struct EnumVariant { |
334 | pub(crate) syntax: SyntaxNode, | 389 | pub(crate) syntax: SyntaxNode, |
335 | } | 390 | } |
391 | impl std::fmt::Display for EnumVariant { | ||
392 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
393 | std::fmt::Display::fmt(self.syntax(), f) | ||
394 | } | ||
395 | } | ||
336 | impl AstNode for EnumVariant { | 396 | impl AstNode for EnumVariant { |
337 | fn can_cast(kind: SyntaxKind) -> bool { | 397 | fn can_cast(kind: SyntaxKind) -> bool { |
338 | match kind { | 398 | match kind { |
@@ -363,6 +423,11 @@ impl EnumVariant { | |||
363 | pub struct TraitDef { | 423 | pub struct TraitDef { |
364 | pub(crate) syntax: SyntaxNode, | 424 | pub(crate) syntax: SyntaxNode, |
365 | } | 425 | } |
426 | impl std::fmt::Display for TraitDef { | ||
427 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
428 | std::fmt::Display::fmt(self.syntax(), f) | ||
429 | } | ||
430 | } | ||
366 | impl AstNode for TraitDef { | 431 | impl AstNode for TraitDef { |
367 | fn can_cast(kind: SyntaxKind) -> bool { | 432 | fn can_cast(kind: SyntaxKind) -> bool { |
368 | match kind { | 433 | match kind { |
@@ -396,6 +461,11 @@ impl TraitDef { | |||
396 | pub struct Module { | 461 | pub struct Module { |
397 | pub(crate) syntax: SyntaxNode, | 462 | pub(crate) syntax: SyntaxNode, |
398 | } | 463 | } |
464 | impl std::fmt::Display for Module { | ||
465 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
466 | std::fmt::Display::fmt(self.syntax(), f) | ||
467 | } | ||
468 | } | ||
399 | impl AstNode for Module { | 469 | impl AstNode for Module { |
400 | fn can_cast(kind: SyntaxKind) -> bool { | 470 | fn can_cast(kind: SyntaxKind) -> bool { |
401 | match kind { | 471 | match kind { |
@@ -427,6 +497,11 @@ impl Module { | |||
427 | pub struct ItemList { | 497 | pub struct ItemList { |
428 | pub(crate) syntax: SyntaxNode, | 498 | pub(crate) syntax: SyntaxNode, |
429 | } | 499 | } |
500 | impl std::fmt::Display for ItemList { | ||
501 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
502 | std::fmt::Display::fmt(self.syntax(), f) | ||
503 | } | ||
504 | } | ||
430 | impl AstNode for ItemList { | 505 | impl AstNode for ItemList { |
431 | fn can_cast(kind: SyntaxKind) -> bool { | 506 | fn can_cast(kind: SyntaxKind) -> bool { |
432 | match kind { | 507 | match kind { |
@@ -456,6 +531,11 @@ impl ItemList { | |||
456 | pub struct ConstDef { | 531 | pub struct ConstDef { |
457 | pub(crate) syntax: SyntaxNode, | 532 | pub(crate) syntax: SyntaxNode, |
458 | } | 533 | } |
534 | impl std::fmt::Display for ConstDef { | ||
535 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
536 | std::fmt::Display::fmt(self.syntax(), f) | ||
537 | } | ||
538 | } | ||
459 | impl AstNode for ConstDef { | 539 | impl AstNode for ConstDef { |
460 | fn can_cast(kind: SyntaxKind) -> bool { | 540 | fn can_cast(kind: SyntaxKind) -> bool { |
461 | match kind { | 541 | match kind { |
@@ -489,6 +569,11 @@ impl ConstDef { | |||
489 | pub struct StaticDef { | 569 | pub struct StaticDef { |
490 | pub(crate) syntax: SyntaxNode, | 570 | pub(crate) syntax: SyntaxNode, |
491 | } | 571 | } |
572 | impl std::fmt::Display for StaticDef { | ||
573 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
574 | std::fmt::Display::fmt(self.syntax(), f) | ||
575 | } | ||
576 | } | ||
492 | impl AstNode for StaticDef { | 577 | impl AstNode for StaticDef { |
493 | fn can_cast(kind: SyntaxKind) -> bool { | 578 | fn can_cast(kind: SyntaxKind) -> bool { |
494 | match kind { | 579 | match kind { |
@@ -522,6 +607,11 @@ impl StaticDef { | |||
522 | pub struct TypeAliasDef { | 607 | pub struct TypeAliasDef { |
523 | pub(crate) syntax: SyntaxNode, | 608 | pub(crate) syntax: SyntaxNode, |
524 | } | 609 | } |
610 | impl std::fmt::Display for TypeAliasDef { | ||
611 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
612 | std::fmt::Display::fmt(self.syntax(), f) | ||
613 | } | ||
614 | } | ||
525 | impl AstNode for TypeAliasDef { | 615 | impl AstNode for TypeAliasDef { |
526 | fn can_cast(kind: SyntaxKind) -> bool { | 616 | fn can_cast(kind: SyntaxKind) -> bool { |
527 | match kind { | 617 | match kind { |
@@ -555,6 +645,11 @@ impl TypeAliasDef { | |||
555 | pub struct ImplDef { | 645 | pub struct ImplDef { |
556 | pub(crate) syntax: SyntaxNode, | 646 | pub(crate) syntax: SyntaxNode, |
557 | } | 647 | } |
648 | impl std::fmt::Display for ImplDef { | ||
649 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
650 | std::fmt::Display::fmt(self.syntax(), f) | ||
651 | } | ||
652 | } | ||
558 | impl AstNode for ImplDef { | 653 | impl AstNode for ImplDef { |
559 | fn can_cast(kind: SyntaxKind) -> bool { | 654 | fn can_cast(kind: SyntaxKind) -> bool { |
560 | match kind { | 655 | match kind { |
@@ -584,6 +679,11 @@ impl ImplDef { | |||
584 | pub struct ParenType { | 679 | pub struct ParenType { |
585 | pub(crate) syntax: SyntaxNode, | 680 | pub(crate) syntax: SyntaxNode, |
586 | } | 681 | } |
682 | impl std::fmt::Display for ParenType { | ||
683 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
684 | std::fmt::Display::fmt(self.syntax(), f) | ||
685 | } | ||
686 | } | ||
587 | impl AstNode for ParenType { | 687 | impl AstNode for ParenType { |
588 | fn can_cast(kind: SyntaxKind) -> bool { | 688 | fn can_cast(kind: SyntaxKind) -> bool { |
589 | match kind { | 689 | match kind { |
@@ -611,6 +711,11 @@ impl ParenType { | |||
611 | pub struct TupleType { | 711 | pub struct TupleType { |
612 | pub(crate) syntax: SyntaxNode, | 712 | pub(crate) syntax: SyntaxNode, |
613 | } | 713 | } |
714 | impl std::fmt::Display for TupleType { | ||
715 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
716 | std::fmt::Display::fmt(self.syntax(), f) | ||
717 | } | ||
718 | } | ||
614 | impl AstNode for TupleType { | 719 | impl AstNode for TupleType { |
615 | fn can_cast(kind: SyntaxKind) -> bool { | 720 | fn can_cast(kind: SyntaxKind) -> bool { |
616 | match kind { | 721 | match kind { |
@@ -638,6 +743,11 @@ impl TupleType { | |||
638 | pub struct NeverType { | 743 | pub struct NeverType { |
639 | pub(crate) syntax: SyntaxNode, | 744 | pub(crate) syntax: SyntaxNode, |
640 | } | 745 | } |
746 | impl std::fmt::Display for NeverType { | ||
747 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
748 | std::fmt::Display::fmt(self.syntax(), f) | ||
749 | } | ||
750 | } | ||
641 | impl AstNode for NeverType { | 751 | impl AstNode for NeverType { |
642 | fn can_cast(kind: SyntaxKind) -> bool { | 752 | fn can_cast(kind: SyntaxKind) -> bool { |
643 | match kind { | 753 | match kind { |
@@ -661,6 +771,11 @@ impl NeverType {} | |||
661 | pub struct PathType { | 771 | pub struct PathType { |
662 | pub(crate) syntax: SyntaxNode, | 772 | pub(crate) syntax: SyntaxNode, |
663 | } | 773 | } |
774 | impl std::fmt::Display for PathType { | ||
775 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
776 | std::fmt::Display::fmt(self.syntax(), f) | ||
777 | } | ||
778 | } | ||
664 | impl AstNode for PathType { | 779 | impl AstNode for PathType { |
665 | fn can_cast(kind: SyntaxKind) -> bool { | 780 | fn can_cast(kind: SyntaxKind) -> bool { |
666 | match kind { | 781 | match kind { |
@@ -688,6 +803,11 @@ impl PathType { | |||
688 | pub struct PointerType { | 803 | pub struct PointerType { |
689 | pub(crate) syntax: SyntaxNode, | 804 | pub(crate) syntax: SyntaxNode, |
690 | } | 805 | } |
806 | impl std::fmt::Display for PointerType { | ||
807 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
808 | std::fmt::Display::fmt(self.syntax(), f) | ||
809 | } | ||
810 | } | ||
691 | impl AstNode for PointerType { | 811 | impl AstNode for PointerType { |
692 | fn can_cast(kind: SyntaxKind) -> bool { | 812 | fn can_cast(kind: SyntaxKind) -> bool { |
693 | match kind { | 813 | match kind { |
@@ -715,6 +835,11 @@ impl PointerType { | |||
715 | pub struct ArrayType { | 835 | pub struct ArrayType { |
716 | pub(crate) syntax: SyntaxNode, | 836 | pub(crate) syntax: SyntaxNode, |
717 | } | 837 | } |
838 | impl std::fmt::Display for ArrayType { | ||
839 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
840 | std::fmt::Display::fmt(self.syntax(), f) | ||
841 | } | ||
842 | } | ||
718 | impl AstNode for ArrayType { | 843 | impl AstNode for ArrayType { |
719 | fn can_cast(kind: SyntaxKind) -> bool { | 844 | fn can_cast(kind: SyntaxKind) -> bool { |
720 | match kind { | 845 | match kind { |
@@ -745,6 +870,11 @@ impl ArrayType { | |||
745 | pub struct SliceType { | 870 | pub struct SliceType { |
746 | pub(crate) syntax: SyntaxNode, | 871 | pub(crate) syntax: SyntaxNode, |
747 | } | 872 | } |
873 | impl std::fmt::Display for SliceType { | ||
874 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
875 | std::fmt::Display::fmt(self.syntax(), f) | ||
876 | } | ||
877 | } | ||
748 | impl AstNode for SliceType { | 878 | impl AstNode for SliceType { |
749 | fn can_cast(kind: SyntaxKind) -> bool { | 879 | fn can_cast(kind: SyntaxKind) -> bool { |
750 | match kind { | 880 | match kind { |
@@ -772,6 +902,11 @@ impl SliceType { | |||
772 | pub struct ReferenceType { | 902 | pub struct ReferenceType { |
773 | pub(crate) syntax: SyntaxNode, | 903 | pub(crate) syntax: SyntaxNode, |
774 | } | 904 | } |
905 | impl std::fmt::Display for ReferenceType { | ||
906 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
907 | std::fmt::Display::fmt(self.syntax(), f) | ||
908 | } | ||
909 | } | ||
775 | impl AstNode for ReferenceType { | 910 | impl AstNode for ReferenceType { |
776 | fn can_cast(kind: SyntaxKind) -> bool { | 911 | fn can_cast(kind: SyntaxKind) -> bool { |
777 | match kind { | 912 | match kind { |
@@ -799,6 +934,11 @@ impl ReferenceType { | |||
799 | pub struct PlaceholderType { | 934 | pub struct PlaceholderType { |
800 | pub(crate) syntax: SyntaxNode, | 935 | pub(crate) syntax: SyntaxNode, |
801 | } | 936 | } |
937 | impl std::fmt::Display for PlaceholderType { | ||
938 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
939 | std::fmt::Display::fmt(self.syntax(), f) | ||
940 | } | ||
941 | } | ||
802 | impl AstNode for PlaceholderType { | 942 | impl AstNode for PlaceholderType { |
803 | fn can_cast(kind: SyntaxKind) -> bool { | 943 | fn can_cast(kind: SyntaxKind) -> bool { |
804 | match kind { | 944 | match kind { |
@@ -822,6 +962,11 @@ impl PlaceholderType {} | |||
822 | pub struct FnPointerType { | 962 | pub struct FnPointerType { |
823 | pub(crate) syntax: SyntaxNode, | 963 | pub(crate) syntax: SyntaxNode, |
824 | } | 964 | } |
965 | impl std::fmt::Display for FnPointerType { | ||
966 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
967 | std::fmt::Display::fmt(self.syntax(), f) | ||
968 | } | ||
969 | } | ||
825 | impl AstNode for FnPointerType { | 970 | impl AstNode for FnPointerType { |
826 | fn can_cast(kind: SyntaxKind) -> bool { | 971 | fn can_cast(kind: SyntaxKind) -> bool { |
827 | match kind { | 972 | match kind { |
@@ -852,6 +997,11 @@ impl FnPointerType { | |||
852 | pub struct ForType { | 997 | pub struct ForType { |
853 | pub(crate) syntax: SyntaxNode, | 998 | pub(crate) syntax: SyntaxNode, |
854 | } | 999 | } |
1000 | impl std::fmt::Display for ForType { | ||
1001 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1002 | std::fmt::Display::fmt(self.syntax(), f) | ||
1003 | } | ||
1004 | } | ||
855 | impl AstNode for ForType { | 1005 | impl AstNode for ForType { |
856 | fn can_cast(kind: SyntaxKind) -> bool { | 1006 | fn can_cast(kind: SyntaxKind) -> bool { |
857 | match kind { | 1007 | match kind { |
@@ -879,6 +1029,11 @@ impl ForType { | |||
879 | pub struct ImplTraitType { | 1029 | pub struct ImplTraitType { |
880 | pub(crate) syntax: SyntaxNode, | 1030 | pub(crate) syntax: SyntaxNode, |
881 | } | 1031 | } |
1032 | impl std::fmt::Display for ImplTraitType { | ||
1033 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1034 | std::fmt::Display::fmt(self.syntax(), f) | ||
1035 | } | ||
1036 | } | ||
882 | impl AstNode for ImplTraitType { | 1037 | impl AstNode for ImplTraitType { |
883 | fn can_cast(kind: SyntaxKind) -> bool { | 1038 | fn can_cast(kind: SyntaxKind) -> bool { |
884 | match kind { | 1039 | match kind { |
@@ -903,6 +1058,11 @@ impl ImplTraitType {} | |||
903 | pub struct DynTraitType { | 1058 | pub struct DynTraitType { |
904 | pub(crate) syntax: SyntaxNode, | 1059 | pub(crate) syntax: SyntaxNode, |
905 | } | 1060 | } |
1061 | impl std::fmt::Display for DynTraitType { | ||
1062 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1063 | std::fmt::Display::fmt(self.syntax(), f) | ||
1064 | } | ||
1065 | } | ||
906 | impl AstNode for DynTraitType { | 1066 | impl AstNode for DynTraitType { |
907 | fn can_cast(kind: SyntaxKind) -> bool { | 1067 | fn can_cast(kind: SyntaxKind) -> bool { |
908 | match kind { | 1068 | match kind { |
@@ -927,6 +1087,11 @@ impl DynTraitType {} | |||
927 | pub struct TupleExpr { | 1087 | pub struct TupleExpr { |
928 | pub(crate) syntax: SyntaxNode, | 1088 | pub(crate) syntax: SyntaxNode, |
929 | } | 1089 | } |
1090 | impl std::fmt::Display for TupleExpr { | ||
1091 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1092 | std::fmt::Display::fmt(self.syntax(), f) | ||
1093 | } | ||
1094 | } | ||
930 | impl AstNode for TupleExpr { | 1095 | impl AstNode for TupleExpr { |
931 | fn can_cast(kind: SyntaxKind) -> bool { | 1096 | fn can_cast(kind: SyntaxKind) -> bool { |
932 | match kind { | 1097 | match kind { |
@@ -954,6 +1119,11 @@ impl TupleExpr { | |||
954 | pub struct ArrayExpr { | 1119 | pub struct ArrayExpr { |
955 | pub(crate) syntax: SyntaxNode, | 1120 | pub(crate) syntax: SyntaxNode, |
956 | } | 1121 | } |
1122 | impl std::fmt::Display for ArrayExpr { | ||
1123 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1124 | std::fmt::Display::fmt(self.syntax(), f) | ||
1125 | } | ||
1126 | } | ||
957 | impl AstNode for ArrayExpr { | 1127 | impl AstNode for ArrayExpr { |
958 | fn can_cast(kind: SyntaxKind) -> bool { | 1128 | fn can_cast(kind: SyntaxKind) -> bool { |
959 | match kind { | 1129 | match kind { |
@@ -981,6 +1151,11 @@ impl ArrayExpr { | |||
981 | pub struct ParenExpr { | 1151 | pub struct ParenExpr { |
982 | pub(crate) syntax: SyntaxNode, | 1152 | pub(crate) syntax: SyntaxNode, |
983 | } | 1153 | } |
1154 | impl std::fmt::Display for ParenExpr { | ||
1155 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1156 | std::fmt::Display::fmt(self.syntax(), f) | ||
1157 | } | ||
1158 | } | ||
984 | impl AstNode for ParenExpr { | 1159 | impl AstNode for ParenExpr { |
985 | fn can_cast(kind: SyntaxKind) -> bool { | 1160 | fn can_cast(kind: SyntaxKind) -> bool { |
986 | match kind { | 1161 | match kind { |
@@ -1008,6 +1183,11 @@ impl ParenExpr { | |||
1008 | pub struct PathExpr { | 1183 | pub struct PathExpr { |
1009 | pub(crate) syntax: SyntaxNode, | 1184 | pub(crate) syntax: SyntaxNode, |
1010 | } | 1185 | } |
1186 | impl std::fmt::Display for PathExpr { | ||
1187 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1188 | std::fmt::Display::fmt(self.syntax(), f) | ||
1189 | } | ||
1190 | } | ||
1011 | impl AstNode for PathExpr { | 1191 | impl AstNode for PathExpr { |
1012 | fn can_cast(kind: SyntaxKind) -> bool { | 1192 | fn can_cast(kind: SyntaxKind) -> bool { |
1013 | match kind { | 1193 | match kind { |
@@ -1035,6 +1215,11 @@ impl PathExpr { | |||
1035 | pub struct LambdaExpr { | 1215 | pub struct LambdaExpr { |
1036 | pub(crate) syntax: SyntaxNode, | 1216 | pub(crate) syntax: SyntaxNode, |
1037 | } | 1217 | } |
1218 | impl std::fmt::Display for LambdaExpr { | ||
1219 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1220 | std::fmt::Display::fmt(self.syntax(), f) | ||
1221 | } | ||
1222 | } | ||
1038 | impl AstNode for LambdaExpr { | 1223 | impl AstNode for LambdaExpr { |
1039 | fn can_cast(kind: SyntaxKind) -> bool { | 1224 | fn can_cast(kind: SyntaxKind) -> bool { |
1040 | match kind { | 1225 | match kind { |
@@ -1068,6 +1253,11 @@ impl LambdaExpr { | |||
1068 | pub struct IfExpr { | 1253 | pub struct IfExpr { |
1069 | pub(crate) syntax: SyntaxNode, | 1254 | pub(crate) syntax: SyntaxNode, |
1070 | } | 1255 | } |
1256 | impl std::fmt::Display for IfExpr { | ||
1257 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1258 | std::fmt::Display::fmt(self.syntax(), f) | ||
1259 | } | ||
1260 | } | ||
1071 | impl AstNode for IfExpr { | 1261 | impl AstNode for IfExpr { |
1072 | fn can_cast(kind: SyntaxKind) -> bool { | 1262 | fn can_cast(kind: SyntaxKind) -> bool { |
1073 | match kind { | 1263 | match kind { |
@@ -1095,6 +1285,11 @@ impl IfExpr { | |||
1095 | pub struct LoopExpr { | 1285 | pub struct LoopExpr { |
1096 | pub(crate) syntax: SyntaxNode, | 1286 | pub(crate) syntax: SyntaxNode, |
1097 | } | 1287 | } |
1288 | impl std::fmt::Display for LoopExpr { | ||
1289 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1290 | std::fmt::Display::fmt(self.syntax(), f) | ||
1291 | } | ||
1292 | } | ||
1098 | impl AstNode for LoopExpr { | 1293 | impl AstNode for LoopExpr { |
1099 | fn can_cast(kind: SyntaxKind) -> bool { | 1294 | fn can_cast(kind: SyntaxKind) -> bool { |
1100 | match kind { | 1295 | match kind { |
@@ -1119,6 +1314,11 @@ impl LoopExpr {} | |||
1119 | pub struct TryBlockExpr { | 1314 | pub struct TryBlockExpr { |
1120 | pub(crate) syntax: SyntaxNode, | 1315 | pub(crate) syntax: SyntaxNode, |
1121 | } | 1316 | } |
1317 | impl std::fmt::Display for TryBlockExpr { | ||
1318 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1319 | std::fmt::Display::fmt(self.syntax(), f) | ||
1320 | } | ||
1321 | } | ||
1122 | impl AstNode for TryBlockExpr { | 1322 | impl AstNode for TryBlockExpr { |
1123 | fn can_cast(kind: SyntaxKind) -> bool { | 1323 | fn can_cast(kind: SyntaxKind) -> bool { |
1124 | match kind { | 1324 | match kind { |
@@ -1146,6 +1346,11 @@ impl TryBlockExpr { | |||
1146 | pub struct ForExpr { | 1346 | pub struct ForExpr { |
1147 | pub(crate) syntax: SyntaxNode, | 1347 | pub(crate) syntax: SyntaxNode, |
1148 | } | 1348 | } |
1349 | impl std::fmt::Display for ForExpr { | ||
1350 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1351 | std::fmt::Display::fmt(self.syntax(), f) | ||
1352 | } | ||
1353 | } | ||
1149 | impl AstNode for ForExpr { | 1354 | impl AstNode for ForExpr { |
1150 | fn can_cast(kind: SyntaxKind) -> bool { | 1355 | fn can_cast(kind: SyntaxKind) -> bool { |
1151 | match kind { | 1356 | match kind { |
@@ -1177,6 +1382,11 @@ impl ForExpr { | |||
1177 | pub struct WhileExpr { | 1382 | pub struct WhileExpr { |
1178 | pub(crate) syntax: SyntaxNode, | 1383 | pub(crate) syntax: SyntaxNode, |
1179 | } | 1384 | } |
1385 | impl std::fmt::Display for WhileExpr { | ||
1386 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1387 | std::fmt::Display::fmt(self.syntax(), f) | ||
1388 | } | ||
1389 | } | ||
1180 | impl AstNode for WhileExpr { | 1390 | impl AstNode for WhileExpr { |
1181 | fn can_cast(kind: SyntaxKind) -> bool { | 1391 | fn can_cast(kind: SyntaxKind) -> bool { |
1182 | match kind { | 1392 | match kind { |
@@ -1205,6 +1415,11 @@ impl WhileExpr { | |||
1205 | pub struct ContinueExpr { | 1415 | pub struct ContinueExpr { |
1206 | pub(crate) syntax: SyntaxNode, | 1416 | pub(crate) syntax: SyntaxNode, |
1207 | } | 1417 | } |
1418 | impl std::fmt::Display for ContinueExpr { | ||
1419 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1420 | std::fmt::Display::fmt(self.syntax(), f) | ||
1421 | } | ||
1422 | } | ||
1208 | impl AstNode for ContinueExpr { | 1423 | impl AstNode for ContinueExpr { |
1209 | fn can_cast(kind: SyntaxKind) -> bool { | 1424 | fn can_cast(kind: SyntaxKind) -> bool { |
1210 | match kind { | 1425 | match kind { |
@@ -1228,6 +1443,11 @@ impl ContinueExpr {} | |||
1228 | pub struct BreakExpr { | 1443 | pub struct BreakExpr { |
1229 | pub(crate) syntax: SyntaxNode, | 1444 | pub(crate) syntax: SyntaxNode, |
1230 | } | 1445 | } |
1446 | impl std::fmt::Display for BreakExpr { | ||
1447 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1448 | std::fmt::Display::fmt(self.syntax(), f) | ||
1449 | } | ||
1450 | } | ||
1231 | impl AstNode for BreakExpr { | 1451 | impl AstNode for BreakExpr { |
1232 | fn can_cast(kind: SyntaxKind) -> bool { | 1452 | fn can_cast(kind: SyntaxKind) -> bool { |
1233 | match kind { | 1453 | match kind { |
@@ -1255,6 +1475,11 @@ impl BreakExpr { | |||
1255 | pub struct Label { | 1475 | pub struct Label { |
1256 | pub(crate) syntax: SyntaxNode, | 1476 | pub(crate) syntax: SyntaxNode, |
1257 | } | 1477 | } |
1478 | impl std::fmt::Display for Label { | ||
1479 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1480 | std::fmt::Display::fmt(self.syntax(), f) | ||
1481 | } | ||
1482 | } | ||
1258 | impl AstNode for Label { | 1483 | impl AstNode for Label { |
1259 | fn can_cast(kind: SyntaxKind) -> bool { | 1484 | fn can_cast(kind: SyntaxKind) -> bool { |
1260 | match kind { | 1485 | match kind { |
@@ -1278,6 +1503,11 @@ impl Label {} | |||
1278 | pub struct BlockExpr { | 1503 | pub struct BlockExpr { |
1279 | pub(crate) syntax: SyntaxNode, | 1504 | pub(crate) syntax: SyntaxNode, |
1280 | } | 1505 | } |
1506 | impl std::fmt::Display for BlockExpr { | ||
1507 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1508 | std::fmt::Display::fmt(self.syntax(), f) | ||
1509 | } | ||
1510 | } | ||
1281 | impl AstNode for BlockExpr { | 1511 | impl AstNode for BlockExpr { |
1282 | fn can_cast(kind: SyntaxKind) -> bool { | 1512 | fn can_cast(kind: SyntaxKind) -> bool { |
1283 | match kind { | 1513 | match kind { |
@@ -1305,6 +1535,11 @@ impl BlockExpr { | |||
1305 | pub struct ReturnExpr { | 1535 | pub struct ReturnExpr { |
1306 | pub(crate) syntax: SyntaxNode, | 1536 | pub(crate) syntax: SyntaxNode, |
1307 | } | 1537 | } |
1538 | impl std::fmt::Display for ReturnExpr { | ||
1539 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1540 | std::fmt::Display::fmt(self.syntax(), f) | ||
1541 | } | ||
1542 | } | ||
1308 | impl AstNode for ReturnExpr { | 1543 | impl AstNode for ReturnExpr { |
1309 | fn can_cast(kind: SyntaxKind) -> bool { | 1544 | fn can_cast(kind: SyntaxKind) -> bool { |
1310 | match kind { | 1545 | match kind { |
@@ -1332,6 +1567,11 @@ impl ReturnExpr { | |||
1332 | pub struct CallExpr { | 1567 | pub struct CallExpr { |
1333 | pub(crate) syntax: SyntaxNode, | 1568 | pub(crate) syntax: SyntaxNode, |
1334 | } | 1569 | } |
1570 | impl std::fmt::Display for CallExpr { | ||
1571 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1572 | std::fmt::Display::fmt(self.syntax(), f) | ||
1573 | } | ||
1574 | } | ||
1335 | impl AstNode for CallExpr { | 1575 | impl AstNode for CallExpr { |
1336 | fn can_cast(kind: SyntaxKind) -> bool { | 1576 | fn can_cast(kind: SyntaxKind) -> bool { |
1337 | match kind { | 1577 | match kind { |
@@ -1360,6 +1600,11 @@ impl CallExpr { | |||
1360 | pub struct MethodCallExpr { | 1600 | pub struct MethodCallExpr { |
1361 | pub(crate) syntax: SyntaxNode, | 1601 | pub(crate) syntax: SyntaxNode, |
1362 | } | 1602 | } |
1603 | impl std::fmt::Display for MethodCallExpr { | ||
1604 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1605 | std::fmt::Display::fmt(self.syntax(), f) | ||
1606 | } | ||
1607 | } | ||
1363 | impl AstNode for MethodCallExpr { | 1608 | impl AstNode for MethodCallExpr { |
1364 | fn can_cast(kind: SyntaxKind) -> bool { | 1609 | fn can_cast(kind: SyntaxKind) -> bool { |
1365 | match kind { | 1610 | match kind { |
@@ -1394,6 +1639,11 @@ impl MethodCallExpr { | |||
1394 | pub struct IndexExpr { | 1639 | pub struct IndexExpr { |
1395 | pub(crate) syntax: SyntaxNode, | 1640 | pub(crate) syntax: SyntaxNode, |
1396 | } | 1641 | } |
1642 | impl std::fmt::Display for IndexExpr { | ||
1643 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1644 | std::fmt::Display::fmt(self.syntax(), f) | ||
1645 | } | ||
1646 | } | ||
1397 | impl AstNode for IndexExpr { | 1647 | impl AstNode for IndexExpr { |
1398 | fn can_cast(kind: SyntaxKind) -> bool { | 1648 | fn can_cast(kind: SyntaxKind) -> bool { |
1399 | match kind { | 1649 | match kind { |
@@ -1417,6 +1667,11 @@ impl IndexExpr {} | |||
1417 | pub struct FieldExpr { | 1667 | pub struct FieldExpr { |
1418 | pub(crate) syntax: SyntaxNode, | 1668 | pub(crate) syntax: SyntaxNode, |
1419 | } | 1669 | } |
1670 | impl std::fmt::Display for FieldExpr { | ||
1671 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1672 | std::fmt::Display::fmt(self.syntax(), f) | ||
1673 | } | ||
1674 | } | ||
1420 | impl AstNode for FieldExpr { | 1675 | impl AstNode for FieldExpr { |
1421 | fn can_cast(kind: SyntaxKind) -> bool { | 1676 | fn can_cast(kind: SyntaxKind) -> bool { |
1422 | match kind { | 1677 | match kind { |
@@ -1447,6 +1702,11 @@ impl FieldExpr { | |||
1447 | pub struct AwaitExpr { | 1702 | pub struct AwaitExpr { |
1448 | pub(crate) syntax: SyntaxNode, | 1703 | pub(crate) syntax: SyntaxNode, |
1449 | } | 1704 | } |
1705 | impl std::fmt::Display for AwaitExpr { | ||
1706 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1707 | std::fmt::Display::fmt(self.syntax(), f) | ||
1708 | } | ||
1709 | } | ||
1450 | impl AstNode for AwaitExpr { | 1710 | impl AstNode for AwaitExpr { |
1451 | fn can_cast(kind: SyntaxKind) -> bool { | 1711 | fn can_cast(kind: SyntaxKind) -> bool { |
1452 | match kind { | 1712 | match kind { |
@@ -1474,6 +1734,11 @@ impl AwaitExpr { | |||
1474 | pub struct TryExpr { | 1734 | pub struct TryExpr { |
1475 | pub(crate) syntax: SyntaxNode, | 1735 | pub(crate) syntax: SyntaxNode, |
1476 | } | 1736 | } |
1737 | impl std::fmt::Display for TryExpr { | ||
1738 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1739 | std::fmt::Display::fmt(self.syntax(), f) | ||
1740 | } | ||
1741 | } | ||
1477 | impl AstNode for TryExpr { | 1742 | impl AstNode for TryExpr { |
1478 | fn can_cast(kind: SyntaxKind) -> bool { | 1743 | fn can_cast(kind: SyntaxKind) -> bool { |
1479 | match kind { | 1744 | match kind { |
@@ -1501,6 +1766,11 @@ impl TryExpr { | |||
1501 | pub struct CastExpr { | 1766 | pub struct CastExpr { |
1502 | pub(crate) syntax: SyntaxNode, | 1767 | pub(crate) syntax: SyntaxNode, |
1503 | } | 1768 | } |
1769 | impl std::fmt::Display for CastExpr { | ||
1770 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1771 | std::fmt::Display::fmt(self.syntax(), f) | ||
1772 | } | ||
1773 | } | ||
1504 | impl AstNode for CastExpr { | 1774 | impl AstNode for CastExpr { |
1505 | fn can_cast(kind: SyntaxKind) -> bool { | 1775 | fn can_cast(kind: SyntaxKind) -> bool { |
1506 | match kind { | 1776 | match kind { |
@@ -1531,6 +1801,11 @@ impl CastExpr { | |||
1531 | pub struct RefExpr { | 1801 | pub struct RefExpr { |
1532 | pub(crate) syntax: SyntaxNode, | 1802 | pub(crate) syntax: SyntaxNode, |
1533 | } | 1803 | } |
1804 | impl std::fmt::Display for RefExpr { | ||
1805 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1806 | std::fmt::Display::fmt(self.syntax(), f) | ||
1807 | } | ||
1808 | } | ||
1534 | impl AstNode for RefExpr { | 1809 | impl AstNode for RefExpr { |
1535 | fn can_cast(kind: SyntaxKind) -> bool { | 1810 | fn can_cast(kind: SyntaxKind) -> bool { |
1536 | match kind { | 1811 | match kind { |
@@ -1558,6 +1833,11 @@ impl RefExpr { | |||
1558 | pub struct PrefixExpr { | 1833 | pub struct PrefixExpr { |
1559 | pub(crate) syntax: SyntaxNode, | 1834 | pub(crate) syntax: SyntaxNode, |
1560 | } | 1835 | } |
1836 | impl std::fmt::Display for PrefixExpr { | ||
1837 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1838 | std::fmt::Display::fmt(self.syntax(), f) | ||
1839 | } | ||
1840 | } | ||
1561 | impl AstNode for PrefixExpr { | 1841 | impl AstNode for PrefixExpr { |
1562 | fn can_cast(kind: SyntaxKind) -> bool { | 1842 | fn can_cast(kind: SyntaxKind) -> bool { |
1563 | match kind { | 1843 | match kind { |
@@ -1585,6 +1865,11 @@ impl PrefixExpr { | |||
1585 | pub struct BoxExpr { | 1865 | pub struct BoxExpr { |
1586 | pub(crate) syntax: SyntaxNode, | 1866 | pub(crate) syntax: SyntaxNode, |
1587 | } | 1867 | } |
1868 | impl std::fmt::Display for BoxExpr { | ||
1869 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1870 | std::fmt::Display::fmt(self.syntax(), f) | ||
1871 | } | ||
1872 | } | ||
1588 | impl AstNode for BoxExpr { | 1873 | impl AstNode for BoxExpr { |
1589 | fn can_cast(kind: SyntaxKind) -> bool { | 1874 | fn can_cast(kind: SyntaxKind) -> bool { |
1590 | match kind { | 1875 | match kind { |
@@ -1612,6 +1897,11 @@ impl BoxExpr { | |||
1612 | pub struct RangeExpr { | 1897 | pub struct RangeExpr { |
1613 | pub(crate) syntax: SyntaxNode, | 1898 | pub(crate) syntax: SyntaxNode, |
1614 | } | 1899 | } |
1900 | impl std::fmt::Display for RangeExpr { | ||
1901 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1902 | std::fmt::Display::fmt(self.syntax(), f) | ||
1903 | } | ||
1904 | } | ||
1615 | impl AstNode for RangeExpr { | 1905 | impl AstNode for RangeExpr { |
1616 | fn can_cast(kind: SyntaxKind) -> bool { | 1906 | fn can_cast(kind: SyntaxKind) -> bool { |
1617 | match kind { | 1907 | match kind { |
@@ -1635,6 +1925,11 @@ impl RangeExpr {} | |||
1635 | pub struct BinExpr { | 1925 | pub struct BinExpr { |
1636 | pub(crate) syntax: SyntaxNode, | 1926 | pub(crate) syntax: SyntaxNode, |
1637 | } | 1927 | } |
1928 | impl std::fmt::Display for BinExpr { | ||
1929 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1930 | std::fmt::Display::fmt(self.syntax(), f) | ||
1931 | } | ||
1932 | } | ||
1638 | impl AstNode for BinExpr { | 1933 | impl AstNode for BinExpr { |
1639 | fn can_cast(kind: SyntaxKind) -> bool { | 1934 | fn can_cast(kind: SyntaxKind) -> bool { |
1640 | match kind { | 1935 | match kind { |
@@ -1658,6 +1953,11 @@ impl BinExpr {} | |||
1658 | pub struct Literal { | 1953 | pub struct Literal { |
1659 | pub(crate) syntax: SyntaxNode, | 1954 | pub(crate) syntax: SyntaxNode, |
1660 | } | 1955 | } |
1956 | impl std::fmt::Display for Literal { | ||
1957 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1958 | std::fmt::Display::fmt(self.syntax(), f) | ||
1959 | } | ||
1960 | } | ||
1661 | impl AstNode for Literal { | 1961 | impl AstNode for Literal { |
1662 | fn can_cast(kind: SyntaxKind) -> bool { | 1962 | fn can_cast(kind: SyntaxKind) -> bool { |
1663 | match kind { | 1963 | match kind { |
@@ -1681,6 +1981,11 @@ impl Literal {} | |||
1681 | pub struct MatchExpr { | 1981 | pub struct MatchExpr { |
1682 | pub(crate) syntax: SyntaxNode, | 1982 | pub(crate) syntax: SyntaxNode, |
1683 | } | 1983 | } |
1984 | impl std::fmt::Display for MatchExpr { | ||
1985 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1986 | std::fmt::Display::fmt(self.syntax(), f) | ||
1987 | } | ||
1988 | } | ||
1684 | impl AstNode for MatchExpr { | 1989 | impl AstNode for MatchExpr { |
1685 | fn can_cast(kind: SyntaxKind) -> bool { | 1990 | fn can_cast(kind: SyntaxKind) -> bool { |
1686 | match kind { | 1991 | match kind { |
@@ -1711,6 +2016,11 @@ impl MatchExpr { | |||
1711 | pub struct MatchArmList { | 2016 | pub struct MatchArmList { |
1712 | pub(crate) syntax: SyntaxNode, | 2017 | pub(crate) syntax: SyntaxNode, |
1713 | } | 2018 | } |
2019 | impl std::fmt::Display for MatchArmList { | ||
2020 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2021 | std::fmt::Display::fmt(self.syntax(), f) | ||
2022 | } | ||
2023 | } | ||
1714 | impl AstNode for MatchArmList { | 2024 | impl AstNode for MatchArmList { |
1715 | fn can_cast(kind: SyntaxKind) -> bool { | 2025 | fn can_cast(kind: SyntaxKind) -> bool { |
1716 | match kind { | 2026 | match kind { |
@@ -1739,6 +2049,11 @@ impl MatchArmList { | |||
1739 | pub struct MatchArm { | 2049 | pub struct MatchArm { |
1740 | pub(crate) syntax: SyntaxNode, | 2050 | pub(crate) syntax: SyntaxNode, |
1741 | } | 2051 | } |
2052 | impl std::fmt::Display for MatchArm { | ||
2053 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2054 | std::fmt::Display::fmt(self.syntax(), f) | ||
2055 | } | ||
2056 | } | ||
1742 | impl AstNode for MatchArm { | 2057 | impl AstNode for MatchArm { |
1743 | fn can_cast(kind: SyntaxKind) -> bool { | 2058 | fn can_cast(kind: SyntaxKind) -> bool { |
1744 | match kind { | 2059 | match kind { |
@@ -1773,6 +2088,11 @@ impl MatchArm { | |||
1773 | pub struct MatchGuard { | 2088 | pub struct MatchGuard { |
1774 | pub(crate) syntax: SyntaxNode, | 2089 | pub(crate) syntax: SyntaxNode, |
1775 | } | 2090 | } |
2091 | impl std::fmt::Display for MatchGuard { | ||
2092 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2093 | std::fmt::Display::fmt(self.syntax(), f) | ||
2094 | } | ||
2095 | } | ||
1776 | impl AstNode for MatchGuard { | 2096 | impl AstNode for MatchGuard { |
1777 | fn can_cast(kind: SyntaxKind) -> bool { | 2097 | fn can_cast(kind: SyntaxKind) -> bool { |
1778 | match kind { | 2098 | match kind { |
@@ -1800,6 +2120,11 @@ impl MatchGuard { | |||
1800 | pub struct RecordLit { | 2120 | pub struct RecordLit { |
1801 | pub(crate) syntax: SyntaxNode, | 2121 | pub(crate) syntax: SyntaxNode, |
1802 | } | 2122 | } |
2123 | impl std::fmt::Display for RecordLit { | ||
2124 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2125 | std::fmt::Display::fmt(self.syntax(), f) | ||
2126 | } | ||
2127 | } | ||
1803 | impl AstNode for RecordLit { | 2128 | impl AstNode for RecordLit { |
1804 | fn can_cast(kind: SyntaxKind) -> bool { | 2129 | fn can_cast(kind: SyntaxKind) -> bool { |
1805 | match kind { | 2130 | match kind { |
@@ -1830,6 +2155,11 @@ impl RecordLit { | |||
1830 | pub struct RecordFieldList { | 2155 | pub struct RecordFieldList { |
1831 | pub(crate) syntax: SyntaxNode, | 2156 | pub(crate) syntax: SyntaxNode, |
1832 | } | 2157 | } |
2158 | impl std::fmt::Display for RecordFieldList { | ||
2159 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2160 | std::fmt::Display::fmt(self.syntax(), f) | ||
2161 | } | ||
2162 | } | ||
1833 | impl AstNode for RecordFieldList { | 2163 | impl AstNode for RecordFieldList { |
1834 | fn can_cast(kind: SyntaxKind) -> bool { | 2164 | fn can_cast(kind: SyntaxKind) -> bool { |
1835 | match kind { | 2165 | match kind { |
@@ -1860,6 +2190,11 @@ impl RecordFieldList { | |||
1860 | pub struct RecordField { | 2190 | pub struct RecordField { |
1861 | pub(crate) syntax: SyntaxNode, | 2191 | pub(crate) syntax: SyntaxNode, |
1862 | } | 2192 | } |
2193 | impl std::fmt::Display for RecordField { | ||
2194 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2195 | std::fmt::Display::fmt(self.syntax(), f) | ||
2196 | } | ||
2197 | } | ||
1863 | impl AstNode for RecordField { | 2198 | impl AstNode for RecordField { |
1864 | fn can_cast(kind: SyntaxKind) -> bool { | 2199 | fn can_cast(kind: SyntaxKind) -> bool { |
1865 | match kind { | 2200 | match kind { |
@@ -1890,6 +2225,11 @@ impl RecordField { | |||
1890 | pub struct OrPat { | 2225 | pub struct OrPat { |
1891 | pub(crate) syntax: SyntaxNode, | 2226 | pub(crate) syntax: SyntaxNode, |
1892 | } | 2227 | } |
2228 | impl std::fmt::Display for OrPat { | ||
2229 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2230 | std::fmt::Display::fmt(self.syntax(), f) | ||
2231 | } | ||
2232 | } | ||
1893 | impl AstNode for OrPat { | 2233 | impl AstNode for OrPat { |
1894 | fn can_cast(kind: SyntaxKind) -> bool { | 2234 | fn can_cast(kind: SyntaxKind) -> bool { |
1895 | match kind { | 2235 | match kind { |
@@ -1917,6 +2257,11 @@ impl OrPat { | |||
1917 | pub struct ParenPat { | 2257 | pub struct ParenPat { |
1918 | pub(crate) syntax: SyntaxNode, | 2258 | pub(crate) syntax: SyntaxNode, |
1919 | } | 2259 | } |
2260 | impl std::fmt::Display for ParenPat { | ||
2261 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2262 | std::fmt::Display::fmt(self.syntax(), f) | ||
2263 | } | ||
2264 | } | ||
1920 | impl AstNode for ParenPat { | 2265 | impl AstNode for ParenPat { |
1921 | fn can_cast(kind: SyntaxKind) -> bool { | 2266 | fn can_cast(kind: SyntaxKind) -> bool { |
1922 | match kind { | 2267 | match kind { |
@@ -1944,6 +2289,11 @@ impl ParenPat { | |||
1944 | pub struct RefPat { | 2289 | pub struct RefPat { |
1945 | pub(crate) syntax: SyntaxNode, | 2290 | pub(crate) syntax: SyntaxNode, |
1946 | } | 2291 | } |
2292 | impl std::fmt::Display for RefPat { | ||
2293 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2294 | std::fmt::Display::fmt(self.syntax(), f) | ||
2295 | } | ||
2296 | } | ||
1947 | impl AstNode for RefPat { | 2297 | impl AstNode for RefPat { |
1948 | fn can_cast(kind: SyntaxKind) -> bool { | 2298 | fn can_cast(kind: SyntaxKind) -> bool { |
1949 | match kind { | 2299 | match kind { |
@@ -1971,6 +2321,11 @@ impl RefPat { | |||
1971 | pub struct BoxPat { | 2321 | pub struct BoxPat { |
1972 | pub(crate) syntax: SyntaxNode, | 2322 | pub(crate) syntax: SyntaxNode, |
1973 | } | 2323 | } |
2324 | impl std::fmt::Display for BoxPat { | ||
2325 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2326 | std::fmt::Display::fmt(self.syntax(), f) | ||
2327 | } | ||
2328 | } | ||
1974 | impl AstNode for BoxPat { | 2329 | impl AstNode for BoxPat { |
1975 | fn can_cast(kind: SyntaxKind) -> bool { | 2330 | fn can_cast(kind: SyntaxKind) -> bool { |
1976 | match kind { | 2331 | match kind { |
@@ -1998,6 +2353,11 @@ impl BoxPat { | |||
1998 | pub struct BindPat { | 2353 | pub struct BindPat { |
1999 | pub(crate) syntax: SyntaxNode, | 2354 | pub(crate) syntax: SyntaxNode, |
2000 | } | 2355 | } |
2356 | impl std::fmt::Display for BindPat { | ||
2357 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2358 | std::fmt::Display::fmt(self.syntax(), f) | ||
2359 | } | ||
2360 | } | ||
2001 | impl AstNode for BindPat { | 2361 | impl AstNode for BindPat { |
2002 | fn can_cast(kind: SyntaxKind) -> bool { | 2362 | fn can_cast(kind: SyntaxKind) -> bool { |
2003 | match kind { | 2363 | match kind { |
@@ -2026,6 +2386,11 @@ impl BindPat { | |||
2026 | pub struct PlaceholderPat { | 2386 | pub struct PlaceholderPat { |
2027 | pub(crate) syntax: SyntaxNode, | 2387 | pub(crate) syntax: SyntaxNode, |
2028 | } | 2388 | } |
2389 | impl std::fmt::Display for PlaceholderPat { | ||
2390 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2391 | std::fmt::Display::fmt(self.syntax(), f) | ||
2392 | } | ||
2393 | } | ||
2029 | impl AstNode for PlaceholderPat { | 2394 | impl AstNode for PlaceholderPat { |
2030 | fn can_cast(kind: SyntaxKind) -> bool { | 2395 | fn can_cast(kind: SyntaxKind) -> bool { |
2031 | match kind { | 2396 | match kind { |
@@ -2049,6 +2414,11 @@ impl PlaceholderPat {} | |||
2049 | pub struct DotDotPat { | 2414 | pub struct DotDotPat { |
2050 | pub(crate) syntax: SyntaxNode, | 2415 | pub(crate) syntax: SyntaxNode, |
2051 | } | 2416 | } |
2417 | impl std::fmt::Display for DotDotPat { | ||
2418 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2419 | std::fmt::Display::fmt(self.syntax(), f) | ||
2420 | } | ||
2421 | } | ||
2052 | impl AstNode for DotDotPat { | 2422 | impl AstNode for DotDotPat { |
2053 | fn can_cast(kind: SyntaxKind) -> bool { | 2423 | fn can_cast(kind: SyntaxKind) -> bool { |
2054 | match kind { | 2424 | match kind { |
@@ -2072,6 +2442,11 @@ impl DotDotPat {} | |||
2072 | pub struct PathPat { | 2442 | pub struct PathPat { |
2073 | pub(crate) syntax: SyntaxNode, | 2443 | pub(crate) syntax: SyntaxNode, |
2074 | } | 2444 | } |
2445 | impl std::fmt::Display for PathPat { | ||
2446 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2447 | std::fmt::Display::fmt(self.syntax(), f) | ||
2448 | } | ||
2449 | } | ||
2075 | impl AstNode for PathPat { | 2450 | impl AstNode for PathPat { |
2076 | fn can_cast(kind: SyntaxKind) -> bool { | 2451 | fn can_cast(kind: SyntaxKind) -> bool { |
2077 | match kind { | 2452 | match kind { |
@@ -2099,6 +2474,11 @@ impl PathPat { | |||
2099 | pub struct SlicePat { | 2474 | pub struct SlicePat { |
2100 | pub(crate) syntax: SyntaxNode, | 2475 | pub(crate) syntax: SyntaxNode, |
2101 | } | 2476 | } |
2477 | impl std::fmt::Display for SlicePat { | ||
2478 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2479 | std::fmt::Display::fmt(self.syntax(), f) | ||
2480 | } | ||
2481 | } | ||
2102 | impl AstNode for SlicePat { | 2482 | impl AstNode for SlicePat { |
2103 | fn can_cast(kind: SyntaxKind) -> bool { | 2483 | fn can_cast(kind: SyntaxKind) -> bool { |
2104 | match kind { | 2484 | match kind { |
@@ -2126,6 +2506,11 @@ impl SlicePat { | |||
2126 | pub struct RangePat { | 2506 | pub struct RangePat { |
2127 | pub(crate) syntax: SyntaxNode, | 2507 | pub(crate) syntax: SyntaxNode, |
2128 | } | 2508 | } |
2509 | impl std::fmt::Display for RangePat { | ||
2510 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2511 | std::fmt::Display::fmt(self.syntax(), f) | ||
2512 | } | ||
2513 | } | ||
2129 | impl AstNode for RangePat { | 2514 | impl AstNode for RangePat { |
2130 | fn can_cast(kind: SyntaxKind) -> bool { | 2515 | fn can_cast(kind: SyntaxKind) -> bool { |
2131 | match kind { | 2516 | match kind { |
@@ -2149,6 +2534,11 @@ impl RangePat {} | |||
2149 | pub struct LiteralPat { | 2534 | pub struct LiteralPat { |
2150 | pub(crate) syntax: SyntaxNode, | 2535 | pub(crate) syntax: SyntaxNode, |
2151 | } | 2536 | } |
2537 | impl std::fmt::Display for LiteralPat { | ||
2538 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2539 | std::fmt::Display::fmt(self.syntax(), f) | ||
2540 | } | ||
2541 | } | ||
2152 | impl AstNode for LiteralPat { | 2542 | impl AstNode for LiteralPat { |
2153 | fn can_cast(kind: SyntaxKind) -> bool { | 2543 | fn can_cast(kind: SyntaxKind) -> bool { |
2154 | match kind { | 2544 | match kind { |
@@ -2176,6 +2566,11 @@ impl LiteralPat { | |||
2176 | pub struct RecordPat { | 2566 | pub struct RecordPat { |
2177 | pub(crate) syntax: SyntaxNode, | 2567 | pub(crate) syntax: SyntaxNode, |
2178 | } | 2568 | } |
2569 | impl std::fmt::Display for RecordPat { | ||
2570 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2571 | std::fmt::Display::fmt(self.syntax(), f) | ||
2572 | } | ||
2573 | } | ||
2179 | impl AstNode for RecordPat { | 2574 | impl AstNode for RecordPat { |
2180 | fn can_cast(kind: SyntaxKind) -> bool { | 2575 | fn can_cast(kind: SyntaxKind) -> bool { |
2181 | match kind { | 2576 | match kind { |
@@ -2206,6 +2601,11 @@ impl RecordPat { | |||
2206 | pub struct RecordFieldPatList { | 2601 | pub struct RecordFieldPatList { |
2207 | pub(crate) syntax: SyntaxNode, | 2602 | pub(crate) syntax: SyntaxNode, |
2208 | } | 2603 | } |
2604 | impl std::fmt::Display for RecordFieldPatList { | ||
2605 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2606 | std::fmt::Display::fmt(self.syntax(), f) | ||
2607 | } | ||
2608 | } | ||
2209 | impl AstNode for RecordFieldPatList { | 2609 | impl AstNode for RecordFieldPatList { |
2210 | fn can_cast(kind: SyntaxKind) -> bool { | 2610 | fn can_cast(kind: SyntaxKind) -> bool { |
2211 | match kind { | 2611 | match kind { |
@@ -2236,6 +2636,11 @@ impl RecordFieldPatList { | |||
2236 | pub struct RecordFieldPat { | 2636 | pub struct RecordFieldPat { |
2237 | pub(crate) syntax: SyntaxNode, | 2637 | pub(crate) syntax: SyntaxNode, |
2238 | } | 2638 | } |
2639 | impl std::fmt::Display for RecordFieldPat { | ||
2640 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2641 | std::fmt::Display::fmt(self.syntax(), f) | ||
2642 | } | ||
2643 | } | ||
2239 | impl AstNode for RecordFieldPat { | 2644 | impl AstNode for RecordFieldPat { |
2240 | fn can_cast(kind: SyntaxKind) -> bool { | 2645 | fn can_cast(kind: SyntaxKind) -> bool { |
2241 | match kind { | 2646 | match kind { |
@@ -2264,6 +2669,11 @@ impl RecordFieldPat { | |||
2264 | pub struct TupleStructPat { | 2669 | pub struct TupleStructPat { |
2265 | pub(crate) syntax: SyntaxNode, | 2670 | pub(crate) syntax: SyntaxNode, |
2266 | } | 2671 | } |
2672 | impl std::fmt::Display for TupleStructPat { | ||
2673 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2674 | std::fmt::Display::fmt(self.syntax(), f) | ||
2675 | } | ||
2676 | } | ||
2267 | impl AstNode for TupleStructPat { | 2677 | impl AstNode for TupleStructPat { |
2268 | fn can_cast(kind: SyntaxKind) -> bool { | 2678 | fn can_cast(kind: SyntaxKind) -> bool { |
2269 | match kind { | 2679 | match kind { |
@@ -2294,6 +2704,11 @@ impl TupleStructPat { | |||
2294 | pub struct TuplePat { | 2704 | pub struct TuplePat { |
2295 | pub(crate) syntax: SyntaxNode, | 2705 | pub(crate) syntax: SyntaxNode, |
2296 | } | 2706 | } |
2707 | impl std::fmt::Display for TuplePat { | ||
2708 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2709 | std::fmt::Display::fmt(self.syntax(), f) | ||
2710 | } | ||
2711 | } | ||
2297 | impl AstNode for TuplePat { | 2712 | impl AstNode for TuplePat { |
2298 | fn can_cast(kind: SyntaxKind) -> bool { | 2713 | fn can_cast(kind: SyntaxKind) -> bool { |
2299 | match kind { | 2714 | match kind { |
@@ -2321,6 +2736,11 @@ impl TuplePat { | |||
2321 | pub struct Visibility { | 2736 | pub struct Visibility { |
2322 | pub(crate) syntax: SyntaxNode, | 2737 | pub(crate) syntax: SyntaxNode, |
2323 | } | 2738 | } |
2739 | impl std::fmt::Display for Visibility { | ||
2740 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2741 | std::fmt::Display::fmt(self.syntax(), f) | ||
2742 | } | ||
2743 | } | ||
2324 | impl AstNode for Visibility { | 2744 | impl AstNode for Visibility { |
2325 | fn can_cast(kind: SyntaxKind) -> bool { | 2745 | fn can_cast(kind: SyntaxKind) -> bool { |
2326 | match kind { | 2746 | match kind { |
@@ -2344,6 +2764,11 @@ impl Visibility {} | |||
2344 | pub struct Name { | 2764 | pub struct Name { |
2345 | pub(crate) syntax: SyntaxNode, | 2765 | pub(crate) syntax: SyntaxNode, |
2346 | } | 2766 | } |
2767 | impl std::fmt::Display for Name { | ||
2768 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2769 | std::fmt::Display::fmt(self.syntax(), f) | ||
2770 | } | ||
2771 | } | ||
2347 | impl AstNode for Name { | 2772 | impl AstNode for Name { |
2348 | fn can_cast(kind: SyntaxKind) -> bool { | 2773 | fn can_cast(kind: SyntaxKind) -> bool { |
2349 | match kind { | 2774 | match kind { |
@@ -2367,6 +2792,11 @@ impl Name {} | |||
2367 | pub struct NameRef { | 2792 | pub struct NameRef { |
2368 | pub(crate) syntax: SyntaxNode, | 2793 | pub(crate) syntax: SyntaxNode, |
2369 | } | 2794 | } |
2795 | impl std::fmt::Display for NameRef { | ||
2796 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2797 | std::fmt::Display::fmt(self.syntax(), f) | ||
2798 | } | ||
2799 | } | ||
2370 | impl AstNode for NameRef { | 2800 | impl AstNode for NameRef { |
2371 | fn can_cast(kind: SyntaxKind) -> bool { | 2801 | fn can_cast(kind: SyntaxKind) -> bool { |
2372 | match kind { | 2802 | match kind { |
@@ -2390,6 +2820,11 @@ impl NameRef {} | |||
2390 | pub struct MacroCall { | 2820 | pub struct MacroCall { |
2391 | pub(crate) syntax: SyntaxNode, | 2821 | pub(crate) syntax: SyntaxNode, |
2392 | } | 2822 | } |
2823 | impl std::fmt::Display for MacroCall { | ||
2824 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2825 | std::fmt::Display::fmt(self.syntax(), f) | ||
2826 | } | ||
2827 | } | ||
2393 | impl AstNode for MacroCall { | 2828 | impl AstNode for MacroCall { |
2394 | fn can_cast(kind: SyntaxKind) -> bool { | 2829 | fn can_cast(kind: SyntaxKind) -> bool { |
2395 | match kind { | 2830 | match kind { |
@@ -2423,6 +2858,11 @@ impl MacroCall { | |||
2423 | pub struct Attr { | 2858 | pub struct Attr { |
2424 | pub(crate) syntax: SyntaxNode, | 2859 | pub(crate) syntax: SyntaxNode, |
2425 | } | 2860 | } |
2861 | impl std::fmt::Display for Attr { | ||
2862 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2863 | std::fmt::Display::fmt(self.syntax(), f) | ||
2864 | } | ||
2865 | } | ||
2426 | impl AstNode for Attr { | 2866 | impl AstNode for Attr { |
2427 | fn can_cast(kind: SyntaxKind) -> bool { | 2867 | fn can_cast(kind: SyntaxKind) -> bool { |
2428 | match kind { | 2868 | match kind { |
@@ -2453,6 +2893,11 @@ impl Attr { | |||
2453 | pub struct TokenTree { | 2893 | pub struct TokenTree { |
2454 | pub(crate) syntax: SyntaxNode, | 2894 | pub(crate) syntax: SyntaxNode, |
2455 | } | 2895 | } |
2896 | impl std::fmt::Display for TokenTree { | ||
2897 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2898 | std::fmt::Display::fmt(self.syntax(), f) | ||
2899 | } | ||
2900 | } | ||
2456 | impl AstNode for TokenTree { | 2901 | impl AstNode for TokenTree { |
2457 | fn can_cast(kind: SyntaxKind) -> bool { | 2902 | fn can_cast(kind: SyntaxKind) -> bool { |
2458 | match kind { | 2903 | match kind { |
@@ -2476,6 +2921,11 @@ impl TokenTree {} | |||
2476 | pub struct TypeParamList { | 2921 | pub struct TypeParamList { |
2477 | pub(crate) syntax: SyntaxNode, | 2922 | pub(crate) syntax: SyntaxNode, |
2478 | } | 2923 | } |
2924 | impl std::fmt::Display for TypeParamList { | ||
2925 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2926 | std::fmt::Display::fmt(self.syntax(), f) | ||
2927 | } | ||
2928 | } | ||
2479 | impl AstNode for TypeParamList { | 2929 | impl AstNode for TypeParamList { |
2480 | fn can_cast(kind: SyntaxKind) -> bool { | 2930 | fn can_cast(kind: SyntaxKind) -> bool { |
2481 | match kind { | 2931 | match kind { |
@@ -2506,6 +2956,11 @@ impl TypeParamList { | |||
2506 | pub struct TypeParam { | 2956 | pub struct TypeParam { |
2507 | pub(crate) syntax: SyntaxNode, | 2957 | pub(crate) syntax: SyntaxNode, |
2508 | } | 2958 | } |
2959 | impl std::fmt::Display for TypeParam { | ||
2960 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2961 | std::fmt::Display::fmt(self.syntax(), f) | ||
2962 | } | ||
2963 | } | ||
2509 | impl AstNode for TypeParam { | 2964 | impl AstNode for TypeParam { |
2510 | fn can_cast(kind: SyntaxKind) -> bool { | 2965 | fn can_cast(kind: SyntaxKind) -> bool { |
2511 | match kind { | 2966 | match kind { |
@@ -2536,6 +2991,11 @@ impl TypeParam { | |||
2536 | pub struct ConstParam { | 2991 | pub struct ConstParam { |
2537 | pub(crate) syntax: SyntaxNode, | 2992 | pub(crate) syntax: SyntaxNode, |
2538 | } | 2993 | } |
2994 | impl std::fmt::Display for ConstParam { | ||
2995 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
2996 | std::fmt::Display::fmt(self.syntax(), f) | ||
2997 | } | ||
2998 | } | ||
2539 | impl AstNode for ConstParam { | 2999 | impl AstNode for ConstParam { |
2540 | fn can_cast(kind: SyntaxKind) -> bool { | 3000 | fn can_cast(kind: SyntaxKind) -> bool { |
2541 | match kind { | 3001 | match kind { |
@@ -2566,6 +3026,11 @@ impl ConstParam { | |||
2566 | pub struct LifetimeParam { | 3026 | pub struct LifetimeParam { |
2567 | pub(crate) syntax: SyntaxNode, | 3027 | pub(crate) syntax: SyntaxNode, |
2568 | } | 3028 | } |
3029 | impl std::fmt::Display for LifetimeParam { | ||
3030 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3031 | std::fmt::Display::fmt(self.syntax(), f) | ||
3032 | } | ||
3033 | } | ||
2569 | impl AstNode for LifetimeParam { | 3034 | impl AstNode for LifetimeParam { |
2570 | fn can_cast(kind: SyntaxKind) -> bool { | 3035 | fn can_cast(kind: SyntaxKind) -> bool { |
2571 | match kind { | 3036 | match kind { |
@@ -2590,6 +3055,11 @@ impl LifetimeParam {} | |||
2590 | pub struct TypeBound { | 3055 | pub struct TypeBound { |
2591 | pub(crate) syntax: SyntaxNode, | 3056 | pub(crate) syntax: SyntaxNode, |
2592 | } | 3057 | } |
3058 | impl std::fmt::Display for TypeBound { | ||
3059 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3060 | std::fmt::Display::fmt(self.syntax(), f) | ||
3061 | } | ||
3062 | } | ||
2593 | impl AstNode for TypeBound { | 3063 | impl AstNode for TypeBound { |
2594 | fn can_cast(kind: SyntaxKind) -> bool { | 3064 | fn can_cast(kind: SyntaxKind) -> bool { |
2595 | match kind { | 3065 | match kind { |
@@ -2617,6 +3087,11 @@ impl TypeBound { | |||
2617 | pub struct TypeBoundList { | 3087 | pub struct TypeBoundList { |
2618 | pub(crate) syntax: SyntaxNode, | 3088 | pub(crate) syntax: SyntaxNode, |
2619 | } | 3089 | } |
3090 | impl std::fmt::Display for TypeBoundList { | ||
3091 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3092 | std::fmt::Display::fmt(self.syntax(), f) | ||
3093 | } | ||
3094 | } | ||
2620 | impl AstNode for TypeBoundList { | 3095 | impl AstNode for TypeBoundList { |
2621 | fn can_cast(kind: SyntaxKind) -> bool { | 3096 | fn can_cast(kind: SyntaxKind) -> bool { |
2622 | match kind { | 3097 | match kind { |
@@ -2644,6 +3119,11 @@ impl TypeBoundList { | |||
2644 | pub struct WherePred { | 3119 | pub struct WherePred { |
2645 | pub(crate) syntax: SyntaxNode, | 3120 | pub(crate) syntax: SyntaxNode, |
2646 | } | 3121 | } |
3122 | impl std::fmt::Display for WherePred { | ||
3123 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3124 | std::fmt::Display::fmt(self.syntax(), f) | ||
3125 | } | ||
3126 | } | ||
2647 | impl AstNode for WherePred { | 3127 | impl AstNode for WherePred { |
2648 | fn can_cast(kind: SyntaxKind) -> bool { | 3128 | fn can_cast(kind: SyntaxKind) -> bool { |
2649 | match kind { | 3129 | match kind { |
@@ -2672,6 +3152,11 @@ impl WherePred { | |||
2672 | pub struct WhereClause { | 3152 | pub struct WhereClause { |
2673 | pub(crate) syntax: SyntaxNode, | 3153 | pub(crate) syntax: SyntaxNode, |
2674 | } | 3154 | } |
3155 | impl std::fmt::Display for WhereClause { | ||
3156 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3157 | std::fmt::Display::fmt(self.syntax(), f) | ||
3158 | } | ||
3159 | } | ||
2675 | impl AstNode for WhereClause { | 3160 | impl AstNode for WhereClause { |
2676 | fn can_cast(kind: SyntaxKind) -> bool { | 3161 | fn can_cast(kind: SyntaxKind) -> bool { |
2677 | match kind { | 3162 | match kind { |
@@ -2699,6 +3184,11 @@ impl WhereClause { | |||
2699 | pub struct ExprStmt { | 3184 | pub struct ExprStmt { |
2700 | pub(crate) syntax: SyntaxNode, | 3185 | pub(crate) syntax: SyntaxNode, |
2701 | } | 3186 | } |
3187 | impl std::fmt::Display for ExprStmt { | ||
3188 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3189 | std::fmt::Display::fmt(self.syntax(), f) | ||
3190 | } | ||
3191 | } | ||
2702 | impl AstNode for ExprStmt { | 3192 | impl AstNode for ExprStmt { |
2703 | fn can_cast(kind: SyntaxKind) -> bool { | 3193 | fn can_cast(kind: SyntaxKind) -> bool { |
2704 | match kind { | 3194 | match kind { |
@@ -2726,6 +3216,11 @@ impl ExprStmt { | |||
2726 | pub struct LetStmt { | 3216 | pub struct LetStmt { |
2727 | pub(crate) syntax: SyntaxNode, | 3217 | pub(crate) syntax: SyntaxNode, |
2728 | } | 3218 | } |
3219 | impl std::fmt::Display for LetStmt { | ||
3220 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3221 | std::fmt::Display::fmt(self.syntax(), f) | ||
3222 | } | ||
3223 | } | ||
2729 | impl AstNode for LetStmt { | 3224 | impl AstNode for LetStmt { |
2730 | fn can_cast(kind: SyntaxKind) -> bool { | 3225 | fn can_cast(kind: SyntaxKind) -> bool { |
2731 | match kind { | 3226 | match kind { |
@@ -2757,6 +3252,11 @@ impl LetStmt { | |||
2757 | pub struct Condition { | 3252 | pub struct Condition { |
2758 | pub(crate) syntax: SyntaxNode, | 3253 | pub(crate) syntax: SyntaxNode, |
2759 | } | 3254 | } |
3255 | impl std::fmt::Display for Condition { | ||
3256 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3257 | std::fmt::Display::fmt(self.syntax(), f) | ||
3258 | } | ||
3259 | } | ||
2760 | impl AstNode for Condition { | 3260 | impl AstNode for Condition { |
2761 | fn can_cast(kind: SyntaxKind) -> bool { | 3261 | fn can_cast(kind: SyntaxKind) -> bool { |
2762 | match kind { | 3262 | match kind { |
@@ -2787,6 +3287,11 @@ impl Condition { | |||
2787 | pub struct Block { | 3287 | pub struct Block { |
2788 | pub(crate) syntax: SyntaxNode, | 3288 | pub(crate) syntax: SyntaxNode, |
2789 | } | 3289 | } |
3290 | impl std::fmt::Display for Block { | ||
3291 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3292 | std::fmt::Display::fmt(self.syntax(), f) | ||
3293 | } | ||
3294 | } | ||
2790 | impl AstNode for Block { | 3295 | impl AstNode for Block { |
2791 | fn can_cast(kind: SyntaxKind) -> bool { | 3296 | fn can_cast(kind: SyntaxKind) -> bool { |
2792 | match kind { | 3297 | match kind { |
@@ -2819,6 +3324,11 @@ impl Block { | |||
2819 | pub struct ParamList { | 3324 | pub struct ParamList { |
2820 | pub(crate) syntax: SyntaxNode, | 3325 | pub(crate) syntax: SyntaxNode, |
2821 | } | 3326 | } |
3327 | impl std::fmt::Display for ParamList { | ||
3328 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3329 | std::fmt::Display::fmt(self.syntax(), f) | ||
3330 | } | ||
3331 | } | ||
2822 | impl AstNode for ParamList { | 3332 | impl AstNode for ParamList { |
2823 | fn can_cast(kind: SyntaxKind) -> bool { | 3333 | fn can_cast(kind: SyntaxKind) -> bool { |
2824 | match kind { | 3334 | match kind { |
@@ -2849,6 +3359,11 @@ impl ParamList { | |||
2849 | pub struct SelfParam { | 3359 | pub struct SelfParam { |
2850 | pub(crate) syntax: SyntaxNode, | 3360 | pub(crate) syntax: SyntaxNode, |
2851 | } | 3361 | } |
3362 | impl std::fmt::Display for SelfParam { | ||
3363 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3364 | std::fmt::Display::fmt(self.syntax(), f) | ||
3365 | } | ||
3366 | } | ||
2852 | impl AstNode for SelfParam { | 3367 | impl AstNode for SelfParam { |
2853 | fn can_cast(kind: SyntaxKind) -> bool { | 3368 | fn can_cast(kind: SyntaxKind) -> bool { |
2854 | match kind { | 3369 | match kind { |
@@ -2874,6 +3389,11 @@ impl SelfParam {} | |||
2874 | pub struct Param { | 3389 | pub struct Param { |
2875 | pub(crate) syntax: SyntaxNode, | 3390 | pub(crate) syntax: SyntaxNode, |
2876 | } | 3391 | } |
3392 | impl std::fmt::Display for Param { | ||
3393 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3394 | std::fmt::Display::fmt(self.syntax(), f) | ||
3395 | } | ||
3396 | } | ||
2877 | impl AstNode for Param { | 3397 | impl AstNode for Param { |
2878 | fn can_cast(kind: SyntaxKind) -> bool { | 3398 | fn can_cast(kind: SyntaxKind) -> bool { |
2879 | match kind { | 3399 | match kind { |
@@ -2903,6 +3423,11 @@ impl Param { | |||
2903 | pub struct UseItem { | 3423 | pub struct UseItem { |
2904 | pub(crate) syntax: SyntaxNode, | 3424 | pub(crate) syntax: SyntaxNode, |
2905 | } | 3425 | } |
3426 | impl std::fmt::Display for UseItem { | ||
3427 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3428 | std::fmt::Display::fmt(self.syntax(), f) | ||
3429 | } | ||
3430 | } | ||
2906 | impl AstNode for UseItem { | 3431 | impl AstNode for UseItem { |
2907 | fn can_cast(kind: SyntaxKind) -> bool { | 3432 | fn can_cast(kind: SyntaxKind) -> bool { |
2908 | match kind { | 3433 | match kind { |
@@ -2932,6 +3457,11 @@ impl UseItem { | |||
2932 | pub struct UseTree { | 3457 | pub struct UseTree { |
2933 | pub(crate) syntax: SyntaxNode, | 3458 | pub(crate) syntax: SyntaxNode, |
2934 | } | 3459 | } |
3460 | impl std::fmt::Display for UseTree { | ||
3461 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3462 | std::fmt::Display::fmt(self.syntax(), f) | ||
3463 | } | ||
3464 | } | ||
2935 | impl AstNode for UseTree { | 3465 | impl AstNode for UseTree { |
2936 | fn can_cast(kind: SyntaxKind) -> bool { | 3466 | fn can_cast(kind: SyntaxKind) -> bool { |
2937 | match kind { | 3467 | match kind { |
@@ -2965,6 +3495,11 @@ impl UseTree { | |||
2965 | pub struct Alias { | 3495 | pub struct Alias { |
2966 | pub(crate) syntax: SyntaxNode, | 3496 | pub(crate) syntax: SyntaxNode, |
2967 | } | 3497 | } |
3498 | impl std::fmt::Display for Alias { | ||
3499 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3500 | std::fmt::Display::fmt(self.syntax(), f) | ||
3501 | } | ||
3502 | } | ||
2968 | impl AstNode for Alias { | 3503 | impl AstNode for Alias { |
2969 | fn can_cast(kind: SyntaxKind) -> bool { | 3504 | fn can_cast(kind: SyntaxKind) -> bool { |
2970 | match kind { | 3505 | match kind { |
@@ -2989,6 +3524,11 @@ impl Alias {} | |||
2989 | pub struct UseTreeList { | 3524 | pub struct UseTreeList { |
2990 | pub(crate) syntax: SyntaxNode, | 3525 | pub(crate) syntax: SyntaxNode, |
2991 | } | 3526 | } |
3527 | impl std::fmt::Display for UseTreeList { | ||
3528 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3529 | std::fmt::Display::fmt(self.syntax(), f) | ||
3530 | } | ||
3531 | } | ||
2992 | impl AstNode for UseTreeList { | 3532 | impl AstNode for UseTreeList { |
2993 | fn can_cast(kind: SyntaxKind) -> bool { | 3533 | fn can_cast(kind: SyntaxKind) -> bool { |
2994 | match kind { | 3534 | match kind { |
@@ -3016,6 +3556,11 @@ impl UseTreeList { | |||
3016 | pub struct ExternCrateItem { | 3556 | pub struct ExternCrateItem { |
3017 | pub(crate) syntax: SyntaxNode, | 3557 | pub(crate) syntax: SyntaxNode, |
3018 | } | 3558 | } |
3559 | impl std::fmt::Display for ExternCrateItem { | ||
3560 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3561 | std::fmt::Display::fmt(self.syntax(), f) | ||
3562 | } | ||
3563 | } | ||
3019 | impl AstNode for ExternCrateItem { | 3564 | impl AstNode for ExternCrateItem { |
3020 | fn can_cast(kind: SyntaxKind) -> bool { | 3565 | fn can_cast(kind: SyntaxKind) -> bool { |
3021 | match kind { | 3566 | match kind { |
@@ -3048,6 +3593,11 @@ impl ExternCrateItem { | |||
3048 | pub struct ArgList { | 3593 | pub struct ArgList { |
3049 | pub(crate) syntax: SyntaxNode, | 3594 | pub(crate) syntax: SyntaxNode, |
3050 | } | 3595 | } |
3596 | impl std::fmt::Display for ArgList { | ||
3597 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3598 | std::fmt::Display::fmt(self.syntax(), f) | ||
3599 | } | ||
3600 | } | ||
3051 | impl AstNode for ArgList { | 3601 | impl AstNode for ArgList { |
3052 | fn can_cast(kind: SyntaxKind) -> bool { | 3602 | fn can_cast(kind: SyntaxKind) -> bool { |
3053 | match kind { | 3603 | match kind { |
@@ -3075,6 +3625,11 @@ impl ArgList { | |||
3075 | pub struct Path { | 3625 | pub struct Path { |
3076 | pub(crate) syntax: SyntaxNode, | 3626 | pub(crate) syntax: SyntaxNode, |
3077 | } | 3627 | } |
3628 | impl std::fmt::Display for Path { | ||
3629 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3630 | std::fmt::Display::fmt(self.syntax(), f) | ||
3631 | } | ||
3632 | } | ||
3078 | impl AstNode for Path { | 3633 | impl AstNode for Path { |
3079 | fn can_cast(kind: SyntaxKind) -> bool { | 3634 | fn can_cast(kind: SyntaxKind) -> bool { |
3080 | match kind { | 3635 | match kind { |
@@ -3105,6 +3660,11 @@ impl Path { | |||
3105 | pub struct PathSegment { | 3660 | pub struct PathSegment { |
3106 | pub(crate) syntax: SyntaxNode, | 3661 | pub(crate) syntax: SyntaxNode, |
3107 | } | 3662 | } |
3663 | impl std::fmt::Display for PathSegment { | ||
3664 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3665 | std::fmt::Display::fmt(self.syntax(), f) | ||
3666 | } | ||
3667 | } | ||
3108 | impl AstNode for PathSegment { | 3668 | impl AstNode for PathSegment { |
3109 | fn can_cast(kind: SyntaxKind) -> bool { | 3669 | fn can_cast(kind: SyntaxKind) -> bool { |
3110 | match kind { | 3670 | match kind { |
@@ -3144,6 +3704,11 @@ impl PathSegment { | |||
3144 | pub struct TypeArgList { | 3704 | pub struct TypeArgList { |
3145 | pub(crate) syntax: SyntaxNode, | 3705 | pub(crate) syntax: SyntaxNode, |
3146 | } | 3706 | } |
3707 | impl std::fmt::Display for TypeArgList { | ||
3708 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3709 | std::fmt::Display::fmt(self.syntax(), f) | ||
3710 | } | ||
3711 | } | ||
3147 | impl AstNode for TypeArgList { | 3712 | impl AstNode for TypeArgList { |
3148 | fn can_cast(kind: SyntaxKind) -> bool { | 3713 | fn can_cast(kind: SyntaxKind) -> bool { |
3149 | match kind { | 3714 | match kind { |
@@ -3180,6 +3745,11 @@ impl TypeArgList { | |||
3180 | pub struct TypeArg { | 3745 | pub struct TypeArg { |
3181 | pub(crate) syntax: SyntaxNode, | 3746 | pub(crate) syntax: SyntaxNode, |
3182 | } | 3747 | } |
3748 | impl std::fmt::Display for TypeArg { | ||
3749 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3750 | std::fmt::Display::fmt(self.syntax(), f) | ||
3751 | } | ||
3752 | } | ||
3183 | impl AstNode for TypeArg { | 3753 | impl AstNode for TypeArg { |
3184 | fn can_cast(kind: SyntaxKind) -> bool { | 3754 | fn can_cast(kind: SyntaxKind) -> bool { |
3185 | match kind { | 3755 | match kind { |
@@ -3207,6 +3777,11 @@ impl TypeArg { | |||
3207 | pub struct AssocTypeArg { | 3777 | pub struct AssocTypeArg { |
3208 | pub(crate) syntax: SyntaxNode, | 3778 | pub(crate) syntax: SyntaxNode, |
3209 | } | 3779 | } |
3780 | impl std::fmt::Display for AssocTypeArg { | ||
3781 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3782 | std::fmt::Display::fmt(self.syntax(), f) | ||
3783 | } | ||
3784 | } | ||
3210 | impl AstNode for AssocTypeArg { | 3785 | impl AstNode for AssocTypeArg { |
3211 | fn can_cast(kind: SyntaxKind) -> bool { | 3786 | fn can_cast(kind: SyntaxKind) -> bool { |
3212 | match kind { | 3787 | match kind { |
@@ -3237,6 +3812,11 @@ impl AssocTypeArg { | |||
3237 | pub struct LifetimeArg { | 3812 | pub struct LifetimeArg { |
3238 | pub(crate) syntax: SyntaxNode, | 3813 | pub(crate) syntax: SyntaxNode, |
3239 | } | 3814 | } |
3815 | impl std::fmt::Display for LifetimeArg { | ||
3816 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3817 | std::fmt::Display::fmt(self.syntax(), f) | ||
3818 | } | ||
3819 | } | ||
3240 | impl AstNode for LifetimeArg { | 3820 | impl AstNode for LifetimeArg { |
3241 | fn can_cast(kind: SyntaxKind) -> bool { | 3821 | fn can_cast(kind: SyntaxKind) -> bool { |
3242 | match kind { | 3822 | match kind { |
@@ -3260,6 +3840,11 @@ impl LifetimeArg {} | |||
3260 | pub struct ConstArg { | 3840 | pub struct ConstArg { |
3261 | pub(crate) syntax: SyntaxNode, | 3841 | pub(crate) syntax: SyntaxNode, |
3262 | } | 3842 | } |
3843 | impl std::fmt::Display for ConstArg { | ||
3844 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3845 | std::fmt::Display::fmt(self.syntax(), f) | ||
3846 | } | ||
3847 | } | ||
3263 | impl AstNode for ConstArg { | 3848 | impl AstNode for ConstArg { |
3264 | fn can_cast(kind: SyntaxKind) -> bool { | 3849 | fn can_cast(kind: SyntaxKind) -> bool { |
3265 | match kind { | 3850 | match kind { |
@@ -3290,6 +3875,11 @@ impl ConstArg { | |||
3290 | pub struct MacroItems { | 3875 | pub struct MacroItems { |
3291 | pub(crate) syntax: SyntaxNode, | 3876 | pub(crate) syntax: SyntaxNode, |
3292 | } | 3877 | } |
3878 | impl std::fmt::Display for MacroItems { | ||
3879 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3880 | std::fmt::Display::fmt(self.syntax(), f) | ||
3881 | } | ||
3882 | } | ||
3293 | impl AstNode for MacroItems { | 3883 | impl AstNode for MacroItems { |
3294 | fn can_cast(kind: SyntaxKind) -> bool { | 3884 | fn can_cast(kind: SyntaxKind) -> bool { |
3295 | match kind { | 3885 | match kind { |
@@ -3315,6 +3905,11 @@ impl MacroItems {} | |||
3315 | pub struct MacroStmts { | 3905 | pub struct MacroStmts { |
3316 | pub(crate) syntax: SyntaxNode, | 3906 | pub(crate) syntax: SyntaxNode, |
3317 | } | 3907 | } |
3908 | impl std::fmt::Display for MacroStmts { | ||
3909 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3910 | std::fmt::Display::fmt(self.syntax(), f) | ||
3911 | } | ||
3912 | } | ||
3318 | impl AstNode for MacroStmts { | 3913 | impl AstNode for MacroStmts { |
3319 | fn can_cast(kind: SyntaxKind) -> bool { | 3914 | fn can_cast(kind: SyntaxKind) -> bool { |
3320 | match kind { | 3915 | match kind { |
@@ -3362,6 +3957,11 @@ impl From<UnionDef> for NominalDef { | |||
3362 | NominalDef::UnionDef(node) | 3957 | NominalDef::UnionDef(node) |
3363 | } | 3958 | } |
3364 | } | 3959 | } |
3960 | impl std::fmt::Display for NominalDef { | ||
3961 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
3962 | std::fmt::Display::fmt(self.syntax(), f) | ||
3963 | } | ||
3964 | } | ||
3365 | impl AstNode for NominalDef { | 3965 | impl AstNode for NominalDef { |
3366 | fn can_cast(kind: SyntaxKind) -> bool { | 3966 | fn can_cast(kind: SyntaxKind) -> bool { |
3367 | match kind { | 3967 | match kind { |
@@ -3470,6 +4070,11 @@ impl From<DynTraitType> for TypeRef { | |||
3470 | TypeRef::DynTraitType(node) | 4070 | TypeRef::DynTraitType(node) |
3471 | } | 4071 | } |
3472 | } | 4072 | } |
4073 | impl std::fmt::Display for TypeRef { | ||
4074 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
4075 | std::fmt::Display::fmt(self.syntax(), f) | ||
4076 | } | ||
4077 | } | ||
3473 | impl AstNode for TypeRef { | 4078 | impl AstNode for TypeRef { |
3474 | fn can_cast(kind: SyntaxKind) -> bool { | 4079 | fn can_cast(kind: SyntaxKind) -> bool { |
3475 | match kind { | 4080 | match kind { |
@@ -3591,6 +4196,11 @@ impl From<Module> for ModuleItem { | |||
3591 | ModuleItem::Module(node) | 4196 | ModuleItem::Module(node) |
3592 | } | 4197 | } |
3593 | } | 4198 | } |
4199 | impl std::fmt::Display for ModuleItem { | ||
4200 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
4201 | std::fmt::Display::fmt(self.syntax(), f) | ||
4202 | } | ||
4203 | } | ||
3594 | impl AstNode for ModuleItem { | 4204 | impl AstNode for ModuleItem { |
3595 | fn can_cast(kind: SyntaxKind) -> bool { | 4205 | fn can_cast(kind: SyntaxKind) -> bool { |
3596 | match kind { | 4206 | match kind { |
@@ -3657,6 +4267,11 @@ impl From<ConstDef> for ImplItem { | |||
3657 | ImplItem::ConstDef(node) | 4267 | ImplItem::ConstDef(node) |
3658 | } | 4268 | } |
3659 | } | 4269 | } |
4270 | impl std::fmt::Display for ImplItem { | ||
4271 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
4272 | std::fmt::Display::fmt(self.syntax(), f) | ||
4273 | } | ||
4274 | } | ||
3660 | impl AstNode for ImplItem { | 4275 | impl AstNode for ImplItem { |
3661 | fn can_cast(kind: SyntaxKind) -> bool { | 4276 | fn can_cast(kind: SyntaxKind) -> bool { |
3662 | match kind { | 4277 | match kind { |
@@ -3871,6 +4486,11 @@ impl From<BoxExpr> for Expr { | |||
3871 | Expr::BoxExpr(node) | 4486 | Expr::BoxExpr(node) |
3872 | } | 4487 | } |
3873 | } | 4488 | } |
4489 | impl std::fmt::Display for Expr { | ||
4490 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
4491 | std::fmt::Display::fmt(self.syntax(), f) | ||
4492 | } | ||
4493 | } | ||
3874 | impl AstNode for Expr { | 4494 | impl AstNode for Expr { |
3875 | fn can_cast(kind: SyntaxKind) -> bool { | 4495 | fn can_cast(kind: SyntaxKind) -> bool { |
3876 | match kind { | 4496 | match kind { |
@@ -4043,6 +4663,11 @@ impl From<LiteralPat> for Pat { | |||
4043 | Pat::LiteralPat(node) | 4663 | Pat::LiteralPat(node) |
4044 | } | 4664 | } |
4045 | } | 4665 | } |
4666 | impl std::fmt::Display for Pat { | ||
4667 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
4668 | std::fmt::Display::fmt(self.syntax(), f) | ||
4669 | } | ||
4670 | } | ||
4046 | impl AstNode for Pat { | 4671 | impl AstNode for Pat { |
4047 | fn can_cast(kind: SyntaxKind) -> bool { | 4672 | fn can_cast(kind: SyntaxKind) -> bool { |
4048 | match kind { | 4673 | match kind { |
@@ -4106,6 +4731,11 @@ impl From<TokenTree> for AttrInput { | |||
4106 | AttrInput::TokenTree(node) | 4731 | AttrInput::TokenTree(node) |
4107 | } | 4732 | } |
4108 | } | 4733 | } |
4734 | impl std::fmt::Display for AttrInput { | ||
4735 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
4736 | std::fmt::Display::fmt(self.syntax(), f) | ||
4737 | } | ||
4738 | } | ||
4109 | impl AstNode for AttrInput { | 4739 | impl AstNode for AttrInput { |
4110 | fn can_cast(kind: SyntaxKind) -> bool { | 4740 | fn can_cast(kind: SyntaxKind) -> bool { |
4111 | match kind { | 4741 | match kind { |
@@ -4143,6 +4773,11 @@ impl From<LetStmt> for Stmt { | |||
4143 | Stmt::LetStmt(node) | 4773 | Stmt::LetStmt(node) |
4144 | } | 4774 | } |
4145 | } | 4775 | } |
4776 | impl std::fmt::Display for Stmt { | ||
4777 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
4778 | std::fmt::Display::fmt(self.syntax(), f) | ||
4779 | } | ||
4780 | } | ||
4146 | impl AstNode for Stmt { | 4781 | impl AstNode for Stmt { |
4147 | fn can_cast(kind: SyntaxKind) -> bool { | 4782 | fn can_cast(kind: SyntaxKind) -> bool { |
4148 | match kind { | 4783 | match kind { |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.rs b/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.rs new file mode 100644 index 000000000..05acc30f1 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn foo() { | ||
2 | v = {1}&2; | ||
3 | } | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.txt b/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.txt new file mode 100644 index 000000000..d568a1d45 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0158_binop_resets_statementness.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | SOURCE_FILE@[0; 28) | ||
2 | FN_DEF@[0; 27) | ||
3 | FN_KW@[0; 2) "fn" | ||
4 | WHITESPACE@[2; 3) " " | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) "(" | ||
9 | R_PAREN@[7; 8) ")" | ||
10 | WHITESPACE@[8; 9) " " | ||
11 | BLOCK_EXPR@[9; 27) | ||
12 | BLOCK@[9; 27) | ||
13 | L_CURLY@[9; 10) "{" | ||
14 | WHITESPACE@[10; 15) "\n " | ||
15 | EXPR_STMT@[15; 25) | ||
16 | BIN_EXPR@[15; 24) | ||
17 | PATH_EXPR@[15; 16) | ||
18 | PATH@[15; 16) | ||
19 | PATH_SEGMENT@[15; 16) | ||
20 | NAME_REF@[15; 16) | ||
21 | IDENT@[15; 16) "v" | ||
22 | WHITESPACE@[16; 17) " " | ||
23 | EQ@[17; 18) "=" | ||
24 | WHITESPACE@[18; 19) " " | ||
25 | BIN_EXPR@[19; 24) | ||
26 | BLOCK_EXPR@[19; 22) | ||
27 | BLOCK@[19; 22) | ||
28 | L_CURLY@[19; 20) "{" | ||
29 | LITERAL@[20; 21) | ||
30 | INT_NUMBER@[20; 21) "1" | ||
31 | R_CURLY@[21; 22) "}" | ||
32 | AMP@[22; 23) "&" | ||
33 | LITERAL@[23; 24) | ||
34 | INT_NUMBER@[23; 24) "2" | ||
35 | SEMI@[24; 25) ";" | ||
36 | WHITESPACE@[25; 26) "\n" | ||
37 | R_CURLY@[26; 27) "}" | ||
38 | WHITESPACE@[27; 28) "\n" | ||
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 5df29a383..2ce69c9b3 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs | |||
@@ -52,7 +52,10 @@ pub(crate) fn load_cargo( | |||
52 | opts | 52 | opts |
53 | }; | 53 | }; |
54 | 54 | ||
55 | let crate_graph = ws.to_crate_graph(&default_cfg_options, &mut |path: &Path| { | 55 | // FIXME: outdirs? |
56 | let outdirs = FxHashMap::default(); | ||
57 | |||
58 | let crate_graph = ws.to_crate_graph(&default_cfg_options, &outdirs, &mut |path: &Path| { | ||
56 | let vfs_file = vfs.load(path); | 59 | let vfs_file = vfs.load(path); |
57 | log::debug!("vfs file {:?} -> {:?}", path, vfs_file); | 60 | log::debug!("vfs file {:?} -> {:?}", path, vfs_file); |
58 | vfs_file.map(vfs_file_to_id) | 61 | vfs_file.map(vfs_file_to_id) |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 3a6cfbe7b..bd5904db0 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -47,6 +47,9 @@ pub struct ServerConfig { | |||
47 | /// Fine grained feature flags to disable specific features. | 47 | /// Fine grained feature flags to disable specific features. |
48 | pub feature_flags: FxHashMap<String, bool>, | 48 | pub feature_flags: FxHashMap<String, bool>, |
49 | 49 | ||
50 | /// Fine grained controls for additional `OUT_DIR` env variables | ||
51 | pub additional_out_dirs: FxHashMap<String, String>, | ||
52 | |||
50 | pub rustfmt_args: Vec<String>, | 53 | pub rustfmt_args: Vec<String>, |
51 | 54 | ||
52 | /// Cargo feature configurations. | 55 | /// Cargo feature configurations. |
@@ -67,6 +70,7 @@ impl Default for ServerConfig { | |||
67 | cargo_watch_all_targets: true, | 70 | cargo_watch_all_targets: true, |
68 | with_sysroot: true, | 71 | with_sysroot: true, |
69 | feature_flags: FxHashMap::default(), | 72 | feature_flags: FxHashMap::default(), |
73 | additional_out_dirs: FxHashMap::default(), | ||
70 | cargo_features: Default::default(), | 74 | cargo_features: Default::default(), |
71 | rustfmt_args: Vec::new(), | 75 | rustfmt_args: Vec::new(), |
72 | } | 76 | } |
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index b6d1f28d8..495056da3 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -196,6 +196,7 @@ pub fn main_loop( | |||
196 | Watch(!config.use_client_watching), | 196 | Watch(!config.use_client_watching), |
197 | options, | 197 | options, |
198 | feature_flags, | 198 | feature_flags, |
199 | config.additional_out_dirs, | ||
199 | ) | 200 | ) |
200 | }; | 201 | }; |
201 | 202 | ||
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs index 004803b00..d358f6b47 100644 --- a/crates/rust-analyzer/src/world.rs +++ b/crates/rust-analyzer/src/world.rs | |||
@@ -27,6 +27,8 @@ use crate::{ | |||
27 | vfs_glob::{Glob, RustPackageFilterBuilder}, | 27 | vfs_glob::{Glob, RustPackageFilterBuilder}, |
28 | LspError, Result, | 28 | LspError, Result, |
29 | }; | 29 | }; |
30 | use ra_db::ExternSourceId; | ||
31 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
30 | 32 | ||
31 | #[derive(Debug, Clone)] | 33 | #[derive(Debug, Clone)] |
32 | pub struct Options { | 34 | pub struct Options { |
@@ -79,6 +81,7 @@ impl WorldState { | |||
79 | watch: Watch, | 81 | watch: Watch, |
80 | options: Options, | 82 | options: Options, |
81 | feature_flags: FeatureFlags, | 83 | feature_flags: FeatureFlags, |
84 | additional_out_dirs: FxHashMap<String, String>, | ||
82 | ) -> WorldState { | 85 | ) -> WorldState { |
83 | let mut change = AnalysisChange::new(); | 86 | let mut change = AnalysisChange::new(); |
84 | 87 | ||
@@ -100,6 +103,19 @@ impl WorldState { | |||
100 | RootEntry::new(pkg_root.path().clone(), filter.into_vfs_filter()) | 103 | RootEntry::new(pkg_root.path().clone(), filter.into_vfs_filter()) |
101 | })); | 104 | })); |
102 | } | 105 | } |
106 | |||
107 | let extern_dirs: FxHashSet<_> = | ||
108 | additional_out_dirs.iter().map(|(_, path)| (PathBuf::from(path))).collect(); | ||
109 | let mut extern_source_roots = FxHashMap::default(); | ||
110 | |||
111 | roots.extend(additional_out_dirs.iter().map(|(_, path)| { | ||
112 | let mut filter = RustPackageFilterBuilder::default().set_member(false); | ||
113 | for glob in exclude_globs.iter() { | ||
114 | filter = filter.exclude(glob.clone()); | ||
115 | } | ||
116 | RootEntry::new(PathBuf::from(&path), filter.into_vfs_filter()) | ||
117 | })); | ||
118 | |||
103 | let (task_sender, task_receiver) = unbounded(); | 119 | let (task_sender, task_receiver) = unbounded(); |
104 | let task_sender = Box::new(move |t| task_sender.send(t).unwrap()); | 120 | let task_sender = Box::new(move |t| task_sender.send(t).unwrap()); |
105 | let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch); | 121 | let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch); |
@@ -109,6 +125,11 @@ impl WorldState { | |||
109 | let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it)); | 125 | let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it)); |
110 | change.add_root(SourceRootId(r.0), is_local); | 126 | change.add_root(SourceRootId(r.0), is_local); |
111 | change.set_debug_root_path(SourceRootId(r.0), vfs_root_path.display().to_string()); | 127 | change.set_debug_root_path(SourceRootId(r.0), vfs_root_path.display().to_string()); |
128 | |||
129 | // FIXME: add path2root in vfs to simpily this logic | ||
130 | if extern_dirs.contains(&vfs_root_path) { | ||
131 | extern_source_roots.insert(vfs_root_path, ExternSourceId(r.0)); | ||
132 | } | ||
112 | } | 133 | } |
113 | 134 | ||
114 | // FIXME: Read default cfgs from config | 135 | // FIXME: Read default cfgs from config |
@@ -126,11 +147,20 @@ impl WorldState { | |||
126 | vfs_file.map(|f| FileId(f.0)) | 147 | vfs_file.map(|f| FileId(f.0)) |
127 | }; | 148 | }; |
128 | 149 | ||
129 | workspaces.iter().map(|ws| ws.to_crate_graph(&default_cfg_options, &mut load)).for_each( | 150 | let mut outdirs = FxHashMap::default(); |
130 | |graph| { | 151 | for (name, path) in additional_out_dirs { |
152 | let path = PathBuf::from(&path); | ||
153 | if let Some(id) = extern_source_roots.get(&path) { | ||
154 | outdirs.insert(name, (id.clone(), path.to_string_lossy().replace("\\", "/"))); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | workspaces | ||
159 | .iter() | ||
160 | .map(|ws| ws.to_crate_graph(&default_cfg_options, &outdirs, &mut load)) | ||
161 | .for_each(|graph| { | ||
131 | crate_graph.extend(graph); | 162 | crate_graph.extend(graph); |
132 | }, | 163 | }); |
133 | ); | ||
134 | change.set_crate_graph(crate_graph); | 164 | change.set_crate_graph(crate_graph); |
135 | 165 | ||
136 | // FIXME: Figure out the multi-workspace situation | 166 | // FIXME: Figure out the multi-workspace situation |
diff --git a/editors/code/package.json b/editors/code/package.json index 78f3539e9..3aaae357a 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -224,6 +224,11 @@ | |||
224 | "default": true, | 224 | "default": true, |
225 | "description": "Whether to ask for permission before downloading any files from the Internet" | 225 | "description": "Whether to ask for permission before downloading any files from the Internet" |
226 | }, | 226 | }, |
227 | "rust-analyzer.additionalOutDirs": { | ||
228 | "type": "object", | ||
229 | "default": {}, | ||
230 | "markdownDescription": "Fine grained controls for OUT_DIR `env!(\"OUT_DIR\")` variable. e.g. `{\"foo\":\"/path/to/foo\"}`, " | ||
231 | }, | ||
227 | "rust-analyzer.serverPath": { | 232 | "rust-analyzer.serverPath": { |
228 | "type": [ | 233 | "type": [ |
229 | "null", | 234 | "null", |
@@ -256,7 +261,7 @@ | |||
256 | "rust-analyzer.cargo-watch.enable": { | 261 | "rust-analyzer.cargo-watch.enable": { |
257 | "type": "boolean", | 262 | "type": "boolean", |
258 | "default": true, | 263 | "default": true, |
259 | "markdownDescription": "Run `cargo check` for diagnostics on save" | 264 | "markdownDescription": "Run specified `cargo-watch` command for diagnostics on save" |
260 | }, | 265 | }, |
261 | "rust-analyzer.cargo-watch.arguments": { | 266 | "rust-analyzer.cargo-watch.arguments": { |
262 | "type": "array", | 267 | "type": "array", |
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 3b8ea6f77..e9f261c24 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts | |||
@@ -37,6 +37,7 @@ export async function createClient(config: Config, serverPath: string): Promise< | |||
37 | excludeGlobs: config.excludeGlobs, | 37 | excludeGlobs: config.excludeGlobs, |
38 | useClientWatching: config.useClientWatching, | 38 | useClientWatching: config.useClientWatching, |
39 | featureFlags: config.featureFlags, | 39 | featureFlags: config.featureFlags, |
40 | additionalOutDirs: config.additionalOutDirs, | ||
40 | withSysroot: config.withSysroot, | 41 | withSysroot: config.withSysroot, |
41 | cargoFeatures: config.cargoFeatures, | 42 | cargoFeatures: config.cargoFeatures, |
42 | rustfmtArgs: config.rustfmtArgs, | 43 | rustfmtArgs: config.rustfmtArgs, |
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index c3b3ecabf..6db073bec 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts | |||
@@ -166,6 +166,7 @@ export class Config { | |||
166 | get excludeGlobs() { return this.cfg.get("excludeGlobs") as string[]; } | 166 | get excludeGlobs() { return this.cfg.get("excludeGlobs") as string[]; } |
167 | get useClientWatching() { return this.cfg.get("useClientWatching") as boolean; } | 167 | get useClientWatching() { return this.cfg.get("useClientWatching") as boolean; } |
168 | get featureFlags() { return this.cfg.get("featureFlags") as Record<string, boolean>; } | 168 | get featureFlags() { return this.cfg.get("featureFlags") as Record<string, boolean>; } |
169 | get additionalOutDirs() { return this.cfg.get("additionalOutDirs") as Record<string, string>; } | ||
169 | get rustfmtArgs() { return this.cfg.get("rustfmtArgs") as string[]; } | 170 | get rustfmtArgs() { return this.cfg.get("rustfmtArgs") as string[]; } |
170 | 171 | ||
171 | get cargoWatchOptions(): CargoWatchOptions { | 172 | get cargoWatchOptions(): CargoWatchOptions { |
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs index db05dcebb..32afd47bc 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs | |||
@@ -68,6 +68,12 @@ fn generate_ast(grammar: AstSrc<'_>) -> Result<String> { | |||
68 | pub(crate) syntax: SyntaxNode, | 68 | pub(crate) syntax: SyntaxNode, |
69 | } | 69 | } |
70 | 70 | ||
71 | impl std::fmt::Display for #name { | ||
72 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
73 | std::fmt::Display::fmt(self.syntax(), f) | ||
74 | } | ||
75 | } | ||
76 | |||
71 | impl AstNode for #name { | 77 | impl AstNode for #name { |
72 | fn can_cast(kind: SyntaxKind) -> bool { | 78 | fn can_cast(kind: SyntaxKind) -> bool { |
73 | match kind { | 79 | match kind { |
@@ -114,6 +120,12 @@ fn generate_ast(grammar: AstSrc<'_>) -> Result<String> { | |||
114 | } | 120 | } |
115 | )* | 121 | )* |
116 | 122 | ||
123 | impl std::fmt::Display for #name { | ||
124 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
125 | std::fmt::Display::fmt(self.syntax(), f) | ||
126 | } | ||
127 | } | ||
128 | |||
117 | impl AstNode for #name { | 129 | impl AstNode for #name { |
118 | fn can_cast(kind: SyntaxKind) -> bool { | 130 | fn can_cast(kind: SyntaxKind) -> bool { |
119 | match kind { | 131 | match kind { |