aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock21
-rw-r--r--crates/ra_assists/src/lib.rs2
-rw-r--r--crates/ra_cargo_watch/src/conv.rs128
-rw-r--r--crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap172
-rw-r--r--crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap76
-rw-r--r--crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap102
-rw-r--r--crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_multi_line_fix.snap114
-rw-r--r--crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap76
-rw-r--r--crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap76
-rw-r--r--crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap148
-rw-r--r--crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap108
-rw-r--r--crates/ra_cargo_watch/src/conv/test.rs148
-rw-r--r--crates/ra_cargo_watch/src/lib.rs32
-rw-r--r--crates/ra_hir/Cargo.toml1
-rw-r--r--crates/ra_hir/src/code_model.rs56
-rw-r--r--crates/ra_hir/src/semantics.rs8
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs48
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs22
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs56
-rw-r--r--crates/ra_hir_expand/src/name.rs1
-rw-r--r--crates/ra_hir_expand/src/quote.rs1
-rw-r--r--crates/ra_ide/src/call_info.rs14
-rw-r--r--crates/ra_ide/src/completion.rs4
-rw-r--r--crates/ra_ide/src/completion/complete_path.rs70
-rw-r--r--crates/ra_ide/src/completion/complete_scope.rs36
-rw-r--r--crates/ra_ide/src/completion/completion_item.rs3
-rw-r--r--crates/ra_ide/src/completion/presentation.rs13
-rw-r--r--crates/ra_ide/src/display/function_signature.rs4
-rw-r--r--crates/ra_ide/src/hover.rs27
-rw-r--r--crates/ra_ide/src/inlay_hints.rs113
-rw-r--r--crates/ra_ide/src/lib.rs6
-rw-r--r--crates/ra_ide/src/syntax_tree.rs16
-rw-r--r--crates/ra_ide_db/src/line_index.rs14
-rw-r--r--crates/ra_ide_db/src/line_index_utils.rs2
-rw-r--r--crates/ra_parser/src/grammar/params.rs64
-rw-r--r--crates/ra_syntax/src/ast.rs2
-rw-r--r--crates/ra_syntax/src/ast/generated.rs635
-rw-r--r--crates/ra_syntax/src/parsing/lexer.rs4
-rw-r--r--crates/ra_syntax/src/tests.rs11
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.txt3
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0116_trait_fn_placeholder_parameter.rs3
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0116_trait_fn_placeholder_parameter.txt47
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.txt3
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.txt44
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt3
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rs (renamed from crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.rs)1
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.txt (renamed from crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.txt)47
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rs5
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.txt133
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rs (renamed from crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.rs)0
-rw-r--r--crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.txt (renamed from crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.txt)0
-rw-r--r--crates/ra_text_edit/src/text_edit.rs10
-rw-r--r--crates/rust-analyzer/src/config.rs10
-rw-r--r--crates/rust-analyzer/src/conv.rs18
-rw-r--r--crates/rust-analyzer/src/main_loop.rs8
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs13
-rw-r--r--crates/rust-analyzer/src/world.rs5
-rw-r--r--crates/test_utils/src/lib.rs3
-rw-r--r--docs/user/features.md5
-rw-r--r--editors/code/package.json13
-rw-r--r--editors/code/src/client.ts7
-rw-r--r--editors/code/src/config.ts18
-rw-r--r--editors/code/src/inlay_hints.ts2
-rw-r--r--xtask/src/codegen/gen_syntax.rs12
-rw-r--r--xtask/src/lib.rs8
66 files changed, 2181 insertions, 675 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 330bdd1cb..41b6d4ab4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -58,9 +58,9 @@ dependencies = [
58 58
59[[package]] 59[[package]]
60name = "backtrace-sys" 60name = "backtrace-sys"
61version = "0.1.33" 61version = "0.1.34"
62source = "registry+https://github.com/rust-lang/crates.io-index" 62source = "registry+https://github.com/rust-lang/crates.io-index"
63checksum = "e17b52e737c40a7d75abca20b29a19a0eb7ba9fc72c5a72dd282a0a3c2c0dc35" 63checksum = "ca797db0057bae1a7aa2eef3283a874695455cecf08a43bfb8507ee0ebc1ed69"
64dependencies = [ 64dependencies = [
65 "cc", 65 "cc",
66 "libc", 66 "libc",
@@ -80,9 +80,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
80 80
81[[package]] 81[[package]]
82name = "bstr" 82name = "bstr"
83version = "0.2.11" 83version = "0.2.12"
84source = "registry+https://github.com/rust-lang/crates.io-index" 84source = "registry+https://github.com/rust-lang/crates.io-index"
85checksum = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48" 85checksum = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41"
86dependencies = [ 86dependencies = [
87 "memchr", 87 "memchr",
88] 88]
@@ -940,6 +940,7 @@ dependencies = [
940name = "ra_hir" 940name = "ra_hir"
941version = "0.1.0" 941version = "0.1.0"
942dependencies = [ 942dependencies = [
943 "arrayvec",
943 "either", 944 "either",
944 "itertools", 945 "itertools",
945 "log", 946 "log",
@@ -1229,9 +1230,9 @@ checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
1229 1230
1230[[package]] 1231[[package]]
1231name = "regex" 1232name = "regex"
1232version = "1.3.4" 1233version = "1.3.5"
1233source = "registry+https://github.com/rust-lang/crates.io-index" 1234source = "registry+https://github.com/rust-lang/crates.io-index"
1234checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" 1235checksum = "8900ebc1363efa7ea1c399ccc32daed870b4002651e0bed86e72d501ebbe0048"
1235dependencies = [ 1236dependencies = [
1236 "aho-corasick", 1237 "aho-corasick",
1237 "memchr", 1238 "memchr",
@@ -1241,9 +1242,9 @@ dependencies = [
1241 1242
1242[[package]] 1243[[package]]
1243name = "regex-syntax" 1244name = "regex-syntax"
1244version = "0.6.16" 1245version = "0.6.17"
1245source = "registry+https://github.com/rust-lang/crates.io-index" 1246source = "registry+https://github.com/rust-lang/crates.io-index"
1246checksum = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" 1247checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
1247 1248
1248[[package]] 1249[[package]]
1249name = "relative-path" 1250name = "relative-path"
@@ -1341,9 +1342,9 @@ dependencies = [
1341 1342
1342[[package]] 1343[[package]]
1343name = "ryu" 1344name = "ryu"
1344version = "1.0.2" 1345version = "1.0.3"
1345source = "registry+https://github.com/rust-lang/crates.io-index" 1346source = "registry+https://github.com/rust-lang/crates.io-index"
1346checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" 1347checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
1347 1348
1348[[package]] 1349[[package]]
1349name = "salsa" 1350name = "salsa"
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index 50a15f978..62fadcddd 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -235,7 +235,7 @@ mod helpers {
235 (Some(assist), ExpectedResult::Target(target)) => { 235 (Some(assist), ExpectedResult::Target(target)) => {
236 let action = assist.0[0].action.clone().unwrap(); 236 let action = assist.0[0].action.clone().unwrap();
237 let range = action.target.expect("expected target on action"); 237 let range = action.target.expect("expected target on action");
238 assert_eq_text!(&before[range.start().to_usize()..range.end().to_usize()], target); 238 assert_eq_text!(&before[range], target);
239 } 239 }
240 (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"), 240 (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"),
241 (None, ExpectedResult::After(_)) | (None, ExpectedResult::Target(_)) => { 241 (None, ExpectedResult::After(_)) | (None, ExpectedResult::Target(_)) => {
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};
10use std::{ 10use 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 {
189pub(crate) fn map_rust_diagnostic_to_lsp( 180pub(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 @@
2source: crates/ra_cargo_watch/src/conv/test.rs 2source: crates/ra_cargo_watch/src/conv/test.rs
3expression: diag 3expression: diag
4--- 4---
5MappedRustDiagnostic { 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 @@
2source: crates/ra_cargo_watch/src/conv/test.rs 2source: crates/ra_cargo_watch/src/conv/test.rs
3expression: diag 3expression: diag
4--- 4---
5MappedRustDiagnostic { 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 @@
2source: crates/ra_cargo_watch/src/conv/test.rs 2source: crates/ra_cargo_watch/src/conv/test.rs
3expression: diag 3expression: diag
4--- 4---
5MappedRustDiagnostic { 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---
2source: crates/ra_cargo_watch/src/conv/test.rs
3expression: 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 @@
2source: crates/ra_cargo_watch/src/conv/test.rs 2source: crates/ra_cargo_watch/src/conv/test.rs
3expression: diag 3expression: diag
4--- 4---
5MappedRustDiagnostic { 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 @@
2source: crates/ra_cargo_watch/src/conv/test.rs 2source: crates/ra_cargo_watch/src/conv/test.rs
3expression: diag 3expression: diag
4--- 4---
5MappedRustDiagnostic { 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 @@
2source: crates/ra_cargo_watch/src/conv/test.rs 2source: crates/ra_cargo_watch/src/conv/test.rs
3expression: diag 3expression: diag
4--- 4---
5MappedRustDiagnostic { 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 @@
2source: crates/ra_cargo_watch/src/conv/test.rs 2source: crates/ra_cargo_watch/src/conv/test.rs
3expression: diag 3expression: diag
4--- 4---
5MappedRustDiagnostic { 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))]
942fn 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_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index 266c4cff3..42193b492 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -11,6 +11,7 @@ doctest = false
11log = "0.4.8" 11log = "0.4.8"
12rustc-hash = "1.1.0" 12rustc-hash = "1.1.0"
13either = "1.5.3" 13either = "1.5.3"
14arrayvec = "0.5.1"
14 15
15itertools = "0.8.2" 16itertools = "0.8.2"
16 17
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 41d4e2ed3..ff041150b 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1,6 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use arrayvec::ArrayVec;
4use either::Either; 5use either::Either;
5use hir_def::{ 6use hir_def::{
6 adt::StructKind, 7 adt::StructKind,
@@ -226,7 +227,9 @@ impl Module {
226 Some((name, def)) 227 Some((name, def))
227 } 228 }
228 }) 229 })
229 .map(|(name, def)| (name.clone(), def.into())) 230 .flat_map(|(name, def)| {
231 ScopeDef::all_items(def).into_iter().map(move |item| (name.clone(), item))
232 })
230 .collect() 233 .collect()
231 } 234 }
232 235
@@ -308,7 +311,11 @@ impl StructField {
308 self.parent.variant_data(db).fields()[self.id].name.clone() 311 self.parent.variant_data(db).fields()[self.id].name.clone()
309 } 312 }
310 313
311 pub fn ty(&self, db: &impl HirDatabase) -> Type { 314 /// Returns the type as in the signature of the struct (i.e., with
315 /// placeholder types for type parameters). This is good for showing
316 /// signature help, but not so good to actually get the type of the field
317 /// when you actually have a variable of the struct.
318 pub fn signature_ty(&self, db: &impl HirDatabase) -> Type {
312 let var_id = self.parent.into(); 319 let var_id = self.parent.into();
313 let generic_def_id: GenericDefId = match self.parent { 320 let generic_def_id: GenericDefId = match self.parent {
314 VariantDef::Struct(it) => it.id.into(), 321 VariantDef::Struct(it) => it.id.into(),
@@ -482,6 +489,10 @@ impl Adt {
482 let subst = db.generic_defaults(self.into()); 489 let subst = db.generic_defaults(self.into());
483 subst.iter().any(|ty| ty == &Ty::Unknown) 490 subst.iter().any(|ty| ty == &Ty::Unknown)
484 } 491 }
492
493 /// Turns this ADT into a type. Any type parameters of the ADT will be
494 /// turned into unknown types, which is good for e.g. finding the most
495 /// general set of completions, but will not look very nice when printed.
485 pub fn ty(self, db: &impl HirDatabase) -> Type { 496 pub fn ty(self, db: &impl HirDatabase) -> Type {
486 let id = AdtId::from(self); 497 let id = AdtId::from(self);
487 Type::from_def(db, id.module(db).krate, id) 498 Type::from_def(db, id.module(db).krate, id)
@@ -1028,7 +1039,7 @@ impl Type {
1028 krate: CrateId, 1039 krate: CrateId,
1029 def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>, 1040 def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>,
1030 ) -> Type { 1041 ) -> Type {
1031 let substs = Substs::type_params(db, def); 1042 let substs = Substs::build_for_def(db, def).fill_with_unknown().build();
1032 let ty = db.ty(def.into()).subst(&substs); 1043 let ty = db.ty(def.into()).subst(&substs);
1033 Type::new(db, krate, def, ty) 1044 Type::new(db, krate, def, ty)
1034 } 1045 }
@@ -1288,15 +1299,36 @@ pub enum ScopeDef {
1288 Unknown, 1299 Unknown,
1289} 1300}
1290 1301
1291impl From<PerNs> for ScopeDef { 1302impl ScopeDef {
1292 fn from(def: PerNs) -> Self { 1303 pub fn all_items(def: PerNs) -> ArrayVec<[Self; 3]> {
1293 def.take_types() 1304 let mut items = ArrayVec::new();
1294 .or_else(|| def.take_values()) 1305
1295 .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) 1306 match (def.take_types(), def.take_values()) {
1296 .or_else(|| { 1307 (Some(m1), None) => items.push(ScopeDef::ModuleDef(m1.into())),
1297 def.take_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) 1308 (None, Some(m2)) => items.push(ScopeDef::ModuleDef(m2.into())),
1298 }) 1309 (Some(m1), Some(m2)) => {
1299 .unwrap_or(ScopeDef::Unknown) 1310 // Some items, like unit structs and enum variants, are
1311 // returned as both a type and a value. Here we want
1312 // to de-duplicate them.
1313 if m1 != m2 {
1314 items.push(ScopeDef::ModuleDef(m1.into()));
1315 items.push(ScopeDef::ModuleDef(m2.into()));
1316 } else {
1317 items.push(ScopeDef::ModuleDef(m1.into()));
1318 }
1319 }
1320 (None, None) => {}
1321 };
1322
1323 if let Some(macro_def_id) = def.take_macros() {
1324 items.push(ScopeDef::MacroDef(macro_def_id.into()));
1325 }
1326
1327 if items.is_empty() {
1328 items.push(ScopeDef::Unknown);
1329 }
1330
1331 items
1300 } 1332 }
1301} 1333}
1302 1334
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 3782a9984..788bb3eb7 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -344,7 +344,13 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
344 344
345 resolver.process_all_names(self.db, &mut |name, def| { 345 resolver.process_all_names(self.db, &mut |name, def| {
346 let def = match def { 346 let def = match def {
347 resolver::ScopeDef::PerNs(it) => it.into(), 347 resolver::ScopeDef::PerNs(it) => {
348 let items = ScopeDef::all_items(it);
349 for item in items {
350 f(name.clone(), item);
351 }
352 return;
353 }
348 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), 354 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
349 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), 355 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
350 resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }), 356 resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }),
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index d0459d9b0..db9838cb5 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -102,6 +102,7 @@ struct MacroDirective {
102 module_id: LocalModuleId, 102 module_id: LocalModuleId,
103 ast_id: AstIdWithPath<ast::MacroCall>, 103 ast_id: AstIdWithPath<ast::MacroCall>,
104 legacy: Option<MacroCallId>, 104 legacy: Option<MacroCallId>,
105 depth: usize,
105} 106}
106 107
107#[derive(Clone, Debug, Eq, PartialEq)] 108#[derive(Clone, Debug, Eq, PartialEq)]
@@ -134,6 +135,7 @@ where
134 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; 135 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
135 ModCollector { 136 ModCollector {
136 def_collector: &mut *self, 137 def_collector: &mut *self,
138 macro_depth: 0,
137 module_id, 139 module_id,
138 file_id: file_id.into(), 140 file_id: file_id.into(),
139 raw_items: &raw_items, 141 raw_items: &raw_items,
@@ -516,7 +518,7 @@ where
516 macros.retain(|directive| { 518 macros.retain(|directive| {
517 if let Some(call_id) = directive.legacy { 519 if let Some(call_id) = directive.legacy {
518 res = ReachedFixedPoint::No; 520 res = ReachedFixedPoint::No;
519 resolved.push((directive.module_id, call_id)); 521 resolved.push((directive.module_id, call_id, directive.depth));
520 return false; 522 return false;
521 } 523 }
522 524
@@ -530,7 +532,7 @@ where
530 ); 532 );
531 resolved_res.resolved_def.take_macros() 533 resolved_res.resolved_def.take_macros()
532 }) { 534 }) {
533 resolved.push((directive.module_id, call_id)); 535 resolved.push((directive.module_id, call_id, directive.depth));
534 res = ReachedFixedPoint::No; 536 res = ReachedFixedPoint::No;
535 return false; 537 return false;
536 } 538 }
@@ -541,7 +543,7 @@ where
541 if let Some(call_id) = 543 if let Some(call_id) =
542 directive.ast_id.as_call_id(self.db, |path| self.resolve_attribute_macro(&path)) 544 directive.ast_id.as_call_id(self.db, |path| self.resolve_attribute_macro(&path))
543 { 545 {
544 resolved.push((directive.module_id, call_id)); 546 resolved.push((directive.module_id, call_id, 0));
545 res = ReachedFixedPoint::No; 547 res = ReachedFixedPoint::No;
546 return false; 548 return false;
547 } 549 }
@@ -552,8 +554,12 @@ where
552 self.unexpanded_macros = macros; 554 self.unexpanded_macros = macros;
553 self.unexpanded_attribute_macros = attribute_macros; 555 self.unexpanded_attribute_macros = attribute_macros;
554 556
555 for (module_id, macro_call_id) in resolved { 557 for (module_id, macro_call_id, depth) in resolved {
556 self.collect_macro_expansion(module_id, macro_call_id); 558 if depth > 1024 {
559 log::debug!("Max macro expansion depth reached");
560 continue;
561 }
562 self.collect_macro_expansion(module_id, macro_call_id, depth);
557 } 563 }
558 564
559 res 565 res
@@ -573,12 +579,18 @@ where
573 None 579 None
574 } 580 }
575 581
576 fn collect_macro_expansion(&mut self, module_id: LocalModuleId, macro_call_id: MacroCallId) { 582 fn collect_macro_expansion(
583 &mut self,
584 module_id: LocalModuleId,
585 macro_call_id: MacroCallId,
586 depth: usize,
587 ) {
577 let file_id: HirFileId = macro_call_id.as_file(); 588 let file_id: HirFileId = macro_call_id.as_file();
578 let raw_items = self.db.raw_items(file_id); 589 let raw_items = self.db.raw_items(file_id);
579 let mod_dir = self.mod_dirs[&module_id].clone(); 590 let mod_dir = self.mod_dirs[&module_id].clone();
580 ModCollector { 591 ModCollector {
581 def_collector: &mut *self, 592 def_collector: &mut *self,
593 macro_depth: depth,
582 file_id, 594 file_id,
583 module_id, 595 module_id,
584 raw_items: &raw_items, 596 raw_items: &raw_items,
@@ -595,6 +607,7 @@ where
595/// Walks a single module, populating defs, imports and macros 607/// Walks a single module, populating defs, imports and macros
596struct ModCollector<'a, D> { 608struct ModCollector<'a, D> {
597 def_collector: D, 609 def_collector: D,
610 macro_depth: usize,
598 module_id: LocalModuleId, 611 module_id: LocalModuleId,
599 file_id: HirFileId, 612 file_id: HirFileId,
600 raw_items: &'a raw::RawItems, 613 raw_items: &'a raw::RawItems,
@@ -684,6 +697,7 @@ where
684 697
685 ModCollector { 698 ModCollector {
686 def_collector: &mut *self.def_collector, 699 def_collector: &mut *self.def_collector,
700 macro_depth: self.macro_depth,
687 module_id, 701 module_id,
688 file_id: self.file_id, 702 file_id: self.file_id,
689 raw_items: self.raw_items, 703 raw_items: self.raw_items,
@@ -713,6 +727,7 @@ where
713 let raw_items = self.def_collector.db.raw_items(file_id.into()); 727 let raw_items = self.def_collector.db.raw_items(file_id.into());
714 ModCollector { 728 ModCollector {
715 def_collector: &mut *self.def_collector, 729 def_collector: &mut *self.def_collector,
730 macro_depth: self.macro_depth,
716 module_id, 731 module_id,
717 file_id: file_id.into(), 732 file_id: file_id.into(),
718 raw_items: &raw_items, 733 raw_items: &raw_items,
@@ -887,6 +902,7 @@ where
887 module_id: self.module_id, 902 module_id: self.module_id,
888 ast_id, 903 ast_id,
889 legacy: Some(macro_call_id), 904 legacy: Some(macro_call_id),
905 depth: self.macro_depth + 1,
890 }); 906 });
891 907
892 return; 908 return;
@@ -902,6 +918,7 @@ where
902 module_id: self.module_id, 918 module_id: self.module_id,
903 ast_id, 919 ast_id,
904 legacy: None, 920 legacy: None,
921 depth: self.macro_depth + 1,
905 }); 922 });
906 } 923 }
907 924
@@ -971,13 +988,26 @@ mod tests {
971 } 988 }
972 989
973 #[test] 990 #[test]
974 fn test_macro_expand_will_stop() { 991 fn test_macro_expand_will_stop_1() {
992 do_resolve(
993 r#"
994 macro_rules! foo {
995 ($($ty:ty)*) => { foo!($($ty)*); }
996 }
997 foo!(KABOOM);
998 "#,
999 );
1000 }
1001
1002 #[ignore] // this test does succeed, but takes quite a while :/
1003 #[test]
1004 fn test_macro_expand_will_stop_2() {
975 do_resolve( 1005 do_resolve(
976 r#" 1006 r#"
977 macro_rules! foo { 1007 macro_rules! foo {
978 ($($ty:ty)*) => { foo!($($ty)*, $($ty)*); } 1008 ($($ty:ty)*) => { foo!($($ty)* $($ty)*); }
979 } 1009 }
980foo!(KABOOM); 1010 foo!(KABOOM);
981 "#, 1011 "#,
982 ); 1012 );
983 } 1013 }
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index dda5ed699..3f33a75b9 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -102,6 +102,28 @@ fn crate_def_map_super_super() {
102} 102}
103 103
104#[test] 104#[test]
105fn crate_def_map_fn_mod_same_name() {
106 let map = def_map(
107 "
108 //- /lib.rs
109 mod m {
110 pub mod z {}
111 pub fn z() {}
112 }
113 ",
114 );
115 assert_snapshot!(map, @r###"
116 ⋮crate
117 ⋮m: t
118
119 ⋮crate::m
120 ⋮z: t v
121
122 ⋮crate::m::z
123 "###)
124}
125
126#[test]
105fn bogus_paths() { 127fn bogus_paths() {
106 covers!(bogus_paths); 128 covers!(bogus_paths);
107 let map = def_map( 129 let map = def_map(
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index a90007f26..f9d3787f6 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -88,6 +88,7 @@ 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 // 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,
@@ -151,6 +152,45 @@ fn column_expand(
151 Ok(expanded) 152 Ok(expanded)
152} 153}
153 154
155fn assert_expand(
156 _db: &dyn AstDatabase,
157 _id: LazyMacroId,
158 tt: &tt::Subtree,
159) -> Result<tt::Subtree, mbe::ExpandError> {
160 // A hacky implementation for goto def and hover
161 // We expand `assert!(cond, arg1, arg2)` to
162 // ```
163 // {(cond, &(arg1), &(arg2));}
164 // ```,
165 // which is wrong but useful.
166
167 let mut args = Vec::new();
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<_>>();
187
188 let expanded = quote! {
189 { { (##arg_tts); } }
190 };
191 Ok(expanded)
192}
193
154fn file_expand( 194fn file_expand(
155 _db: &dyn AstDatabase, 195 _db: &dyn AstDatabase,
156 _id: LazyMacroId, 196 _id: LazyMacroId,
@@ -494,6 +534,22 @@ mod tests {
494 } 534 }
495 535
496 #[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]
497 fn test_compile_error_expand() { 553 fn test_compile_error_expand() {
498 let expanded = expand_builtin_macro( 554 let expanded = expand_builtin_macro(
499 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_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index 2b35a3803..39d09a07f 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -544,6 +544,20 @@ fn main() {
544 } 544 }
545 545
546 #[test] 546 #[test]
547 fn generic_struct() {
548 let info = call_info(
549 r#"
550struct TS<T>(T);
551fn main() {
552 let s = TS(<|>);
553}"#,
554 );
555
556 assert_eq!(info.label(), "struct TS<T>(T) -> TS");
557 assert_eq!(info.active_parameter, Some(0));
558 }
559
560 #[test]
547 #[should_panic] 561 #[should_panic]
548 fn cant_call_named_structs() { 562 fn cant_call_named_structs() {
549 let _ = call_info( 563 let _ = call_info(
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs
index 93e53c921..cd0757be5 100644
--- a/crates/ra_ide/src/completion.rs
+++ b/crates/ra_ide/src/completion.rs
@@ -75,9 +75,9 @@ impl Default for CompletionOptions {
75pub(crate) fn completions( 75pub(crate) fn completions(
76 db: &RootDatabase, 76 db: &RootDatabase,
77 position: FilePosition, 77 position: FilePosition,
78 opts: &CompletionOptions, 78 options: &CompletionOptions,
79) -> Option<Completions> { 79) -> Option<Completions> {
80 let ctx = CompletionContext::new(db, position, opts)?; 80 let ctx = CompletionContext::new(db, position, options)?;
81 81
82 let mut acc = Completions::default(); 82 let mut acc = Completions::default();
83 83
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs
index d588ee364..3db17f15f 100644
--- a/crates/ra_ide/src/completion/complete_path.rs
+++ b/crates/ra_ide/src/completion/complete_path.rs
@@ -967,4 +967,74 @@ mod tests {
967 ] 967 ]
968 "###); 968 "###);
969 } 969 }
970
971 #[test]
972 fn function_mod_share_name() {
973 assert_debug_snapshot!(
974 do_reference_completion(
975 r"
976 fn foo() {
977 self::m::<|>
978 }
979
980 mod m {
981 pub mod z {}
982 pub fn z() {}
983 }
984 ",
985 ),
986 @r###"
987 [
988 CompletionItem {
989 label: "z",
990 source_range: [57; 57),
991 delete: [57; 57),
992 insert: "z",
993 kind: Module,
994 },
995 CompletionItem {
996 label: "z()",
997 source_range: [57; 57),
998 delete: [57; 57),
999 insert: "z()$0",
1000 kind: Function,
1001 lookup: "z",
1002 detail: "pub fn z()",
1003 },
1004 ]
1005 "###
1006 );
1007 }
1008
1009 #[test]
1010 fn completes_hashmap_new() {
1011 assert_debug_snapshot!(
1012 do_reference_completion(
1013 r"
1014 struct RandomState;
1015 struct HashMap<K, V, S = RandomState> {}
1016
1017 impl<K, V> HashMap<K, V, RandomState> {
1018 pub fn new() -> HashMap<K, V, RandomState> { }
1019 }
1020 fn foo() {
1021 HashMap::<|>
1022 }
1023 "
1024 ),
1025 @r###"
1026 [
1027 CompletionItem {
1028 label: "new()",
1029 source_range: [292; 292),
1030 delete: [292; 292),
1031 insert: "new()$0",
1032 kind: Function,
1033 lookup: "new",
1034 detail: "pub fn new() -> HashMap<K, V, RandomState>",
1035 },
1036 ]
1037 "###
1038 );
1039 }
970} 1040}
diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs
index bd4adf23a..5ffff5a1c 100644
--- a/crates/ra_ide/src/completion/complete_scope.rs
+++ b/crates/ra_ide/src/completion/complete_scope.rs
@@ -42,6 +42,7 @@ mod tests {
42 kind: Function, 42 kind: Function,
43 lookup: "quux", 43 lookup: "quux",
44 detail: "fn quux(x: i32)", 44 detail: "fn quux(x: i32)",
45 trigger_call_info: true,
45 }, 46 },
46 CompletionItem { 47 CompletionItem {
47 label: "x", 48 label: "x",
@@ -844,6 +845,7 @@ mod tests {
844 kind: Function, 845 kind: Function,
845 lookup: "quux", 846 lookup: "quux",
846 detail: "fn quux(x: i32)", 847 detail: "fn quux(x: i32)",
848 trigger_call_info: true,
847 }, 849 },
848 CompletionItem { 850 CompletionItem {
849 label: "x", 851 label: "x",
@@ -865,4 +867,38 @@ mod tests {
865 "### 867 "###
866 ); 868 );
867 } 869 }
870
871 #[test]
872 fn completes_unresolved_uses() {
873 assert_debug_snapshot!(
874 do_reference_completion(
875 r"
876 use spam::Quux;
877
878 fn main() {
879 <|>
880 }
881 "
882 ),
883 @r###"
884 [
885 CompletionItem {
886 label: "Quux",
887 source_range: [82; 82),
888 delete: [82; 82),
889 insert: "Quux",
890 },
891 CompletionItem {
892 label: "main()",
893 source_range: [82; 82),
894 delete: [82; 82),
895 insert: "main()$0",
896 kind: Function,
897 lookup: "main",
898 detail: "fn main()",
899 },
900 ]
901 "###
902 );
903 }
868} 904}
diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs
index ef0eb43b2..bc0f1aff5 100644
--- a/crates/ra_ide/src/completion/completion_item.rs
+++ b/crates/ra_ide/src/completion/completion_item.rs
@@ -80,6 +80,9 @@ impl fmt::Debug for CompletionItem {
80 if self.deprecated { 80 if self.deprecated {
81 s.field("deprecated", &true); 81 s.field("deprecated", &true);
82 } 82 }
83 if self.trigger_call_info {
84 s.field("trigger_call_info", &true);
85 }
83 s.finish() 86 s.finish()
84 } 87 }
85} 88}
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index 5213def20..910844244 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -273,8 +273,10 @@ impl Completions {
273 pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { 273 pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) {
274 let is_deprecated = is_deprecated(variant, ctx.db); 274 let is_deprecated = is_deprecated(variant, ctx.db);
275 let name = variant.name(ctx.db); 275 let name = variant.name(ctx.db);
276 let detail_types = 276 let detail_types = variant
277 variant.fields(ctx.db).into_iter().map(|field| (field.name(ctx.db), field.ty(ctx.db))); 277 .fields(ctx.db)
278 .into_iter()
279 .map(|field| (field.name(ctx.db), field.signature_ty(ctx.db)));
278 let detail = match variant.kind(ctx.db) { 280 let detail = match variant.kind(ctx.db) {
279 StructKind::Tuple | StructKind::Unit => { 281 StructKind::Tuple | StructKind::Unit => {
280 join(detail_types.map(|(_, t)| t.display(ctx.db).to_string())) 282 join(detail_types.map(|(_, t)| t.display(ctx.db).to_string()))
@@ -510,6 +512,7 @@ mod tests {
510 kind: Function, 512 kind: Function,
511 lookup: "with_args", 513 lookup: "with_args",
512 detail: "fn with_args(x: i32, y: String)", 514 detail: "fn with_args(x: i32, y: String)",
515 trigger_call_info: true,
513 }, 516 },
514 ] 517 ]
515 "### 518 "###
@@ -566,6 +569,7 @@ mod tests {
566 kind: Method, 569 kind: Method,
567 lookup: "foo", 570 lookup: "foo",
568 detail: "fn foo(&self, x: i32)", 571 detail: "fn foo(&self, x: i32)",
572 trigger_call_info: true,
569 }, 573 },
570 ] 574 ]
571 "### 575 "###
@@ -600,6 +604,7 @@ mod tests {
600 kind: Method, 604 kind: Method,
601 lookup: "foo", 605 lookup: "foo",
602 detail: "fn foo(&self, x: i32)", 606 detail: "fn foo(&self, x: i32)",
607 trigger_call_info: true,
603 }, 608 },
604 ] 609 ]
605 "### 610 "###
@@ -718,6 +723,7 @@ mod tests {
718 kind: Function, 723 kind: Function,
719 lookup: "foo", 724 lookup: "foo",
720 detail: "fn foo(xs: Ve)", 725 detail: "fn foo(xs: Ve)",
726 trigger_call_info: true,
721 }, 727 },
722 ] 728 ]
723 "### 729 "###
@@ -747,6 +753,7 @@ mod tests {
747 kind: Function, 753 kind: Function,
748 lookup: "foo", 754 lookup: "foo",
749 detail: "fn foo(xs: Ve)", 755 detail: "fn foo(xs: Ve)",
756 trigger_call_info: true,
750 }, 757 },
751 ] 758 ]
752 "### 759 "###
@@ -775,6 +782,7 @@ mod tests {
775 kind: Function, 782 kind: Function,
776 lookup: "foo", 783 lookup: "foo",
777 detail: "fn foo(xs: Ve)", 784 detail: "fn foo(xs: Ve)",
785 trigger_call_info: true,
778 }, 786 },
779 ] 787 ]
780 "### 788 "###
@@ -803,6 +811,7 @@ mod tests {
803 kind: Function, 811 kind: Function,
804 lookup: "foo", 812 lookup: "foo",
805 detail: "fn foo(xs: Ve<i128>)", 813 detail: "fn foo(xs: Ve<i128>)",
814 trigger_call_info: true,
806 }, 815 },
807 ] 816 ]
808 "### 817 "###
diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs
index 2c4c932de..ec1bbd5a0 100644
--- a/crates/ra_ide/src/display/function_signature.rs
+++ b/crates/ra_ide/src/display/function_signature.rs
@@ -64,7 +64,7 @@ impl FunctionSignature {
64 .fields(db) 64 .fields(db)
65 .into_iter() 65 .into_iter()
66 .map(|field: hir::StructField| { 66 .map(|field: hir::StructField| {
67 let ty = field.ty(db); 67 let ty = field.signature_ty(db);
68 format!("{}", ty.display(db)) 68 format!("{}", ty.display(db))
69 }) 69 })
70 .collect(); 70 .collect();
@@ -102,7 +102,7 @@ impl FunctionSignature {
102 .into_iter() 102 .into_iter()
103 .map(|field: hir::StructField| { 103 .map(|field: hir::StructField| {
104 let name = field.name(db); 104 let name = field.name(db);
105 let ty = field.ty(db); 105 let ty = field.signature_ty(db);
106 format!("{}: {}", name, ty.display(db)) 106 format!("{}: {}", name, ty.display(db))
107 }) 107 })
108 .collect(); 108 .collect();
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/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index cf0cbdbd0..ecd615cf4 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -10,7 +10,20 @@ use ra_syntax::{
10 10
11use crate::{FileId, FunctionSignature}; 11use crate::{FileId, FunctionSignature};
12 12
13#[derive(Debug, PartialEq, Eq)] 13#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct InlayHintsOptions {
15 pub type_hints: bool,
16 pub parameter_hints: bool,
17 pub max_length: Option<usize>,
18}
19
20impl Default for InlayHintsOptions {
21 fn default() -> Self {
22 Self { type_hints: true, parameter_hints: true, max_length: None }
23 }
24}
25
26#[derive(Clone, Debug, PartialEq, Eq)]
14pub enum InlayKind { 27pub enum InlayKind {
15 TypeHint, 28 TypeHint,
16 ParameterHint, 29 ParameterHint,
@@ -26,7 +39,7 @@ pub struct InlayHint {
26pub(crate) fn inlay_hints( 39pub(crate) fn inlay_hints(
27 db: &RootDatabase, 40 db: &RootDatabase,
28 file_id: FileId, 41 file_id: FileId,
29 max_inlay_hint_length: Option<usize>, 42 options: &InlayHintsOptions,
30) -> Vec<InlayHint> { 43) -> Vec<InlayHint> {
31 let _p = profile("inlay_hints"); 44 let _p = profile("inlay_hints");
32 let sema = Semantics::new(db); 45 let sema = Semantics::new(db);
@@ -36,9 +49,9 @@ pub(crate) fn inlay_hints(
36 for node in file.syntax().descendants() { 49 for node in file.syntax().descendants() {
37 match_ast! { 50 match_ast! {
38 match node { 51 match node {
39 ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, ast::Expr::from(it)); }, 52 ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, options, ast::Expr::from(it)); },
40 ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, ast::Expr::from(it)); }, 53 ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, options, ast::Expr::from(it)); },
41 ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, max_inlay_hint_length, it); }, 54 ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, options, it); },
42 _ => (), 55 _ => (),
43 } 56 }
44 } 57 }
@@ -49,8 +62,13 @@ pub(crate) fn inlay_hints(
49fn get_param_name_hints( 62fn get_param_name_hints(
50 acc: &mut Vec<InlayHint>, 63 acc: &mut Vec<InlayHint>,
51 sema: &Semantics<RootDatabase>, 64 sema: &Semantics<RootDatabase>,
65 options: &InlayHintsOptions,
52 expr: ast::Expr, 66 expr: ast::Expr,
53) -> Option<()> { 67) -> Option<()> {
68 if !options.parameter_hints {
69 return None;
70 }
71
54 let args = match &expr { 72 let args = match &expr {
55 ast::Expr::CallExpr(expr) => expr.arg_list()?.args(), 73 ast::Expr::CallExpr(expr) => expr.arg_list()?.args(),
56 ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(), 74 ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(),
@@ -84,9 +102,13 @@ fn get_param_name_hints(
84fn get_bind_pat_hints( 102fn get_bind_pat_hints(
85 acc: &mut Vec<InlayHint>, 103 acc: &mut Vec<InlayHint>,
86 sema: &Semantics<RootDatabase>, 104 sema: &Semantics<RootDatabase>,
87 max_inlay_hint_length: Option<usize>, 105 options: &InlayHintsOptions,
88 pat: ast::BindPat, 106 pat: ast::BindPat,
89) -> Option<()> { 107) -> Option<()> {
108 if !options.type_hints {
109 return None;
110 }
111
90 let ty = sema.type_of_pat(&pat.clone().into())?; 112 let ty = sema.type_of_pat(&pat.clone().into())?;
91 113
92 if should_not_display_type_hint(sema.db, &pat, &ty) { 114 if should_not_display_type_hint(sema.db, &pat, &ty) {
@@ -96,7 +118,7 @@ fn get_bind_pat_hints(
96 acc.push(InlayHint { 118 acc.push(InlayHint {
97 range: pat.syntax().text_range(), 119 range: pat.syntax().text_range(),
98 kind: InlayKind::TypeHint, 120 kind: InlayKind::TypeHint,
99 label: ty.display_truncated(sema.db, max_inlay_hint_length).to_string().into(), 121 label: ty.display_truncated(sema.db, options.max_length).to_string().into(),
100 }); 122 });
101 Some(()) 123 Some(())
102} 124}
@@ -202,11 +224,66 @@ fn get_fn_signature(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<
202 224
203#[cfg(test)] 225#[cfg(test)]
204mod tests { 226mod tests {
227 use crate::inlay_hints::InlayHintsOptions;
205 use insta::assert_debug_snapshot; 228 use insta::assert_debug_snapshot;
206 229
207 use crate::mock_analysis::single_file; 230 use crate::mock_analysis::single_file;
208 231
209 #[test] 232 #[test]
233 fn param_hints_only() {
234 let (analysis, file_id) = single_file(
235 r#"
236 fn foo(a: i32, b: i32) -> i32 { a + b }
237 fn main() {
238 let _x = foo(4, 4);
239 }"#,
240 );
241 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ parameter_hints: true, type_hints: false, max_length: None}).unwrap(), @r###"
242 [
243 InlayHint {
244 range: [106; 107),
245 kind: ParameterHint,
246 label: "a",
247 },
248 InlayHint {
249 range: [109; 110),
250 kind: ParameterHint,
251 label: "b",
252 },
253 ]"###);
254 }
255
256 #[test]
257 fn hints_disabled() {
258 let (analysis, file_id) = single_file(
259 r#"
260 fn foo(a: i32, b: i32) -> i32 { a + b }
261 fn main() {
262 let _x = foo(4, 4);
263 }"#,
264 );
265 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ type_hints: false, parameter_hints: false, max_length: None}).unwrap(), @r###"[]"###);
266 }
267
268 #[test]
269 fn type_hints_only() {
270 let (analysis, file_id) = single_file(
271 r#"
272 fn foo(a: i32, b: i32) -> i32 { a + b }
273 fn main() {
274 let _x = foo(4, 4);
275 }"#,
276 );
277 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ type_hints: true, parameter_hints: false, max_length: None}).unwrap(), @r###"
278 [
279 InlayHint {
280 range: [97; 99),
281 kind: TypeHint,
282 label: "i32",
283 },
284 ]"###);
285 }
286 #[test]
210 fn default_generic_types_should_not_be_displayed() { 287 fn default_generic_types_should_not_be_displayed() {
211 let (analysis, file_id) = single_file( 288 let (analysis, file_id) = single_file(
212 r#" 289 r#"
@@ -221,7 +298,7 @@ fn main() {
221}"#, 298}"#,
222 ); 299 );
223 300
224 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 301 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
225 [ 302 [
226 InlayHint { 303 InlayHint {
227 range: [69; 71), 304 range: [69; 71),
@@ -278,7 +355,7 @@ fn main() {
278}"#, 355}"#,
279 ); 356 );
280 357
281 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 358 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
282 [ 359 [
283 InlayHint { 360 InlayHint {
284 range: [193; 197), 361 range: [193; 197),
@@ -358,7 +435,7 @@ fn main() {
358}"#, 435}"#,
359 ); 436 );
360 437
361 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 438 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
362 [ 439 [
363 InlayHint { 440 InlayHint {
364 range: [21; 30), 441 range: [21; 30),
@@ -422,7 +499,7 @@ fn main() {
422}"#, 499}"#,
423 ); 500 );
424 501
425 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 502 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
426 [ 503 [
427 InlayHint { 504 InlayHint {
428 range: [21; 30), 505 range: [21; 30),
@@ -472,7 +549,7 @@ fn main() {
472}"#, 549}"#,
473 ); 550 );
474 551
475 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 552 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
476 [ 553 [
477 InlayHint { 554 InlayHint {
478 range: [188; 192), 555 range: [188; 192),
@@ -567,7 +644,7 @@ fn main() {
567}"#, 644}"#,
568 ); 645 );
569 646
570 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 647 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
571 [ 648 [
572 InlayHint { 649 InlayHint {
573 range: [188; 192), 650 range: [188; 192),
@@ -662,7 +739,7 @@ fn main() {
662}"#, 739}"#,
663 ); 740 );
664 741
665 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 742 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
666 [ 743 [
667 InlayHint { 744 InlayHint {
668 range: [252; 256), 745 range: [252; 256),
@@ -734,7 +811,7 @@ fn main() {
734}"#, 811}"#,
735 ); 812 );
736 813
737 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 814 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
738 [ 815 [
739 InlayHint { 816 InlayHint {
740 range: [74; 75), 817 range: [74; 75),
@@ -822,7 +899,7 @@ fn main() {
822}"#, 899}"#,
823 ); 900 );
824 901
825 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 902 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
826 [ 903 [
827 InlayHint { 904 InlayHint {
828 range: [798; 809), 905 range: [798; 809),
@@ -944,7 +1021,7 @@ fn main() {
944}"#, 1021}"#,
945 ); 1022 );
946 1023
947 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 1024 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
948 [] 1025 []
949 "### 1026 "###
950 ); 1027 );
@@ -970,7 +1047,7 @@ fn main() {
970}"#, 1047}"#,
971 ); 1048 );
972 1049
973 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 1050 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
974 [] 1051 []
975 "### 1052 "###
976 ); 1053 );
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 015fae195..e9af80b6c 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -68,7 +68,7 @@ pub use crate::{
68 expand_macro::ExpandedMacro, 68 expand_macro::ExpandedMacro,
69 folding_ranges::{Fold, FoldKind}, 69 folding_ranges::{Fold, FoldKind},
70 hover::HoverResult, 70 hover::HoverResult,
71 inlay_hints::{InlayHint, InlayKind}, 71 inlay_hints::{InlayHint, InlayHintsOptions, InlayKind},
72 references::{Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult}, 72 references::{Declaration, Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult},
73 runnables::{Runnable, RunnableKind, TestId}, 73 runnables::{Runnable, RunnableKind, TestId},
74 source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, 74 source_change::{FileSystemEdit, SourceChange, SourceFileEdit},
@@ -319,9 +319,9 @@ impl Analysis {
319 pub fn inlay_hints( 319 pub fn inlay_hints(
320 &self, 320 &self,
321 file_id: FileId, 321 file_id: FileId,
322 max_inlay_hint_length: Option<usize>, 322 inlay_hint_opts: &InlayHintsOptions,
323 ) -> Cancelable<Vec<InlayHint>> { 323 ) -> Cancelable<Vec<InlayHint>> {
324 self.with_db(|db| inlay_hints::inlay_hints(db, file_id, max_inlay_hint_length)) 324 self.with_db(|db| inlay_hints::inlay_hints(db, file_id, inlay_hint_opts))
325 } 325 }
326 326
327 /// Returns the set of folding ranges. 327 /// Returns the set of folding ranges.
diff --git a/crates/ra_ide/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs
index 55966daf3..f58e436d1 100644
--- a/crates/ra_ide/src/syntax_tree.rs
+++ b/crates/ra_ide/src/syntax_tree.rs
@@ -5,7 +5,7 @@ use ra_ide_db::RootDatabase;
5use ra_syntax::{ 5use ra_syntax::{
6 algo, AstNode, NodeOrToken, SourceFile, 6 algo, AstNode, NodeOrToken, SourceFile,
7 SyntaxKind::{RAW_STRING, STRING}, 7 SyntaxKind::{RAW_STRING, STRING},
8 SyntaxToken, TextRange, 8 SyntaxToken, TextRange, TextUnit,
9}; 9};
10 10
11pub use ra_db::FileId; 11pub use ra_db::FileId;
@@ -56,19 +56,23 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<St
56 let start = text_range.start() - node_range.start(); 56 let start = text_range.start() - node_range.start();
57 57
58 // how many characters we have selected 58 // how many characters we have selected
59 let len = text_range.len().to_usize(); 59 let len = text_range.len();
60 60
61 let node_len = node_range.len().to_usize(); 61 let node_len = node_range.len();
62 62
63 let start = start.to_usize(); 63 let start = start;
64 64
65 // We want to cap our length 65 // We want to cap our length
66 let len = len.min(node_len); 66 let len = len.min(node_len);
67 67
68 // Ensure our slice is inside the actual string 68 // Ensure our slice is inside the actual string
69 let end = if start + len < text.len() { start + len } else { text.len() - start }; 69 let end = if start + len < TextUnit::of_str(&text) {
70 start + len
71 } else {
72 TextUnit::of_str(&text) - start
73 };
70 74
71 let text = &text[start..end]; 75 let text = &text[TextRange::from_to(start, end)];
72 76
73 // Remove possible extra string quotes from the start 77 // Remove possible extra string quotes from the start
74 // and the end of the string 78 // and the end of the string
diff --git a/crates/ra_ide_db/src/line_index.rs b/crates/ra_ide_db/src/line_index.rs
index b9db5c276..8ae745ff2 100644
--- a/crates/ra_ide_db/src/line_index.rs
+++ b/crates/ra_ide_db/src/line_index.rs
@@ -59,7 +59,7 @@ impl LineIndex {
59 } 59 }
60 60
61 let char_len = TextUnit::of_char(c); 61 let char_len = TextUnit::of_char(c);
62 if char_len.to_usize() > 1 { 62 if char_len > TextUnit::from_usize(1) {
63 utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + char_len }); 63 utf16_chars.push(Utf16Char { start: curr_col, end: curr_col + char_len });
64 } 64 }
65 65
@@ -101,12 +101,12 @@ impl LineIndex {
101 .filter(|it| !it.is_empty()) 101 .filter(|it| !it.is_empty())
102 } 102 }
103 103
104 fn utf8_to_utf16_col(&self, line: u32, mut col: TextUnit) -> usize { 104 fn utf8_to_utf16_col(&self, line: u32, col: TextUnit) -> usize {
105 if let Some(utf16_chars) = self.utf16_lines.get(&line) { 105 if let Some(utf16_chars) = self.utf16_lines.get(&line) {
106 let mut correction = TextUnit::from_usize(0); 106 let mut correction = 0;
107 for c in utf16_chars { 107 for c in utf16_chars {
108 if col >= c.end { 108 if col >= c.end {
109 correction += c.len() - TextUnit::from_usize(1); 109 correction += c.len().to_usize() - 1;
110 } else { 110 } else {
111 // From here on, all utf16 characters come *after* the character we are mapping, 111 // From here on, all utf16 characters come *after* the character we are mapping,
112 // so we don't need to take them into account 112 // so we don't need to take them into account
@@ -114,10 +114,10 @@ impl LineIndex {
114 } 114 }
115 } 115 }
116 116
117 col -= correction; 117 col.to_usize() - correction
118 } else {
119 col.to_usize()
118 } 120 }
119
120 col.to_usize()
121 } 121 }
122 122
123 fn utf16_to_utf8_col(&self, line: u32, col: u32) -> TextUnit { 123 fn utf16_to_utf8_col(&self, line: u32, col: u32) -> TextUnit {
diff --git a/crates/ra_ide_db/src/line_index_utils.rs b/crates/ra_ide_db/src/line_index_utils.rs
index 75a498151..2ebbabdc6 100644
--- a/crates/ra_ide_db/src/line_index_utils.rs
+++ b/crates/ra_ide_db/src/line_index_utils.rs
@@ -145,7 +145,7 @@ impl Iterator for OffsetStepIter<'_> {
145 Some((next, next_offset)) 145 Some((next, next_offset))
146 } else { 146 } else {
147 let char_len = TextUnit::of_char(c); 147 let char_len = TextUnit::of_char(c);
148 if char_len.to_usize() > 1 { 148 if char_len > TextUnit::from_usize(1) {
149 let start = self.offset + TextUnit::from_usize(i); 149 let start = self.offset + TextUnit::from_usize(i);
150 let end = start + char_len; 150 let end = start + char_len;
151 let next = Step::Utf16Char(TextRange::from_to(start, end)); 151 let next = Step::Utf16Char(TextRange::from_to(start, end));
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs
index 272661b1d..f0da173cc 100644
--- a/crates/ra_parser/src/grammar/params.rs
+++ b/crates/ra_parser/src/grammar/params.rs
@@ -56,21 +56,17 @@ fn list_(p: &mut Parser, flavor: Flavor) {
56 // fn f(#[attr1] pat: Type) {} 56 // fn f(#[attr1] pat: Type) {}
57 attributes::outer_attributes(p); 57 attributes::outer_attributes(p);
58 58
59 // test param_list_vararg
60 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
61 match flavor {
62 FnDef | FnPointer if p.eat(T![...]) => break,
63 _ => (),
64 }
65
66 if !p.at_ts(VALUE_PARAMETER_FIRST) { 59 if !p.at_ts(VALUE_PARAMETER_FIRST) {
67 p.error("expected value parameter"); 60 p.error("expected value parameter");
68 break; 61 break;
69 } 62 }
70 value_parameter(p, flavor); 63 let param = value_parameter(p, flavor);
71 if !p.at(ket) { 64 if !p.at(ket) {
72 p.expect(T![,]); 65 p.expect(T![,]);
73 } 66 }
67 if let Variadic(true) = param {
68 break;
69 }
74 } 70 }
75 71
76 p.expect(ket); 72 p.expect(ket);
@@ -79,32 +75,25 @@ fn list_(p: &mut Parser, flavor: Flavor) {
79 75
80const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST); 76const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
81 77
82fn value_parameter(p: &mut Parser, flavor: Flavor) { 78struct Variadic(bool);
79
80fn value_parameter(p: &mut Parser, flavor: Flavor) -> Variadic {
81 let mut res = Variadic(false);
83 let m = p.start(); 82 let m = p.start();
84 match flavor { 83 match flavor {
85 // test trait_fn_placeholder_parameter 84 // test param_list_vararg
86 // trait Foo { 85 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
87 // fn bar(_: u64, mut x: i32); 86 Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => res = Variadic(true),
88 // }
89
90 // test trait_fn_patterns
91 // trait T {
92 // fn f1((a, b): (usize, usize)) {}
93 // fn f2(S { a, b }: S) {}
94 // fn f3(NewType(a): NewType) {}
95 // fn f4(&&a: &&usize) {}
96 // }
97 87
98 // test fn_patterns 88 // test fn_def_param
99 // impl U { 89 // fn foo((x, y): (i32, i32)) {}
100 // fn f1((a, b): (usize, usize)) {}
101 // fn f2(S { a, b }: S) {}
102 // fn f3(NewType(a): NewType) {}
103 // fn f4(&&a: &&usize) {}
104 // }
105 Flavor::FnDef => { 90 Flavor::FnDef => {
106 patterns::pattern(p); 91 patterns::pattern(p);
107 types::ascription(p); 92 if variadic_param(p) {
93 res = Variadic(true)
94 } else {
95 types::ascription(p);
96 }
108 } 97 }
109 // test value_parameters_no_patterns 98 // test value_parameters_no_patterns
110 // type F = Box<Fn(i32, &i32, &i32, ())>; 99 // type F = Box<Fn(i32, &i32, &i32, ())>;
@@ -120,7 +109,11 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
120 Flavor::FnPointer => { 109 Flavor::FnPointer => {
121 if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { 110 if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
122 patterns::pattern_single(p); 111 patterns::pattern_single(p);
123 types::ascription(p); 112 if variadic_param(p) {
113 res = Variadic(true)
114 } else {
115 types::ascription(p);
116 }
124 } else { 117 } else {
125 types::type_(p); 118 types::type_(p);
126 } 119 }
@@ -137,6 +130,17 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
137 } 130 }
138 } 131 }
139 m.complete(p, PARAM); 132 m.complete(p, PARAM);
133 res
134}
135
136fn variadic_param(p: &mut Parser) -> bool {
137 if p.at(T![:]) && p.nth_at(1, T![...]) {
138 p.bump(T![:]);
139 p.bump(T![...]);
140 true
141 } else {
142 false
143 }
140} 144}
141 145
142// test self_param 146// test self_param
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.
33pub trait AstNode { 33pub 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::{
9pub struct SourceFile { 9pub struct SourceFile {
10 pub(crate) syntax: SyntaxNode, 10 pub(crate) syntax: SyntaxNode,
11} 11}
12impl 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}
12impl AstNode for SourceFile { 17impl 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 {
38pub struct FnDef { 43pub struct FnDef {
39 pub(crate) syntax: SyntaxNode, 44 pub(crate) syntax: SyntaxNode,
40} 45}
46impl 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}
41impl AstNode for FnDef { 51impl 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 {
76pub struct RetType { 86pub struct RetType {
77 pub(crate) syntax: SyntaxNode, 87 pub(crate) syntax: SyntaxNode,
78} 88}
89impl 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}
79impl AstNode for RetType { 94impl 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 {
103pub struct StructDef { 118pub struct StructDef {
104 pub(crate) syntax: SyntaxNode, 119 pub(crate) syntax: SyntaxNode,
105} 120}
121impl 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}
106impl AstNode for StructDef { 126impl 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 {}
131pub struct UnionDef { 151pub struct UnionDef {
132 pub(crate) syntax: SyntaxNode, 152 pub(crate) syntax: SyntaxNode,
133} 153}
154impl 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}
134impl AstNode for UnionDef { 159impl 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 {
163pub struct RecordFieldDefList { 188pub struct RecordFieldDefList {
164 pub(crate) syntax: SyntaxNode, 189 pub(crate) syntax: SyntaxNode,
165} 190}
191impl 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}
166impl AstNode for RecordFieldDefList { 196impl 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 {
190pub struct RecordFieldDef { 220pub struct RecordFieldDef {
191 pub(crate) syntax: SyntaxNode, 221 pub(crate) syntax: SyntaxNode,
192} 222}
223impl 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}
193impl AstNode for RecordFieldDef { 228impl 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 {}
218pub struct TupleFieldDefList { 253pub struct TupleFieldDefList {
219 pub(crate) syntax: SyntaxNode, 254 pub(crate) syntax: SyntaxNode,
220} 255}
256impl 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}
221impl AstNode for TupleFieldDefList { 261impl 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 {
245pub struct TupleFieldDef { 285pub struct TupleFieldDef {
246 pub(crate) syntax: SyntaxNode, 286 pub(crate) syntax: SyntaxNode,
247} 287}
288impl 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}
248impl AstNode for TupleFieldDef { 293impl 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 {
274pub struct EnumDef { 319pub struct EnumDef {
275 pub(crate) syntax: SyntaxNode, 320 pub(crate) syntax: SyntaxNode,
276} 321}
322impl 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}
277impl AstNode for EnumDef { 327impl 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 {
306pub struct EnumVariantList { 356pub struct EnumVariantList {
307 pub(crate) syntax: SyntaxNode, 357 pub(crate) syntax: SyntaxNode,
308} 358}
359impl 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}
309impl AstNode for EnumVariantList { 364impl 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 {
333pub struct EnumVariant { 388pub struct EnumVariant {
334 pub(crate) syntax: SyntaxNode, 389 pub(crate) syntax: SyntaxNode,
335} 390}
391impl 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}
336impl AstNode for EnumVariant { 396impl 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 {
363pub struct TraitDef { 423pub struct TraitDef {
364 pub(crate) syntax: SyntaxNode, 424 pub(crate) syntax: SyntaxNode,
365} 425}
426impl 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}
366impl AstNode for TraitDef { 431impl 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 {
396pub struct Module { 461pub struct Module {
397 pub(crate) syntax: SyntaxNode, 462 pub(crate) syntax: SyntaxNode,
398} 463}
464impl 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}
399impl AstNode for Module { 469impl 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 {
427pub struct ItemList { 497pub struct ItemList {
428 pub(crate) syntax: SyntaxNode, 498 pub(crate) syntax: SyntaxNode,
429} 499}
500impl 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}
430impl AstNode for ItemList { 505impl 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 {
456pub struct ConstDef { 531pub struct ConstDef {
457 pub(crate) syntax: SyntaxNode, 532 pub(crate) syntax: SyntaxNode,
458} 533}
534impl 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}
459impl AstNode for ConstDef { 539impl 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 {
489pub struct StaticDef { 569pub struct StaticDef {
490 pub(crate) syntax: SyntaxNode, 570 pub(crate) syntax: SyntaxNode,
491} 571}
572impl 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}
492impl AstNode for StaticDef { 577impl 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 {
522pub struct TypeAliasDef { 607pub struct TypeAliasDef {
523 pub(crate) syntax: SyntaxNode, 608 pub(crate) syntax: SyntaxNode,
524} 609}
610impl 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}
525impl AstNode for TypeAliasDef { 615impl 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 {
555pub struct ImplDef { 645pub struct ImplDef {
556 pub(crate) syntax: SyntaxNode, 646 pub(crate) syntax: SyntaxNode,
557} 647}
648impl 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}
558impl AstNode for ImplDef { 653impl 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 {
584pub struct ParenType { 679pub struct ParenType {
585 pub(crate) syntax: SyntaxNode, 680 pub(crate) syntax: SyntaxNode,
586} 681}
682impl 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}
587impl AstNode for ParenType { 687impl 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 {
611pub struct TupleType { 711pub struct TupleType {
612 pub(crate) syntax: SyntaxNode, 712 pub(crate) syntax: SyntaxNode,
613} 713}
714impl 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}
614impl AstNode for TupleType { 719impl 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 {
638pub struct NeverType { 743pub struct NeverType {
639 pub(crate) syntax: SyntaxNode, 744 pub(crate) syntax: SyntaxNode,
640} 745}
746impl 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}
641impl AstNode for NeverType { 751impl 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 {}
661pub struct PathType { 771pub struct PathType {
662 pub(crate) syntax: SyntaxNode, 772 pub(crate) syntax: SyntaxNode,
663} 773}
774impl 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}
664impl AstNode for PathType { 779impl 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 {
688pub struct PointerType { 803pub struct PointerType {
689 pub(crate) syntax: SyntaxNode, 804 pub(crate) syntax: SyntaxNode,
690} 805}
806impl 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}
691impl AstNode for PointerType { 811impl 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 {
715pub struct ArrayType { 835pub struct ArrayType {
716 pub(crate) syntax: SyntaxNode, 836 pub(crate) syntax: SyntaxNode,
717} 837}
838impl 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}
718impl AstNode for ArrayType { 843impl 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 {
745pub struct SliceType { 870pub struct SliceType {
746 pub(crate) syntax: SyntaxNode, 871 pub(crate) syntax: SyntaxNode,
747} 872}
873impl 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}
748impl AstNode for SliceType { 878impl 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 {
772pub struct ReferenceType { 902pub struct ReferenceType {
773 pub(crate) syntax: SyntaxNode, 903 pub(crate) syntax: SyntaxNode,
774} 904}
905impl 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}
775impl AstNode for ReferenceType { 910impl 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 {
799pub struct PlaceholderType { 934pub struct PlaceholderType {
800 pub(crate) syntax: SyntaxNode, 935 pub(crate) syntax: SyntaxNode,
801} 936}
937impl 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}
802impl AstNode for PlaceholderType { 942impl 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 {}
822pub struct FnPointerType { 962pub struct FnPointerType {
823 pub(crate) syntax: SyntaxNode, 963 pub(crate) syntax: SyntaxNode,
824} 964}
965impl 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}
825impl AstNode for FnPointerType { 970impl 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 {
852pub struct ForType { 997pub struct ForType {
853 pub(crate) syntax: SyntaxNode, 998 pub(crate) syntax: SyntaxNode,
854} 999}
1000impl 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}
855impl AstNode for ForType { 1005impl 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 {
879pub struct ImplTraitType { 1029pub struct ImplTraitType {
880 pub(crate) syntax: SyntaxNode, 1030 pub(crate) syntax: SyntaxNode,
881} 1031}
1032impl 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}
882impl AstNode for ImplTraitType { 1037impl 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 {}
903pub struct DynTraitType { 1058pub struct DynTraitType {
904 pub(crate) syntax: SyntaxNode, 1059 pub(crate) syntax: SyntaxNode,
905} 1060}
1061impl 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}
906impl AstNode for DynTraitType { 1066impl 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 {}
927pub struct TupleExpr { 1087pub struct TupleExpr {
928 pub(crate) syntax: SyntaxNode, 1088 pub(crate) syntax: SyntaxNode,
929} 1089}
1090impl 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}
930impl AstNode for TupleExpr { 1095impl 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 {
954pub struct ArrayExpr { 1119pub struct ArrayExpr {
955 pub(crate) syntax: SyntaxNode, 1120 pub(crate) syntax: SyntaxNode,
956} 1121}
1122impl 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}
957impl AstNode for ArrayExpr { 1127impl 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 {
981pub struct ParenExpr { 1151pub struct ParenExpr {
982 pub(crate) syntax: SyntaxNode, 1152 pub(crate) syntax: SyntaxNode,
983} 1153}
1154impl 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}
984impl AstNode for ParenExpr { 1159impl 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 {
1008pub struct PathExpr { 1183pub struct PathExpr {
1009 pub(crate) syntax: SyntaxNode, 1184 pub(crate) syntax: SyntaxNode,
1010} 1185}
1186impl 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}
1011impl AstNode for PathExpr { 1191impl 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 {
1035pub struct LambdaExpr { 1215pub struct LambdaExpr {
1036 pub(crate) syntax: SyntaxNode, 1216 pub(crate) syntax: SyntaxNode,
1037} 1217}
1218impl 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}
1038impl AstNode for LambdaExpr { 1223impl 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 {
1068pub struct IfExpr { 1253pub struct IfExpr {
1069 pub(crate) syntax: SyntaxNode, 1254 pub(crate) syntax: SyntaxNode,
1070} 1255}
1256impl 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}
1071impl AstNode for IfExpr { 1261impl 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 {
1095pub struct LoopExpr { 1285pub struct LoopExpr {
1096 pub(crate) syntax: SyntaxNode, 1286 pub(crate) syntax: SyntaxNode,
1097} 1287}
1288impl 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}
1098impl AstNode for LoopExpr { 1293impl 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 {}
1119pub struct TryBlockExpr { 1314pub struct TryBlockExpr {
1120 pub(crate) syntax: SyntaxNode, 1315 pub(crate) syntax: SyntaxNode,
1121} 1316}
1317impl 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}
1122impl AstNode for TryBlockExpr { 1322impl 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 {
1146pub struct ForExpr { 1346pub struct ForExpr {
1147 pub(crate) syntax: SyntaxNode, 1347 pub(crate) syntax: SyntaxNode,
1148} 1348}
1349impl 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}
1149impl AstNode for ForExpr { 1354impl 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 {
1177pub struct WhileExpr { 1382pub struct WhileExpr {
1178 pub(crate) syntax: SyntaxNode, 1383 pub(crate) syntax: SyntaxNode,
1179} 1384}
1385impl 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}
1180impl AstNode for WhileExpr { 1390impl 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 {
1205pub struct ContinueExpr { 1415pub struct ContinueExpr {
1206 pub(crate) syntax: SyntaxNode, 1416 pub(crate) syntax: SyntaxNode,
1207} 1417}
1418impl 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}
1208impl AstNode for ContinueExpr { 1423impl 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 {}
1228pub struct BreakExpr { 1443pub struct BreakExpr {
1229 pub(crate) syntax: SyntaxNode, 1444 pub(crate) syntax: SyntaxNode,
1230} 1445}
1446impl 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}
1231impl AstNode for BreakExpr { 1451impl 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 {
1255pub struct Label { 1475pub struct Label {
1256 pub(crate) syntax: SyntaxNode, 1476 pub(crate) syntax: SyntaxNode,
1257} 1477}
1478impl 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}
1258impl AstNode for Label { 1483impl 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 {}
1278pub struct BlockExpr { 1503pub struct BlockExpr {
1279 pub(crate) syntax: SyntaxNode, 1504 pub(crate) syntax: SyntaxNode,
1280} 1505}
1506impl 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}
1281impl AstNode for BlockExpr { 1511impl 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 {
1305pub struct ReturnExpr { 1535pub struct ReturnExpr {
1306 pub(crate) syntax: SyntaxNode, 1536 pub(crate) syntax: SyntaxNode,
1307} 1537}
1538impl 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}
1308impl AstNode for ReturnExpr { 1543impl 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 {
1332pub struct CallExpr { 1567pub struct CallExpr {
1333 pub(crate) syntax: SyntaxNode, 1568 pub(crate) syntax: SyntaxNode,
1334} 1569}
1570impl 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}
1335impl AstNode for CallExpr { 1575impl 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 {
1360pub struct MethodCallExpr { 1600pub struct MethodCallExpr {
1361 pub(crate) syntax: SyntaxNode, 1601 pub(crate) syntax: SyntaxNode,
1362} 1602}
1603impl 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}
1363impl AstNode for MethodCallExpr { 1608impl 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 {
1394pub struct IndexExpr { 1639pub struct IndexExpr {
1395 pub(crate) syntax: SyntaxNode, 1640 pub(crate) syntax: SyntaxNode,
1396} 1641}
1642impl 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}
1397impl AstNode for IndexExpr { 1647impl 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 {}
1417pub struct FieldExpr { 1667pub struct FieldExpr {
1418 pub(crate) syntax: SyntaxNode, 1668 pub(crate) syntax: SyntaxNode,
1419} 1669}
1670impl 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}
1420impl AstNode for FieldExpr { 1675impl 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 {
1447pub struct AwaitExpr { 1702pub struct AwaitExpr {
1448 pub(crate) syntax: SyntaxNode, 1703 pub(crate) syntax: SyntaxNode,
1449} 1704}
1705impl 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}
1450impl AstNode for AwaitExpr { 1710impl 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 {
1474pub struct TryExpr { 1734pub struct TryExpr {
1475 pub(crate) syntax: SyntaxNode, 1735 pub(crate) syntax: SyntaxNode,
1476} 1736}
1737impl 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}
1477impl AstNode for TryExpr { 1742impl 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 {
1501pub struct CastExpr { 1766pub struct CastExpr {
1502 pub(crate) syntax: SyntaxNode, 1767 pub(crate) syntax: SyntaxNode,
1503} 1768}
1769impl 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}
1504impl AstNode for CastExpr { 1774impl 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 {
1531pub struct RefExpr { 1801pub struct RefExpr {
1532 pub(crate) syntax: SyntaxNode, 1802 pub(crate) syntax: SyntaxNode,
1533} 1803}
1804impl 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}
1534impl AstNode for RefExpr { 1809impl 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 {
1558pub struct PrefixExpr { 1833pub struct PrefixExpr {
1559 pub(crate) syntax: SyntaxNode, 1834 pub(crate) syntax: SyntaxNode,
1560} 1835}
1836impl 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}
1561impl AstNode for PrefixExpr { 1841impl 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 {
1585pub struct BoxExpr { 1865pub struct BoxExpr {
1586 pub(crate) syntax: SyntaxNode, 1866 pub(crate) syntax: SyntaxNode,
1587} 1867}
1868impl 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}
1588impl AstNode for BoxExpr { 1873impl 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 {
1612pub struct RangeExpr { 1897pub struct RangeExpr {
1613 pub(crate) syntax: SyntaxNode, 1898 pub(crate) syntax: SyntaxNode,
1614} 1899}
1900impl 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}
1615impl AstNode for RangeExpr { 1905impl 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 {}
1635pub struct BinExpr { 1925pub struct BinExpr {
1636 pub(crate) syntax: SyntaxNode, 1926 pub(crate) syntax: SyntaxNode,
1637} 1927}
1928impl 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}
1638impl AstNode for BinExpr { 1933impl 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 {}
1658pub struct Literal { 1953pub struct Literal {
1659 pub(crate) syntax: SyntaxNode, 1954 pub(crate) syntax: SyntaxNode,
1660} 1955}
1956impl 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}
1661impl AstNode for Literal { 1961impl 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 {}
1681pub struct MatchExpr { 1981pub struct MatchExpr {
1682 pub(crate) syntax: SyntaxNode, 1982 pub(crate) syntax: SyntaxNode,
1683} 1983}
1984impl 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}
1684impl AstNode for MatchExpr { 1989impl 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 {
1711pub struct MatchArmList { 2016pub struct MatchArmList {
1712 pub(crate) syntax: SyntaxNode, 2017 pub(crate) syntax: SyntaxNode,
1713} 2018}
2019impl 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}
1714impl AstNode for MatchArmList { 2024impl 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 {
1739pub struct MatchArm { 2049pub struct MatchArm {
1740 pub(crate) syntax: SyntaxNode, 2050 pub(crate) syntax: SyntaxNode,
1741} 2051}
2052impl 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}
1742impl AstNode for MatchArm { 2057impl 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 {
1773pub struct MatchGuard { 2088pub struct MatchGuard {
1774 pub(crate) syntax: SyntaxNode, 2089 pub(crate) syntax: SyntaxNode,
1775} 2090}
2091impl 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}
1776impl AstNode for MatchGuard { 2096impl 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 {
1800pub struct RecordLit { 2120pub struct RecordLit {
1801 pub(crate) syntax: SyntaxNode, 2121 pub(crate) syntax: SyntaxNode,
1802} 2122}
2123impl 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}
1803impl AstNode for RecordLit { 2128impl 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 {
1830pub struct RecordFieldList { 2155pub struct RecordFieldList {
1831 pub(crate) syntax: SyntaxNode, 2156 pub(crate) syntax: SyntaxNode,
1832} 2157}
2158impl 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}
1833impl AstNode for RecordFieldList { 2163impl 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 {
1860pub struct RecordField { 2190pub struct RecordField {
1861 pub(crate) syntax: SyntaxNode, 2191 pub(crate) syntax: SyntaxNode,
1862} 2192}
2193impl 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}
1863impl AstNode for RecordField { 2198impl 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 {
1890pub struct OrPat { 2225pub struct OrPat {
1891 pub(crate) syntax: SyntaxNode, 2226 pub(crate) syntax: SyntaxNode,
1892} 2227}
2228impl 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}
1893impl AstNode for OrPat { 2233impl 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 {
1917pub struct ParenPat { 2257pub struct ParenPat {
1918 pub(crate) syntax: SyntaxNode, 2258 pub(crate) syntax: SyntaxNode,
1919} 2259}
2260impl 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}
1920impl AstNode for ParenPat { 2265impl 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 {
1944pub struct RefPat { 2289pub struct RefPat {
1945 pub(crate) syntax: SyntaxNode, 2290 pub(crate) syntax: SyntaxNode,
1946} 2291}
2292impl 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}
1947impl AstNode for RefPat { 2297impl 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 {
1971pub struct BoxPat { 2321pub struct BoxPat {
1972 pub(crate) syntax: SyntaxNode, 2322 pub(crate) syntax: SyntaxNode,
1973} 2323}
2324impl 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}
1974impl AstNode for BoxPat { 2329impl 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 {
1998pub struct BindPat { 2353pub struct BindPat {
1999 pub(crate) syntax: SyntaxNode, 2354 pub(crate) syntax: SyntaxNode,
2000} 2355}
2356impl 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}
2001impl AstNode for BindPat { 2361impl 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 {
2026pub struct PlaceholderPat { 2386pub struct PlaceholderPat {
2027 pub(crate) syntax: SyntaxNode, 2387 pub(crate) syntax: SyntaxNode,
2028} 2388}
2389impl 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}
2029impl AstNode for PlaceholderPat { 2394impl 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 {}
2049pub struct DotDotPat { 2414pub struct DotDotPat {
2050 pub(crate) syntax: SyntaxNode, 2415 pub(crate) syntax: SyntaxNode,
2051} 2416}
2417impl 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}
2052impl AstNode for DotDotPat { 2422impl 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 {}
2072pub struct PathPat { 2442pub struct PathPat {
2073 pub(crate) syntax: SyntaxNode, 2443 pub(crate) syntax: SyntaxNode,
2074} 2444}
2445impl 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}
2075impl AstNode for PathPat { 2450impl 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 {
2099pub struct SlicePat { 2474pub struct SlicePat {
2100 pub(crate) syntax: SyntaxNode, 2475 pub(crate) syntax: SyntaxNode,
2101} 2476}
2477impl 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}
2102impl AstNode for SlicePat { 2482impl 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 {
2126pub struct RangePat { 2506pub struct RangePat {
2127 pub(crate) syntax: SyntaxNode, 2507 pub(crate) syntax: SyntaxNode,
2128} 2508}
2509impl 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}
2129impl AstNode for RangePat { 2514impl 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 {}
2149pub struct LiteralPat { 2534pub struct LiteralPat {
2150 pub(crate) syntax: SyntaxNode, 2535 pub(crate) syntax: SyntaxNode,
2151} 2536}
2537impl 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}
2152impl AstNode for LiteralPat { 2542impl 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 {
2176pub struct RecordPat { 2566pub struct RecordPat {
2177 pub(crate) syntax: SyntaxNode, 2567 pub(crate) syntax: SyntaxNode,
2178} 2568}
2569impl 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}
2179impl AstNode for RecordPat { 2574impl 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 {
2206pub struct RecordFieldPatList { 2601pub struct RecordFieldPatList {
2207 pub(crate) syntax: SyntaxNode, 2602 pub(crate) syntax: SyntaxNode,
2208} 2603}
2604impl 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}
2209impl AstNode for RecordFieldPatList { 2609impl 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 {
2236pub struct RecordFieldPat { 2636pub struct RecordFieldPat {
2237 pub(crate) syntax: SyntaxNode, 2637 pub(crate) syntax: SyntaxNode,
2238} 2638}
2639impl 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}
2239impl AstNode for RecordFieldPat { 2644impl 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 {
2264pub struct TupleStructPat { 2669pub struct TupleStructPat {
2265 pub(crate) syntax: SyntaxNode, 2670 pub(crate) syntax: SyntaxNode,
2266} 2671}
2672impl 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}
2267impl AstNode for TupleStructPat { 2677impl 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 {
2294pub struct TuplePat { 2704pub struct TuplePat {
2295 pub(crate) syntax: SyntaxNode, 2705 pub(crate) syntax: SyntaxNode,
2296} 2706}
2707impl 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}
2297impl AstNode for TuplePat { 2712impl 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 {
2321pub struct Visibility { 2736pub struct Visibility {
2322 pub(crate) syntax: SyntaxNode, 2737 pub(crate) syntax: SyntaxNode,
2323} 2738}
2739impl 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}
2324impl AstNode for Visibility { 2744impl 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 {}
2344pub struct Name { 2764pub struct Name {
2345 pub(crate) syntax: SyntaxNode, 2765 pub(crate) syntax: SyntaxNode,
2346} 2766}
2767impl 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}
2347impl AstNode for Name { 2772impl 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 {}
2367pub struct NameRef { 2792pub struct NameRef {
2368 pub(crate) syntax: SyntaxNode, 2793 pub(crate) syntax: SyntaxNode,
2369} 2794}
2795impl 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}
2370impl AstNode for NameRef { 2800impl 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 {}
2390pub struct MacroCall { 2820pub struct MacroCall {
2391 pub(crate) syntax: SyntaxNode, 2821 pub(crate) syntax: SyntaxNode,
2392} 2822}
2823impl 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}
2393impl AstNode for MacroCall { 2828impl 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 {
2423pub struct Attr { 2858pub struct Attr {
2424 pub(crate) syntax: SyntaxNode, 2859 pub(crate) syntax: SyntaxNode,
2425} 2860}
2861impl 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}
2426impl AstNode for Attr { 2866impl 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 {
2453pub struct TokenTree { 2893pub struct TokenTree {
2454 pub(crate) syntax: SyntaxNode, 2894 pub(crate) syntax: SyntaxNode,
2455} 2895}
2896impl 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}
2456impl AstNode for TokenTree { 2901impl 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 {}
2476pub struct TypeParamList { 2921pub struct TypeParamList {
2477 pub(crate) syntax: SyntaxNode, 2922 pub(crate) syntax: SyntaxNode,
2478} 2923}
2924impl 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}
2479impl AstNode for TypeParamList { 2929impl 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 {
2506pub struct TypeParam { 2956pub struct TypeParam {
2507 pub(crate) syntax: SyntaxNode, 2957 pub(crate) syntax: SyntaxNode,
2508} 2958}
2959impl 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}
2509impl AstNode for TypeParam { 2964impl 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 {
2536pub struct ConstParam { 2991pub struct ConstParam {
2537 pub(crate) syntax: SyntaxNode, 2992 pub(crate) syntax: SyntaxNode,
2538} 2993}
2994impl 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}
2539impl AstNode for ConstParam { 2999impl 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 {
2566pub struct LifetimeParam { 3026pub struct LifetimeParam {
2567 pub(crate) syntax: SyntaxNode, 3027 pub(crate) syntax: SyntaxNode,
2568} 3028}
3029impl 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}
2569impl AstNode for LifetimeParam { 3034impl 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 {}
2590pub struct TypeBound { 3055pub struct TypeBound {
2591 pub(crate) syntax: SyntaxNode, 3056 pub(crate) syntax: SyntaxNode,
2592} 3057}
3058impl 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}
2593impl AstNode for TypeBound { 3063impl 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 {
2617pub struct TypeBoundList { 3087pub struct TypeBoundList {
2618 pub(crate) syntax: SyntaxNode, 3088 pub(crate) syntax: SyntaxNode,
2619} 3089}
3090impl 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}
2620impl AstNode for TypeBoundList { 3095impl 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 {
2644pub struct WherePred { 3119pub struct WherePred {
2645 pub(crate) syntax: SyntaxNode, 3120 pub(crate) syntax: SyntaxNode,
2646} 3121}
3122impl 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}
2647impl AstNode for WherePred { 3127impl 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 {
2672pub struct WhereClause { 3152pub struct WhereClause {
2673 pub(crate) syntax: SyntaxNode, 3153 pub(crate) syntax: SyntaxNode,
2674} 3154}
3155impl 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}
2675impl AstNode for WhereClause { 3160impl 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 {
2699pub struct ExprStmt { 3184pub struct ExprStmt {
2700 pub(crate) syntax: SyntaxNode, 3185 pub(crate) syntax: SyntaxNode,
2701} 3186}
3187impl 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}
2702impl AstNode for ExprStmt { 3192impl 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 {
2726pub struct LetStmt { 3216pub struct LetStmt {
2727 pub(crate) syntax: SyntaxNode, 3217 pub(crate) syntax: SyntaxNode,
2728} 3218}
3219impl 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}
2729impl AstNode for LetStmt { 3224impl 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 {
2757pub struct Condition { 3252pub struct Condition {
2758 pub(crate) syntax: SyntaxNode, 3253 pub(crate) syntax: SyntaxNode,
2759} 3254}
3255impl 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}
2760impl AstNode for Condition { 3260impl 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 {
2787pub struct Block { 3287pub struct Block {
2788 pub(crate) syntax: SyntaxNode, 3288 pub(crate) syntax: SyntaxNode,
2789} 3289}
3290impl 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}
2790impl AstNode for Block { 3295impl 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 {
2819pub struct ParamList { 3324pub struct ParamList {
2820 pub(crate) syntax: SyntaxNode, 3325 pub(crate) syntax: SyntaxNode,
2821} 3326}
3327impl 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}
2822impl AstNode for ParamList { 3332impl 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 {
2849pub struct SelfParam { 3359pub struct SelfParam {
2850 pub(crate) syntax: SyntaxNode, 3360 pub(crate) syntax: SyntaxNode,
2851} 3361}
3362impl 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}
2852impl AstNode for SelfParam { 3367impl 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 {}
2874pub struct Param { 3389pub struct Param {
2875 pub(crate) syntax: SyntaxNode, 3390 pub(crate) syntax: SyntaxNode,
2876} 3391}
3392impl 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}
2877impl AstNode for Param { 3397impl 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 {
2903pub struct UseItem { 3423pub struct UseItem {
2904 pub(crate) syntax: SyntaxNode, 3424 pub(crate) syntax: SyntaxNode,
2905} 3425}
3426impl 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}
2906impl AstNode for UseItem { 3431impl 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 {
2932pub struct UseTree { 3457pub struct UseTree {
2933 pub(crate) syntax: SyntaxNode, 3458 pub(crate) syntax: SyntaxNode,
2934} 3459}
3460impl 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}
2935impl AstNode for UseTree { 3465impl 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 {
2965pub struct Alias { 3495pub struct Alias {
2966 pub(crate) syntax: SyntaxNode, 3496 pub(crate) syntax: SyntaxNode,
2967} 3497}
3498impl 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}
2968impl AstNode for Alias { 3503impl 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 {}
2989pub struct UseTreeList { 3524pub struct UseTreeList {
2990 pub(crate) syntax: SyntaxNode, 3525 pub(crate) syntax: SyntaxNode,
2991} 3526}
3527impl 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}
2992impl AstNode for UseTreeList { 3532impl 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 {
3016pub struct ExternCrateItem { 3556pub struct ExternCrateItem {
3017 pub(crate) syntax: SyntaxNode, 3557 pub(crate) syntax: SyntaxNode,
3018} 3558}
3559impl 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}
3019impl AstNode for ExternCrateItem { 3564impl 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 {
3048pub struct ArgList { 3593pub struct ArgList {
3049 pub(crate) syntax: SyntaxNode, 3594 pub(crate) syntax: SyntaxNode,
3050} 3595}
3596impl 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}
3051impl AstNode for ArgList { 3601impl 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 {
3075pub struct Path { 3625pub struct Path {
3076 pub(crate) syntax: SyntaxNode, 3626 pub(crate) syntax: SyntaxNode,
3077} 3627}
3628impl 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}
3078impl AstNode for Path { 3633impl 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 {
3105pub struct PathSegment { 3660pub struct PathSegment {
3106 pub(crate) syntax: SyntaxNode, 3661 pub(crate) syntax: SyntaxNode,
3107} 3662}
3663impl 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}
3108impl AstNode for PathSegment { 3668impl 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 {
3144pub struct TypeArgList { 3704pub struct TypeArgList {
3145 pub(crate) syntax: SyntaxNode, 3705 pub(crate) syntax: SyntaxNode,
3146} 3706}
3707impl 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}
3147impl AstNode for TypeArgList { 3712impl 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 {
3180pub struct TypeArg { 3745pub struct TypeArg {
3181 pub(crate) syntax: SyntaxNode, 3746 pub(crate) syntax: SyntaxNode,
3182} 3747}
3748impl 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}
3183impl AstNode for TypeArg { 3753impl 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 {
3207pub struct AssocTypeArg { 3777pub struct AssocTypeArg {
3208 pub(crate) syntax: SyntaxNode, 3778 pub(crate) syntax: SyntaxNode,
3209} 3779}
3780impl 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}
3210impl AstNode for AssocTypeArg { 3785impl 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 {
3237pub struct LifetimeArg { 3812pub struct LifetimeArg {
3238 pub(crate) syntax: SyntaxNode, 3813 pub(crate) syntax: SyntaxNode,
3239} 3814}
3815impl 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}
3240impl AstNode for LifetimeArg { 3820impl 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 {}
3260pub struct ConstArg { 3840pub struct ConstArg {
3261 pub(crate) syntax: SyntaxNode, 3841 pub(crate) syntax: SyntaxNode,
3262} 3842}
3843impl 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}
3263impl AstNode for ConstArg { 3848impl 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 {
3290pub struct MacroItems { 3875pub struct MacroItems {
3291 pub(crate) syntax: SyntaxNode, 3876 pub(crate) syntax: SyntaxNode,
3292} 3877}
3878impl 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}
3293impl AstNode for MacroItems { 3883impl 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 {}
3315pub struct MacroStmts { 3905pub struct MacroStmts {
3316 pub(crate) syntax: SyntaxNode, 3906 pub(crate) syntax: SyntaxNode,
3317} 3907}
3908impl 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}
3318impl AstNode for MacroStmts { 3913impl 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}
3960impl 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}
3365impl AstNode for NominalDef { 3965impl 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}
4073impl 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}
3473impl AstNode for TypeRef { 4078impl 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}
4199impl 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}
3594impl AstNode for ModuleItem { 4204impl 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}
4270impl 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}
3660impl AstNode for ImplItem { 4275impl 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}
4489impl 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}
3874impl AstNode for Expr { 4494impl 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}
4666impl 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}
4046impl AstNode for Pat { 4671impl 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}
4734impl 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}
4109impl AstNode for AttrInput { 4739impl 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}
4776impl 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}
4146impl AstNode for Stmt { 4781impl 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/src/parsing/lexer.rs b/crates/ra_syntax/src/parsing/lexer.rs
index f2684c852..d1baaa607 100644
--- a/crates/ra_syntax/src/parsing/lexer.rs
+++ b/crates/ra_syntax/src/parsing/lexer.rs
@@ -65,7 +65,7 @@ pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) {
65/// Beware that unescape errors are not checked at tokenization time. 65/// Beware that unescape errors are not checked at tokenization time.
66pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxError>)> { 66pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxError>)> {
67 lex_first_token(text) 67 lex_first_token(text)
68 .filter(|(token, _)| token.len.to_usize() == text.len()) 68 .filter(|(token, _)| token.len == TextUnit::of_str(text))
69 .map(|(token, error)| (token.kind, error)) 69 .map(|(token, error)| (token.kind, error))
70} 70}
71 71
@@ -75,7 +75,7 @@ pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxEr
75/// Beware that unescape errors are not checked at tokenization time. 75/// Beware that unescape errors are not checked at tokenization time.
76pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> { 76pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> {
77 lex_first_token(text) 77 lex_first_token(text)
78 .filter(|(token, error)| !error.is_some() && token.len.to_usize() == text.len()) 78 .filter(|(token, error)| !error.is_some() && token.len == TextUnit::of_str(text))
79 .map(|(token, _error)| token.kind) 79 .map(|(token, _error)| token.kind)
80} 80}
81 81
diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs
index 912e6aec0..6a8cb6bb5 100644
--- a/crates/ra_syntax/src/tests.rs
+++ b/crates/ra_syntax/src/tests.rs
@@ -5,7 +5,7 @@ use std::{
5 5
6use test_utils::{collect_tests, dir_tests, project_dir, read_text}; 6use test_utils::{collect_tests, dir_tests, project_dir, read_text};
7 7
8use crate::{fuzz, tokenize, SourceFile, SyntaxError, Token}; 8use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextUnit, Token};
9 9
10#[test] 10#[test]
11fn lexer_tests() { 11fn lexer_tests() {
@@ -34,6 +34,7 @@ fn main() {
34 "##; 34 "##;
35 35
36 let parse = SourceFile::parse(code); 36 let parse = SourceFile::parse(code);
37 // eprintln!("{:#?}", parse.syntax_node());
37 assert!(parse.ok().is_ok()); 38 assert!(parse.ok().is_ok());
38} 39}
39 40
@@ -120,11 +121,11 @@ fn assert_errors_are_absent(errors: &[SyntaxError], path: &Path) {
120 121
121fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String { 122fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String {
122 let mut acc = String::new(); 123 let mut acc = String::new();
123 let mut offset = 0; 124 let mut offset = TextUnit::from_usize(0);
124 for token in tokens { 125 for token in tokens {
125 let token_len = token.len.to_usize(); 126 let token_len = token.len;
126 let token_text = &text[offset..offset + token_len]; 127 let token_text = &text[TextRange::offset_len(offset, token.len)];
127 offset += token_len; 128 offset += token.len;
128 writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap(); 129 writeln!(acc, "{:?} {} {:?}", token.kind, token_len, token_text).unwrap();
129 } 130 }
130 for err in errors { 131 for err in errors {
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.txt b/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.txt
index a0a8aea76..4c17f0db8 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0032_fn_pointer_type.txt
@@ -81,7 +81,8 @@ SOURCE_FILE@[0; 113)
81 WHITESPACE@[97; 98) " " 81 WHITESPACE@[97; 98) " "
82 COMMA@[98; 99) "," 82 COMMA@[98; 99) ","
83 WHITESPACE@[99; 100) " " 83 WHITESPACE@[99; 100) " "
84 DOTDOTDOT@[100; 103) "..." 84 PARAM@[100; 103)
85 DOTDOTDOT@[100; 103) "..."
85 WHITESPACE@[103; 104) " " 86 WHITESPACE@[103; 104) " "
86 R_PAREN@[104; 105) ")" 87 R_PAREN@[104; 105) ")"
87 WHITESPACE@[105; 106) " " 88 WHITESPACE@[105; 106) " "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0116_trait_fn_placeholder_parameter.rs b/crates/ra_syntax/test_data/parser/inline/ok/0116_trait_fn_placeholder_parameter.rs
deleted file mode 100644
index 472cb8803..000000000
--- a/crates/ra_syntax/test_data/parser/inline/ok/0116_trait_fn_placeholder_parameter.rs
+++ /dev/null
@@ -1,3 +0,0 @@
1trait Foo {
2 fn bar(_: u64, mut x: i32);
3}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0116_trait_fn_placeholder_parameter.txt b/crates/ra_syntax/test_data/parser/inline/ok/0116_trait_fn_placeholder_parameter.txt
deleted file mode 100644
index 158236c5a..000000000
--- a/crates/ra_syntax/test_data/parser/inline/ok/0116_trait_fn_placeholder_parameter.txt
+++ /dev/null
@@ -1,47 +0,0 @@
1SOURCE_FILE@[0; 46)
2 TRAIT_DEF@[0; 45)
3 TRAIT_KW@[0; 5) "trait"
4 WHITESPACE@[5; 6) " "
5 NAME@[6; 9)
6 IDENT@[6; 9) "Foo"
7 WHITESPACE@[9; 10) " "
8 ITEM_LIST@[10; 45)
9 L_CURLY@[10; 11) "{"
10 WHITESPACE@[11; 16) "\n "
11 FN_DEF@[16; 43)
12 FN_KW@[16; 18) "fn"
13 WHITESPACE@[18; 19) " "
14 NAME@[19; 22)
15 IDENT@[19; 22) "bar"
16 PARAM_LIST@[22; 42)
17 L_PAREN@[22; 23) "("
18 PARAM@[23; 29)
19 PLACEHOLDER_PAT@[23; 24)
20 UNDERSCORE@[23; 24) "_"
21 COLON@[24; 25) ":"
22 WHITESPACE@[25; 26) " "
23 PATH_TYPE@[26; 29)
24 PATH@[26; 29)
25 PATH_SEGMENT@[26; 29)
26 NAME_REF@[26; 29)
27 IDENT@[26; 29) "u64"
28 COMMA@[29; 30) ","
29 WHITESPACE@[30; 31) " "
30 PARAM@[31; 41)
31 BIND_PAT@[31; 36)
32 MUT_KW@[31; 34) "mut"
33 WHITESPACE@[34; 35) " "
34 NAME@[35; 36)
35 IDENT@[35; 36) "x"
36 COLON@[36; 37) ":"
37 WHITESPACE@[37; 38) " "
38 PATH_TYPE@[38; 41)
39 PATH@[38; 41)
40 PATH_SEGMENT@[38; 41)
41 NAME_REF@[38; 41)
42 IDENT@[38; 41) "i32"
43 R_PAREN@[41; 42) ")"
44 SEMI@[42; 43) ";"
45 WHITESPACE@[43; 44) "\n"
46 R_CURLY@[44; 45) "}"
47 WHITESPACE@[45; 46) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.txt
index 836e8e55b..6c3b17868 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0123_param_list_vararg.txt
@@ -32,7 +32,8 @@ SOURCE_FILE@[0; 57)
32 IDENT@[38; 40) "i8" 32 IDENT@[38; 40) "i8"
33 COMMA@[40; 41) "," 33 COMMA@[40; 41) ","
34 WHITESPACE@[41; 42) " " 34 WHITESPACE@[41; 42) " "
35 DOTDOTDOT@[42; 45) "..." 35 PARAM@[42; 45)
36 DOTDOTDOT@[42; 45) "..."
36 R_PAREN@[45; 46) ")" 37 R_PAREN@[45; 46) ")"
37 WHITESPACE@[46; 47) " " 38 WHITESPACE@[46; 47) " "
38 RET_TYPE@[47; 53) 39 RET_TYPE@[47; 53)
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.rs b/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.rs
new file mode 100644
index 000000000..7b277c16b
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.rs
@@ -0,0 +1 @@
fn foo((x, y): (i32, i32)) {}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.txt b/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.txt
new file mode 100644
index 000000000..103e254a6
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0156_fn_def_param.txt
@@ -0,0 +1,44 @@
1SOURCE_FILE@[0; 30)
2 FN_DEF@[0; 29)
3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 26)
8 L_PAREN@[6; 7) "("
9 PARAM@[7; 25)
10 TUPLE_PAT@[7; 13)
11 L_PAREN@[7; 8) "("
12 BIND_PAT@[8; 9)
13 NAME@[8; 9)
14 IDENT@[8; 9) "x"
15 COMMA@[9; 10) ","
16 WHITESPACE@[10; 11) " "
17 BIND_PAT@[11; 12)
18 NAME@[11; 12)
19 IDENT@[11; 12) "y"
20 R_PAREN@[12; 13) ")"
21 COLON@[13; 14) ":"
22 WHITESPACE@[14; 15) " "
23 TUPLE_TYPE@[15; 25)
24 L_PAREN@[15; 16) "("
25 PATH_TYPE@[16; 19)
26 PATH@[16; 19)
27 PATH_SEGMENT@[16; 19)
28 NAME_REF@[16; 19)
29 IDENT@[16; 19) "i32"
30 COMMA@[19; 20) ","
31 WHITESPACE@[20; 21) " "
32 PATH_TYPE@[21; 24)
33 PATH@[21; 24)
34 PATH_SEGMENT@[21; 24)
35 NAME_REF@[21; 24)
36 IDENT@[21; 24) "i32"
37 R_PAREN@[24; 25) ")"
38 R_PAREN@[25; 26) ")"
39 WHITESPACE@[26; 27) " "
40 BLOCK_EXPR@[27; 29)
41 BLOCK@[27; 29)
42 L_CURLY@[27; 28) "{"
43 R_CURLY@[28; 29) "}"
44 WHITESPACE@[29; 30) "\n"
diff --git a/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt b/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt
index 719c99c17..254eafc36 100644
--- a/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0051_parameter_attrs.txt
@@ -118,7 +118,8 @@ SOURCE_FILE@[0; 519)
118 IDENT@[108; 112) "attr" 118 IDENT@[108; 112) "attr"
119 R_BRACK@[112; 113) "]" 119 R_BRACK@[112; 113) "]"
120 WHITESPACE@[113; 114) " " 120 WHITESPACE@[113; 114) " "
121 DOTDOTDOT@[114; 117) "..." 121 PARAM@[114; 117)
122 DOTDOTDOT@[114; 117) "..."
122 R_PAREN@[117; 118) ")" 123 R_PAREN@[117; 118) ")"
123 WHITESPACE@[118; 119) " " 124 WHITESPACE@[118; 119) " "
124 RET_TYPE@[119; 125) 125 RET_TYPE@[119; 125)
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.rs b/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rs
index a94bf378a..3b666af8e 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.rs
+++ b/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.rs
@@ -3,4 +3,5 @@ trait T {
3 fn f2(S { a, b }: S) {} 3 fn f2(S { a, b }: S) {}
4 fn f3(NewType(a): NewType) {} 4 fn f3(NewType(a): NewType) {}
5 fn f4(&&a: &&usize) {} 5 fn f4(&&a: &&usize) {}
6 fn bar(_: u64, mut x: i32);
6} 7}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.txt b/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.txt
index b22df8dbe..eb2e3a503 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0153_trait_fn_patterns.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0063_trait_fn_patterns.txt
@@ -1,11 +1,11 @@
1SOURCE_FILE@[0; 138) 1SOURCE_FILE@[0; 170)
2 TRAIT_DEF@[0; 137) 2 TRAIT_DEF@[0; 169)
3 TRAIT_KW@[0; 5) "trait" 3 TRAIT_KW@[0; 5) "trait"
4 WHITESPACE@[5; 6) " " 4 WHITESPACE@[5; 6) " "
5 NAME@[6; 7) 5 NAME@[6; 7)
6 IDENT@[6; 7) "T" 6 IDENT@[6; 7) "T"
7 WHITESPACE@[7; 8) " " 7 WHITESPACE@[7; 8) " "
8 ITEM_LIST@[8; 137) 8 ITEM_LIST@[8; 169)
9 L_CURLY@[8; 9) "{" 9 L_CURLY@[8; 9) "{"
10 WHITESPACE@[9; 14) "\n " 10 WHITESPACE@[9; 14) "\n "
11 FN_DEF@[14; 46) 11 FN_DEF@[14; 46)
@@ -156,6 +156,41 @@ SOURCE_FILE@[0; 138)
156 BLOCK@[133; 135) 156 BLOCK@[133; 135)
157 L_CURLY@[133; 134) "{" 157 L_CURLY@[133; 134) "{"
158 R_CURLY@[134; 135) "}" 158 R_CURLY@[134; 135) "}"
159 WHITESPACE@[135; 136) "\n" 159 WHITESPACE@[135; 140) "\n "
160 R_CURLY@[136; 137) "}" 160 FN_DEF@[140; 167)
161 WHITESPACE@[137; 138) "\n" 161 FN_KW@[140; 142) "fn"
162 WHITESPACE@[142; 143) " "
163 NAME@[143; 146)
164 IDENT@[143; 146) "bar"
165 PARAM_LIST@[146; 166)
166 L_PAREN@[146; 147) "("
167 PARAM@[147; 153)
168 PLACEHOLDER_PAT@[147; 148)
169 UNDERSCORE@[147; 148) "_"
170 COLON@[148; 149) ":"
171 WHITESPACE@[149; 150) " "
172 PATH_TYPE@[150; 153)
173 PATH@[150; 153)
174 PATH_SEGMENT@[150; 153)
175 NAME_REF@[150; 153)
176 IDENT@[150; 153) "u64"
177 COMMA@[153; 154) ","
178 WHITESPACE@[154; 155) " "
179 PARAM@[155; 165)
180 BIND_PAT@[155; 160)
181 MUT_KW@[155; 158) "mut"
182 WHITESPACE@[158; 159) " "
183 NAME@[159; 160)
184 IDENT@[159; 160) "x"
185 COLON@[160; 161) ":"
186 WHITESPACE@[161; 162) " "
187 PATH_TYPE@[162; 165)
188 PATH@[162; 165)
189 PATH_SEGMENT@[162; 165)
190 NAME_REF@[162; 165)
191 IDENT@[162; 165) "i32"
192 R_PAREN@[165; 166) ")"
193 SEMI@[166; 167) ";"
194 WHITESPACE@[167; 168) "\n"
195 R_CURLY@[168; 169) "}"
196 WHITESPACE@[169; 170) "\n"
diff --git a/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rs b/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rs
new file mode 100644
index 000000000..a16afbaf3
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.rs
@@ -0,0 +1,5 @@
1extern "C" {
2 fn a(_: *mut u8, ...,);
3 fn b(_: *mut u8, _: ...);
4 fn c(_: *mut u8, #[cfg(never)] [w, t, f]: ...,);
5}
diff --git a/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.txt b/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.txt
new file mode 100644
index 000000000..186f03626
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/ok/0063_variadic_fun.txt
@@ -0,0 +1,133 @@
1SOURCE_FILE@[0; 126)
2 EXTERN_BLOCK@[0; 125)
3 ABI@[0; 10)
4 EXTERN_KW@[0; 6) "extern"
5 WHITESPACE@[6; 7) " "
6 STRING@[7; 10) "\"C\""
7 WHITESPACE@[10; 11) " "
8 EXTERN_ITEM_LIST@[11; 125)
9 L_CURLY@[11; 12) "{"
10 WHITESPACE@[12; 17) "\n "
11 FN_DEF@[17; 40)
12 FN_KW@[17; 19) "fn"
13 WHITESPACE@[19; 20) " "
14 NAME@[20; 21)
15 IDENT@[20; 21) "a"
16 PARAM_LIST@[21; 39)
17 L_PAREN@[21; 22) "("
18 PARAM@[22; 32)
19 PLACEHOLDER_PAT@[22; 23)
20 UNDERSCORE@[22; 23) "_"
21 COLON@[23; 24) ":"
22 WHITESPACE@[24; 25) " "
23 POINTER_TYPE@[25; 32)
24 STAR@[25; 26) "*"
25 MUT_KW@[26; 29) "mut"
26 WHITESPACE@[29; 30) " "
27 PATH_TYPE@[30; 32)
28 PATH@[30; 32)
29 PATH_SEGMENT@[30; 32)
30 NAME_REF@[30; 32)
31 IDENT@[30; 32) "u8"
32 COMMA@[32; 33) ","
33 WHITESPACE@[33; 34) " "
34 PARAM@[34; 37)
35 DOTDOTDOT@[34; 37) "..."
36 COMMA@[37; 38) ","
37 R_PAREN@[38; 39) ")"
38 SEMI@[39; 40) ";"
39 WHITESPACE@[40; 45) "\n "
40 FN_DEF@[45; 70)
41 FN_KW@[45; 47) "fn"
42 WHITESPACE@[47; 48) " "
43 NAME@[48; 49)
44 IDENT@[48; 49) "b"
45 PARAM_LIST@[49; 69)
46 L_PAREN@[49; 50) "("
47 PARAM@[50; 60)
48 PLACEHOLDER_PAT@[50; 51)
49 UNDERSCORE@[50; 51) "_"
50 COLON@[51; 52) ":"
51 WHITESPACE@[52; 53) " "
52 POINTER_TYPE@[53; 60)
53 STAR@[53; 54) "*"
54 MUT_KW@[54; 57) "mut"
55 WHITESPACE@[57; 58) " "
56 PATH_TYPE@[58; 60)
57 PATH@[58; 60)
58 PATH_SEGMENT@[58; 60)
59 NAME_REF@[58; 60)
60 IDENT@[58; 60) "u8"
61 COMMA@[60; 61) ","
62 WHITESPACE@[61; 62) " "
63 PARAM@[62; 68)
64 PLACEHOLDER_PAT@[62; 63)
65 UNDERSCORE@[62; 63) "_"
66 COLON@[63; 64) ":"
67 WHITESPACE@[64; 65) " "
68 DOTDOTDOT@[65; 68) "..."
69 R_PAREN@[68; 69) ")"
70 SEMI@[69; 70) ";"
71 WHITESPACE@[70; 75) "\n "
72 FN_DEF@[75; 123)
73 FN_KW@[75; 77) "fn"
74 WHITESPACE@[77; 78) " "
75 NAME@[78; 79)
76 IDENT@[78; 79) "c"
77 PARAM_LIST@[79; 122)
78 L_PAREN@[79; 80) "("
79 PARAM@[80; 90)
80 PLACEHOLDER_PAT@[80; 81)
81 UNDERSCORE@[80; 81) "_"
82 COLON@[81; 82) ":"
83 WHITESPACE@[82; 83) " "
84 POINTER_TYPE@[83; 90)
85 STAR@[83; 84) "*"
86 MUT_KW@[84; 87) "mut"
87 WHITESPACE@[87; 88) " "
88 PATH_TYPE@[88; 90)
89 PATH@[88; 90)
90 PATH_SEGMENT@[88; 90)
91 NAME_REF@[88; 90)
92 IDENT@[88; 90) "u8"
93 COMMA@[90; 91) ","
94 WHITESPACE@[91; 92) " "
95 ATTR@[92; 105)
96 POUND@[92; 93) "#"
97 L_BRACK@[93; 94) "["
98 PATH@[94; 97)
99 PATH_SEGMENT@[94; 97)
100 NAME_REF@[94; 97)
101 IDENT@[94; 97) "cfg"
102 TOKEN_TREE@[97; 104)
103 L_PAREN@[97; 98) "("
104 IDENT@[98; 103) "never"
105 R_PAREN@[103; 104) ")"
106 R_BRACK@[104; 105) "]"
107 WHITESPACE@[105; 106) " "
108 PARAM@[106; 120)
109 SLICE_PAT@[106; 115)
110 L_BRACK@[106; 107) "["
111 BIND_PAT@[107; 108)
112 NAME@[107; 108)
113 IDENT@[107; 108) "w"
114 COMMA@[108; 109) ","
115 WHITESPACE@[109; 110) " "
116 BIND_PAT@[110; 111)
117 NAME@[110; 111)
118 IDENT@[110; 111) "t"
119 COMMA@[111; 112) ","
120 WHITESPACE@[112; 113) " "
121 BIND_PAT@[113; 114)
122 NAME@[113; 114)
123 IDENT@[113; 114) "f"
124 R_BRACK@[114; 115) "]"
125 COLON@[115; 116) ":"
126 WHITESPACE@[116; 117) " "
127 DOTDOTDOT@[117; 120) "..."
128 COMMA@[120; 121) ","
129 R_PAREN@[121; 122) ")"
130 SEMI@[122; 123) ";"
131 WHITESPACE@[123; 124) "\n"
132 R_CURLY@[124; 125) "}"
133 WHITESPACE@[125; 126) "\n"
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.rs b/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rs
index b49e872d7..b49e872d7 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.rs
+++ b/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.rs
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.txt b/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.txt
index b30030de3..b30030de3 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0152_fn_patterns.txt
+++ b/crates/ra_syntax/test_data/parser/ok/0064_impl_fn_params.txt
diff --git a/crates/ra_text_edit/src/text_edit.rs b/crates/ra_text_edit/src/text_edit.rs
index 3291ada42..5c37a08a8 100644
--- a/crates/ra_text_edit/src/text_edit.rs
+++ b/crates/ra_text_edit/src/text_edit.rs
@@ -63,12 +63,12 @@ impl TextEdit {
63 } 63 }
64 64
65 pub fn apply(&self, text: &str) -> String { 65 pub fn apply(&self, text: &str) -> String {
66 let mut total_len = text.len(); 66 let mut total_len = TextUnit::of_str(text);
67 for atom in self.atoms.iter() { 67 for atom in self.atoms.iter() {
68 total_len += atom.insert.len(); 68 total_len += TextUnit::of_str(&atom.insert);
69 total_len -= (atom.delete.end() - atom.delete.start()).to_usize(); 69 total_len -= atom.delete.end() - atom.delete.start();
70 } 70 }
71 let mut buf = String::with_capacity(total_len); 71 let mut buf = String::with_capacity(total_len.to_usize());
72 let mut prev = 0; 72 let mut prev = 0;
73 for atom in self.atoms.iter() { 73 for atom in self.atoms.iter() {
74 let start = atom.delete.start().to_usize(); 74 let start = atom.delete.start().to_usize();
@@ -80,7 +80,7 @@ impl TextEdit {
80 prev = end; 80 prev = end;
81 } 81 }
82 buf.push_str(&text[prev..text.len()]); 82 buf.push_str(&text[prev..text.len()]);
83 assert_eq!(buf.len(), total_len); 83 assert_eq!(TextUnit::of_str(&buf), total_len);
84 buf 84 buf
85 } 85 }
86 86
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index cfca06f56..6b9a11a87 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -30,7 +30,11 @@ pub struct ServerConfig {
30 30
31 pub lru_capacity: Option<usize>, 31 pub lru_capacity: Option<usize>,
32 32
33 pub max_inlay_hint_length: Option<usize>, 33 #[serde(deserialize_with = "nullable_bool_true")]
34 pub inlay_hints_type: bool,
35 #[serde(deserialize_with = "nullable_bool_true")]
36 pub inlay_hints_parameter: bool,
37 pub inlay_hints_max_length: Option<usize>,
34 38
35 pub cargo_watch_enable: bool, 39 pub cargo_watch_enable: bool,
36 pub cargo_watch_args: Vec<String>, 40 pub cargo_watch_args: Vec<String>,
@@ -63,7 +67,9 @@ impl Default for ServerConfig {
63 exclude_globs: Vec::new(), 67 exclude_globs: Vec::new(),
64 use_client_watching: false, 68 use_client_watching: false,
65 lru_capacity: None, 69 lru_capacity: None,
66 max_inlay_hint_length: None, 70 inlay_hints_type: true,
71 inlay_hints_parameter: true,
72 inlay_hints_max_length: None,
67 cargo_watch_enable: true, 73 cargo_watch_enable: true,
68 cargo_watch_args: Vec::new(), 74 cargo_watch_args: Vec::new(),
69 cargo_watch_command: "check".to_string(), 75 cargo_watch_command: "check".to_string(),
diff --git a/crates/rust-analyzer/src/conv.rs b/crates/rust-analyzer/src/conv.rs
index a2d68c344..fd4657d7e 100644
--- a/crates/rust-analyzer/src/conv.rs
+++ b/crates/rust-analyzer/src/conv.rs
@@ -11,8 +11,8 @@ use lsp_types::{
11use ra_ide::{ 11use ra_ide::{
12 translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, 12 translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition,
13 FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, 13 FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag,
14 InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo, ReferenceAccess, Severity, 14 InlayHint, InlayKind, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo,
15 SourceChange, SourceFileEdit, 15 ReferenceAccess, Severity, SourceChange, SourceFileEdit,
16}; 16};
17use ra_syntax::{SyntaxKind, TextRange, TextUnit}; 17use ra_syntax::{SyntaxKind, TextRange, TextUnit};
18use ra_text_edit::{AtomTextEdit, TextEdit}; 18use ra_text_edit::{AtomTextEdit, TextEdit};
@@ -323,6 +323,20 @@ impl ConvWith<&FoldConvCtx<'_>> for Fold {
323 } 323 }
324} 324}
325 325
326impl ConvWith<&LineIndex> for InlayHint {
327 type Output = req::InlayHint;
328 fn conv_with(self, line_index: &LineIndex) -> Self::Output {
329 req::InlayHint {
330 label: self.label.to_string(),
331 range: self.range.conv_with(line_index),
332 kind: match self.kind {
333 InlayKind::ParameterHint => req::InlayKind::ParameterHint,
334 InlayKind::TypeHint => req::InlayKind::TypeHint,
335 },
336 }
337 }
338}
339
326impl Conv for Highlight { 340impl Conv for Highlight {
327 type Output = (u32, u32); 341 type Output = (u32, u32);
328 342
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index b4add046f..eb29e8322 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -18,7 +18,7 @@ use crossbeam_channel::{select, unbounded, RecvError, Sender};
18use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; 18use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
19use lsp_types::{ClientCapabilities, NumberOrString}; 19use lsp_types::{ClientCapabilities, NumberOrString};
20use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask}; 20use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask};
21use ra_ide::{Canceled, FileId, LibraryData, SourceRootId}; 21use ra_ide::{Canceled, FileId, InlayHintsOptions, LibraryData, SourceRootId};
22use ra_prof::profile; 22use ra_prof::profile;
23use ra_vfs::{VfsFile, VfsTask, Watch}; 23use ra_vfs::{VfsFile, VfsTask, Watch};
24use relative_path::RelativePathBuf; 24use relative_path::RelativePathBuf;
@@ -177,7 +177,11 @@ pub fn main_loop(
177 .and_then(|it| it.folding_range.as_ref()) 177 .and_then(|it| it.folding_range.as_ref())
178 .and_then(|it| it.line_folding_only) 178 .and_then(|it| it.line_folding_only)
179 .unwrap_or(false), 179 .unwrap_or(false),
180 max_inlay_hint_length: config.max_inlay_hint_length, 180 inlay_hints: InlayHintsOptions {
181 type_hints: config.inlay_hints_type,
182 parameter_hints: config.inlay_hints_parameter,
183 max_length: config.inlay_hints_max_length,
184 },
181 cargo_watch: CheckOptions { 185 cargo_watch: CheckOptions {
182 enable: config.cargo_watch_enable, 186 enable: config.cargo_watch_enable,
183 args: config.cargo_watch_args, 187 args: config.cargo_watch_args,
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 571a896f3..df3622d61 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -37,7 +37,7 @@ use crate::{
37 }, 37 },
38 diagnostics::DiagnosticTask, 38 diagnostics::DiagnosticTask,
39 from_json, 39 from_json,
40 req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, 40 req::{self, Decoration, InlayHint, InlayHintsParams},
41 semantic_tokens::SemanticTokensBuilder, 41 semantic_tokens::SemanticTokensBuilder,
42 world::WorldSnapshot, 42 world::WorldSnapshot,
43 LspError, Result, 43 LspError, Result,
@@ -1017,16 +1017,9 @@ pub fn handle_inlay_hints(
1017 let analysis = world.analysis(); 1017 let analysis = world.analysis();
1018 let line_index = analysis.file_line_index(file_id)?; 1018 let line_index = analysis.file_line_index(file_id)?;
1019 Ok(analysis 1019 Ok(analysis
1020 .inlay_hints(file_id, world.options.max_inlay_hint_length)? 1020 .inlay_hints(file_id, &world.options.inlay_hints)?
1021 .into_iter() 1021 .into_iter()
1022 .map(|api_type| InlayHint { 1022 .map_conv_with(&line_index)
1023 label: api_type.label.to_string(),
1024 range: api_type.range.conv_with(&line_index),
1025 kind: match api_type.kind {
1026 ra_ide::InlayKind::TypeHint => InlayKind::TypeHint,
1027 ra_ide::InlayKind::ParameterHint => InlayKind::ParameterHint,
1028 },
1029 })
1030 .collect()) 1023 .collect())
1031} 1024}
1032 1025
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs
index a4fda9f80..5743471bf 100644
--- a/crates/rust-analyzer/src/world.rs
+++ b/crates/rust-analyzer/src/world.rs
@@ -13,7 +13,8 @@ use lsp_types::Url;
13use parking_lot::RwLock; 13use parking_lot::RwLock;
14use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckWatcher}; 14use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckWatcher};
15use ra_ide::{ 15use ra_ide::{
16 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, 16 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, InlayHintsOptions, LibraryData,
17 SourceRootId,
17}; 18};
18use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace}; 19use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace};
19use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch}; 20use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch};
@@ -34,7 +35,7 @@ pub struct Options {
34 pub publish_decorations: bool, 35 pub publish_decorations: bool,
35 pub supports_location_link: bool, 36 pub supports_location_link: bool,
36 pub line_folding_only: bool, 37 pub line_folding_only: bool,
37 pub max_inlay_hint_length: Option<usize>, 38 pub inlay_hints: InlayHintsOptions,
38 pub rustfmt_args: Vec<String>, 39 pub rustfmt_args: Vec<String>,
39 pub cargo_watch: CheckOptions, 40 pub cargo_watch: CheckOptions,
40 pub vscode_lldb: bool, 41 pub vscode_lldb: bool,
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index a0d8f4d37..db03df1c4 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -397,6 +397,8 @@ pub fn skip_slow_tests() -> bool {
397 should_skip 397 should_skip
398} 398}
399 399
400const REWRITE: bool = false;
401
400/// Asserts that `expected` and `actual` strings are equal. If they differ only 402/// Asserts that `expected` and `actual` strings are equal. If they differ only
401/// in trailing or leading whitespace the test won't fail and 403/// in trailing or leading whitespace the test won't fail and
402/// the contents of `actual` will be written to the file located at `path`. 404/// the contents of `actual` will be written to the file located at `path`.
@@ -412,7 +414,6 @@ fn assert_equal_text(expected: &str, actual: &str, path: &Path) {
412 fs::write(path, actual).unwrap(); 414 fs::write(path, actual).unwrap();
413 return; 415 return;
414 } 416 }
415 const REWRITE: bool = false;
416 if REWRITE { 417 if REWRITE {
417 println!("rewriting {}", pretty_path.display()); 418 println!("rewriting {}", pretty_path.display());
418 fs::write(path, actual).unwrap(); 419 fs::write(path, actual).unwrap();
diff --git a/docs/user/features.md b/docs/user/features.md
index ba4d50fa8..45360c633 100644
--- a/docs/user/features.md
+++ b/docs/user/features.md
@@ -191,8 +191,9 @@ Two types of inlay hints are displayed currently:
191 191
192In VS Code, the following settings can be used to configure the inlay hints: 192In VS Code, the following settings can be used to configure the inlay hints:
193 193
194* `rust-analyzer.displayInlayHints` — toggles inlay hints display on or off 194* `rust-analyzer.inlayHints.typeHints` - enable hints for inferred types.
195* `rust-analyzer.maxInlayHintLength` — shortens the hints if their length exceeds the value specified. If no value is specified (`null`), no shortening is applied. 195* `rust-analyzer.inlayHints.parameterHints` - enable hints for function parameters.
196* `rust-analyzer.inlayHints.maxLength` — shortens the hints if their length exceeds the value specified. If no value is specified (`null`), no shortening is applied.
196 197
197**Note:** VS Code does not have native support for inlay hints [yet](https://github.com/microsoft/vscode/issues/16221) and the hints are implemented using decorations. 198**Note:** VS Code does not have native support for inlay hints [yet](https://github.com/microsoft/vscode/issues/16221) and the hints are implemented using decorations.
198This approach has limitations, the caret movement and bracket highlighting near the edges of the hint may be weird: 199This approach has limitations, the caret movement and bracket highlighting near the edges of the hint may be weird:
diff --git a/editors/code/package.json b/editors/code/package.json
index 1fe8e9f8a..3aaae357a 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -261,7 +261,7 @@
261 "rust-analyzer.cargo-watch.enable": { 261 "rust-analyzer.cargo-watch.enable": {
262 "type": "boolean", 262 "type": "boolean",
263 "default": true, 263 "default": true,
264 "markdownDescription": "Run `cargo check` for diagnostics on save" 264 "markdownDescription": "Run specified `cargo-watch` command for diagnostics on save"
265 }, 265 },
266 "rust-analyzer.cargo-watch.arguments": { 266 "rust-analyzer.cargo-watch.arguments": {
267 "type": "array", 267 "type": "array",
@@ -312,12 +312,17 @@
312 "exclusiveMinimum": true, 312 "exclusiveMinimum": true,
313 "description": "Number of syntax trees rust-analyzer keeps in memory" 313 "description": "Number of syntax trees rust-analyzer keeps in memory"
314 }, 314 },
315 "rust-analyzer.displayInlayHints": { 315 "rust-analyzer.inlayHints.typeHints": {
316 "type": "boolean", 316 "type": "boolean",
317 "default": true, 317 "default": true,
318 "description": "Display additional type and parameter information in the editor" 318 "description": "Whether to show inlay type hints"
319 }, 319 },
320 "rust-analyzer.maxInlayHintLength": { 320 "rust-analyzer.inlayHints.parameterHints": {
321 "type": "boolean",
322 "default": true,
323 "description": "Whether to show function parameter name inlay hints at the call site"
324 },
325 "rust-analyzer.inlayHints.maxLength": {
321 "type": [ 326 "type": [
322 "null", 327 "null",
323 "integer" 328 "integer"
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 99c9c5ae7..d65454275 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -29,11 +29,16 @@ export async function createClient(config: Config, serverPath: string): Promise<
29 initializationOptions: { 29 initializationOptions: {
30 publishDecorations: !config.highlightingSemanticTokens, 30 publishDecorations: !config.highlightingSemanticTokens,
31 lruCapacity: config.lruCapacity, 31 lruCapacity: config.lruCapacity,
32 maxInlayHintLength: config.maxInlayHintLength, 32
33 inlayHintsType: config.inlayHints.typeHints,
34 inlayHintsParameter: config.inlayHints.parameterHints,
35 inlayHintsMaxLength: config.inlayHints.maxLength,
36
33 cargoWatchEnable: cargoWatchOpts.enable, 37 cargoWatchEnable: cargoWatchOpts.enable,
34 cargoWatchArgs: cargoWatchOpts.arguments, 38 cargoWatchArgs: cargoWatchOpts.arguments,
35 cargoWatchCommand: cargoWatchOpts.command, 39 cargoWatchCommand: cargoWatchOpts.command,
36 cargoWatchAllTargets: cargoWatchOpts.allTargets, 40 cargoWatchAllTargets: cargoWatchOpts.allTargets,
41
37 excludeGlobs: config.excludeGlobs, 42 excludeGlobs: config.excludeGlobs,
38 useClientWatching: config.useClientWatching, 43 useClientWatching: config.useClientWatching,
39 featureFlags: config.featureFlags, 44 featureFlags: config.featureFlags,
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 3ade7e900..6db073bec 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -5,6 +5,12 @@ import { log } from "./util";
5 5
6const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; 6const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
7 7
8export interface InlayHintOptions {
9 typeHints: boolean;
10 parameterHints: boolean;
11 maxLength: number | null;
12}
13
8export interface CargoWatchOptions { 14export interface CargoWatchOptions {
9 enable: boolean; 15 enable: boolean;
10 arguments: string[]; 16 arguments: string[];
@@ -22,7 +28,8 @@ export class Config {
22 private static readonly requiresReloadOpts = [ 28 private static readonly requiresReloadOpts = [
23 "cargoFeatures", 29 "cargoFeatures",
24 "cargo-watch", 30 "cargo-watch",
25 "highlighting.semanticTokens" 31 "highlighting.semanticTokens",
32 "inlayHints",
26 ] 33 ]
27 .map(opt => `${Config.rootSection}.${opt}`); 34 .map(opt => `${Config.rootSection}.${opt}`);
28 35
@@ -149,8 +156,13 @@ export class Config {
149 get highlightingOn() { return this.cfg.get("highlightingOn") as boolean; } 156 get highlightingOn() { return this.cfg.get("highlightingOn") as boolean; }
150 get rainbowHighlightingOn() { return this.cfg.get("rainbowHighlightingOn") as boolean; } 157 get rainbowHighlightingOn() { return this.cfg.get("rainbowHighlightingOn") as boolean; }
151 get lruCapacity() { return this.cfg.get("lruCapacity") as null | number; } 158 get lruCapacity() { return this.cfg.get("lruCapacity") as null | number; }
152 get displayInlayHints() { return this.cfg.get("displayInlayHints") as boolean; } 159 get inlayHints(): InlayHintOptions {
153 get maxInlayHintLength() { return this.cfg.get("maxInlayHintLength") as number; } 160 return {
161 typeHints: this.cfg.get("inlayHints.typeHints") as boolean,
162 parameterHints: this.cfg.get("inlayHints.parameterHints") as boolean,
163 maxLength: this.cfg.get("inlayHints.maxLength") as null | number,
164 };
165 }
154 get excludeGlobs() { return this.cfg.get("excludeGlobs") as string[]; } 166 get excludeGlobs() { return this.cfg.get("excludeGlobs") as string[]; }
155 get useClientWatching() { return this.cfg.get("useClientWatching") as boolean; } 167 get useClientWatching() { return this.cfg.get("useClientWatching") as boolean; }
156 get featureFlags() { return this.cfg.get("featureFlags") as Record<string, boolean>; } 168 get featureFlags() { return this.cfg.get("featureFlags") as Record<string, boolean>; }
diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts
index e1a82e03e..b19b09ad5 100644
--- a/editors/code/src/inlay_hints.ts
+++ b/editors/code/src/inlay_hints.ts
@@ -10,7 +10,7 @@ export function activateInlayHints(ctx: Ctx) {
10 const maybeUpdater = { 10 const maybeUpdater = {
11 updater: null as null | HintsUpdater, 11 updater: null as null | HintsUpdater,
12 onConfigChange() { 12 onConfigChange() {
13 if (!ctx.config.displayInlayHints) { 13 if (!ctx.config.inlayHints.typeHints && !ctx.config.inlayHints.parameterHints) {
14 return this.dispose(); 14 return this.dispose();
15 } 15 }
16 if (!this.updater) this.updater = new HintsUpdater(ctx); 16 if (!this.updater) this.updater = new HintsUpdater(ctx);
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 {
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 014b61b37..e1472e85d 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -38,13 +38,11 @@ pub fn project_root() -> PathBuf {
38} 38}
39 39
40pub fn run_rustfmt(mode: Mode) -> Result<()> { 40pub fn run_rustfmt(mode: Mode) -> Result<()> {
41 let _dir = pushd(project_root());
41 ensure_rustfmt()?; 42 ensure_rustfmt()?;
42 43
43 if mode == Mode::Verify { 44 let check = if mode == Mode::Verify { "--check" } else { "" };
44 run!("rustup run {} -- cargo fmt -- --check", TOOLCHAIN)?; 45 run!("rustup run {} -- cargo fmt -- {}", TOOLCHAIN, check)?;
45 } else {
46 run!("rustup run {} -- cargo fmt", TOOLCHAIN)?;
47 }
48 Ok(()) 46 Ok(())
49} 47}
50 48