diff options
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/diagnostics.rs | 9 | ||||
-rw-r--r-- | crates/ide/src/goto_definition.rs | 64 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 46 | ||||
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 4 | ||||
-rw-r--r-- | crates/ide/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ide/src/references/rename.rs | 177 | ||||
-rw-r--r-- | crates/ide/src/status.rs | 10 |
7 files changed, 276 insertions, 38 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 3df73ed4f..9d3d88289 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -142,6 +142,15 @@ pub(crate) fn diagnostics( | |||
142 | .with_code(Some(d.code())), | 142 | .with_code(Some(d.code())), |
143 | ); | 143 | ); |
144 | }) | 144 | }) |
145 | .on::<hir::diagnostics::UnresolvedProcMacro, _>(|d| { | ||
146 | // Use more accurate position if available. | ||
147 | let display_range = | ||
148 | d.precise_location.unwrap_or_else(|| sema.diagnostics_display_range(d).range); | ||
149 | |||
150 | // FIXME: it would be nice to tell the user whether proc macros are currently disabled | ||
151 | res.borrow_mut() | ||
152 | .push(Diagnostic::hint(display_range, d.message()).with_code(Some(d.code()))); | ||
153 | }) | ||
145 | // Only collect experimental diagnostics when they're enabled. | 154 | // Only collect experimental diagnostics when they're enabled. |
146 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) | 155 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) |
147 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); | 156 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); |
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 15792f947..b9810457f 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -1,14 +1,10 @@ | |||
1 | use hir::Semantics; | 1 | use hir::Semantics; |
2 | use ide_db::{ | 2 | use ide_db::{ |
3 | base_db::FileId, | ||
3 | defs::{NameClass, NameRefClass}, | 4 | defs::{NameClass, NameRefClass}, |
4 | symbol_index, RootDatabase, | 5 | symbol_index, RootDatabase, |
5 | }; | 6 | }; |
6 | use syntax::{ | 7 | use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; |
7 | ast::{self}, | ||
8 | match_ast, AstNode, | ||
9 | SyntaxKind::*, | ||
10 | SyntaxToken, TokenAtOffset, T, | ||
11 | }; | ||
12 | 8 | ||
13 | use crate::{ | 9 | use crate::{ |
14 | display::{ToNav, TryToNav}, | 10 | display::{ToNav, TryToNav}, |
@@ -44,6 +40,19 @@ pub(crate) fn goto_definition( | |||
44 | let nav = def.try_to_nav(sema.db)?; | 40 | let nav = def.try_to_nav(sema.db)?; |
45 | vec![nav] | 41 | vec![nav] |
46 | }, | 42 | }, |
43 | ast::SelfParam(self_param) => { | ||
44 | vec![self_to_nav_target(self_param, position.file_id)?] | ||
45 | }, | ||
46 | ast::PathSegment(segment) => { | ||
47 | segment.self_token()?; | ||
48 | let path = segment.parent_path(); | ||
49 | if path.qualifier().is_some() && !ast::PathExpr::can_cast(path.syntax().parent()?.kind()) { | ||
50 | return None; | ||
51 | } | ||
52 | let func = segment.syntax().ancestors().find_map(ast::Fn::cast)?; | ||
53 | let self_param = func.param_list()?.self_param()?; | ||
54 | vec![self_to_nav_target(self_param, position.file_id)?] | ||
55 | }, | ||
47 | _ => return None, | 56 | _ => return None, |
48 | } | 57 | } |
49 | }; | 58 | }; |
@@ -62,6 +71,20 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | |||
62 | } | 71 | } |
63 | } | 72 | } |
64 | 73 | ||
74 | fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option<NavigationTarget> { | ||
75 | let self_token = self_param.self_token()?; | ||
76 | Some(NavigationTarget { | ||
77 | file_id, | ||
78 | full_range: self_param.syntax().text_range(), | ||
79 | focus_range: Some(self_token.text_range()), | ||
80 | name: self_token.text().clone(), | ||
81 | kind: self_token.kind(), | ||
82 | container_name: None, | ||
83 | description: None, | ||
84 | docs: None, | ||
85 | }) | ||
86 | } | ||
87 | |||
65 | #[derive(Debug)] | 88 | #[derive(Debug)] |
66 | pub(crate) enum ReferenceResult { | 89 | pub(crate) enum ReferenceResult { |
67 | Exact(NavigationTarget), | 90 | Exact(NavigationTarget), |
@@ -984,4 +1007,33 @@ fn g() -> <() as Iterator<A = (), B<|> = u8>>::A {} | |||
984 | "#, | 1007 | "#, |
985 | ); | 1008 | ); |
986 | } | 1009 | } |
1010 | |||
1011 | #[test] | ||
1012 | fn goto_self_param_ty_specified() { | ||
1013 | check( | ||
1014 | r#" | ||
1015 | struct Foo {} | ||
1016 | |||
1017 | impl Foo { | ||
1018 | fn bar(self: &Foo) { | ||
1019 | //^^^^ | ||
1020 | let foo = sel<|>f; | ||
1021 | } | ||
1022 | }"#, | ||
1023 | ) | ||
1024 | } | ||
1025 | |||
1026 | #[test] | ||
1027 | fn goto_self_param_on_decl() { | ||
1028 | check( | ||
1029 | r#" | ||
1030 | struct Foo {} | ||
1031 | |||
1032 | impl Foo { | ||
1033 | fn bar(&self<|>) { | ||
1034 | //^^^^ | ||
1035 | } | ||
1036 | }"#, | ||
1037 | ) | ||
1038 | } | ||
987 | } | 1039 | } |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 832192881..94ad800a0 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -139,14 +139,17 @@ pub(crate) fn hover( | |||
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | let node = token | 142 | let node = token.ancestors().find(|n| { |
143 | .ancestors() | 143 | ast::Expr::can_cast(n.kind()) |
144 | .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?; | 144 | || ast::Pat::can_cast(n.kind()) |
145 | || ast::SelfParam::can_cast(n.kind()) | ||
146 | })?; | ||
145 | 147 | ||
146 | let ty = match_ast! { | 148 | let ty = match_ast! { |
147 | match node { | 149 | match node { |
148 | ast::Expr(it) => sema.type_of_expr(&it)?, | 150 | ast::Expr(it) => sema.type_of_expr(&it)?, |
149 | ast::Pat(it) => sema.type_of_pat(&it)?, | 151 | ast::Pat(it) => sema.type_of_pat(&it)?, |
152 | ast::SelfParam(self_param) => sema.type_of_self(&self_param)?, | ||
150 | // If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve. | 153 | // If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve. |
151 | // (e.g expanding a builtin macro). So we give up here. | 154 | // (e.g expanding a builtin macro). So we give up here. |
152 | ast::MacroCall(_it) => return None, | 155 | ast::MacroCall(_it) => return None, |
@@ -3282,4 +3285,41 @@ fn main() { | |||
3282 | "#]], | 3285 | "#]], |
3283 | ); | 3286 | ); |
3284 | } | 3287 | } |
3288 | |||
3289 | #[test] | ||
3290 | fn hover_self_param_shows_type() { | ||
3291 | check( | ||
3292 | r#" | ||
3293 | struct Foo {} | ||
3294 | impl Foo { | ||
3295 | fn bar(&sel<|>f) {} | ||
3296 | } | ||
3297 | "#, | ||
3298 | expect![[r#" | ||
3299 | *&self* | ||
3300 | ```rust | ||
3301 | &Foo | ||
3302 | ``` | ||
3303 | "#]], | ||
3304 | ); | ||
3305 | } | ||
3306 | |||
3307 | #[test] | ||
3308 | fn hover_self_param_shows_type_for_arbitrary_self_type() { | ||
3309 | check( | ||
3310 | r#" | ||
3311 | struct Arc<T>(T); | ||
3312 | struct Foo {} | ||
3313 | impl Foo { | ||
3314 | fn bar(sel<|>f: Arc<Foo>) {} | ||
3315 | } | ||
3316 | "#, | ||
3317 | expect![[r#" | ||
3318 | *self: Arc<Foo>* | ||
3319 | ```rust | ||
3320 | Arc<Foo> | ||
3321 | ``` | ||
3322 | "#]], | ||
3323 | ); | ||
3324 | } | ||
3285 | } | 3325 | } |
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 6cfb22e13..65df7979c 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use assists::utils::FamousDefs; | ||
2 | use either::Either; | 1 | use either::Either; |
3 | use hir::{known, Callable, HirDisplay, Semantics}; | 2 | use hir::{known, Callable, HirDisplay, Semantics}; |
3 | use ide_db::helpers::FamousDefs; | ||
4 | use ide_db::RootDatabase; | 4 | use ide_db::RootDatabase; |
5 | use stdx::to_lower_snake_case; | 5 | use stdx::to_lower_snake_case; |
6 | use syntax::{ | 6 | use syntax::{ |
@@ -427,8 +427,8 @@ fn get_callable(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<hir: | |||
427 | 427 | ||
428 | #[cfg(test)] | 428 | #[cfg(test)] |
429 | mod tests { | 429 | mod tests { |
430 | use assists::utils::FamousDefs; | ||
431 | use expect_test::{expect, Expect}; | 430 | use expect_test::{expect, Expect}; |
431 | use ide_db::helpers::FamousDefs; | ||
432 | use test_utils::extract_annotations; | 432 | use test_utils::extract_annotations; |
433 | 433 | ||
434 | use crate::{fixture, inlay_hints::InlayHintsConfig}; | 434 | use crate::{fixture, inlay_hints::InlayHintsConfig}; |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 6288f7ea7..5244bdd61 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -87,9 +87,7 @@ pub use ide_db::{ | |||
87 | search::{Reference, ReferenceAccess, ReferenceKind}, | 87 | search::{Reference, ReferenceAccess, ReferenceKind}, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | pub use assists::{ | 90 | pub use assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist}; |
91 | utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist, | ||
92 | }; | ||
93 | pub use hir::{Documentation, Semantics}; | 91 | pub use hir::{Documentation, Semantics}; |
94 | pub use ide_db::base_db::{ | 92 | pub use ide_db::base_db::{ |
95 | Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, | 93 | Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot, |
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index b8725693a..731457696 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -1,4 +1,9 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | use std::{ | ||
3 | convert::TryInto, | ||
4 | error::Error, | ||
5 | fmt::{self, Display}, | ||
6 | }; | ||
2 | 7 | ||
3 | use hir::{Module, ModuleDef, ModuleSource, Semantics}; | 8 | use hir::{Module, ModuleDef, ModuleSource, Semantics}; |
4 | use ide_db::base_db::{FileRange, SourceDatabaseExt}; | 9 | use ide_db::base_db::{FileRange, SourceDatabaseExt}; |
@@ -6,12 +11,6 @@ use ide_db::{ | |||
6 | defs::{Definition, NameClass, NameRefClass}, | 11 | defs::{Definition, NameClass, NameRefClass}, |
7 | RootDatabase, | 12 | RootDatabase, |
8 | }; | 13 | }; |
9 | |||
10 | use std::{ | ||
11 | convert::TryInto, | ||
12 | error::Error, | ||
13 | fmt::{self, Display}, | ||
14 | }; | ||
15 | use syntax::{ | 14 | use syntax::{ |
16 | algo::find_node_at_offset, | 15 | algo::find_node_at_offset, |
17 | ast::{self, NameOwner}, | 16 | ast::{self, NameOwner}, |
@@ -222,24 +221,47 @@ fn rename_to_self( | |||
222 | let source_file = sema.parse(position.file_id); | 221 | let source_file = sema.parse(position.file_id); |
223 | let syn = source_file.syntax(); | 222 | let syn = source_file.syntax(); |
224 | 223 | ||
225 | let fn_def = find_node_at_offset::<ast::Fn>(syn, position.offset) | 224 | let (fn_def, fn_ast) = find_node_at_offset::<ast::Fn>(syn, position.offset) |
225 | .and_then(|fn_ast| sema.to_def(&fn_ast).zip(Some(fn_ast))) | ||
226 | .ok_or_else(|| RenameError("No surrounding method declaration found".to_string()))?; | 226 | .ok_or_else(|| RenameError("No surrounding method declaration found".to_string()))?; |
227 | let params = | 227 | let param_range = fn_ast |
228 | fn_def.param_list().ok_or_else(|| RenameError("Method has no parameters".to_string()))?; | 228 | .param_list() |
229 | if params.self_param().is_some() { | 229 | .and_then(|p| p.params().next()) |
230 | .ok_or_else(|| RenameError("Method has no parameters".to_string()))? | ||
231 | .syntax() | ||
232 | .text_range(); | ||
233 | if !param_range.contains(position.offset) { | ||
234 | return Err(RenameError("Only the first parameter can be self".to_string())); | ||
235 | } | ||
236 | |||
237 | let impl_block = find_node_at_offset::<ast::Impl>(syn, position.offset) | ||
238 | .and_then(|def| sema.to_def(&def)) | ||
239 | .ok_or_else(|| RenameError("No impl block found for function".to_string()))?; | ||
240 | if fn_def.self_param(sema.db).is_some() { | ||
230 | return Err(RenameError("Method already has a self parameter".to_string())); | 241 | return Err(RenameError("Method already has a self parameter".to_string())); |
231 | } | 242 | } |
243 | |||
244 | let params = fn_def.params(sema.db); | ||
232 | let first_param = | 245 | let first_param = |
233 | params.params().next().ok_or_else(|| RenameError("Method has no parameters".into()))?; | 246 | params.first().ok_or_else(|| RenameError("Method has no parameters".into()))?; |
234 | let mutable = match first_param.ty() { | 247 | let first_param_ty = first_param.ty(); |
235 | Some(ast::Type::RefType(rt)) => rt.mut_token().is_some(), | 248 | let impl_ty = impl_block.target_ty(sema.db); |
236 | _ => return Err(RenameError("Not renaming other types".to_string())), | 249 | let (ty, self_param) = if impl_ty.remove_ref().is_some() { |
250 | // if the impl is a ref to the type we can just match the `&T` with self directly | ||
251 | (first_param_ty.clone(), "self") | ||
252 | } else { | ||
253 | first_param_ty.remove_ref().map_or((first_param_ty.clone(), "self"), |ty| { | ||
254 | (ty, if first_param_ty.is_mutable_reference() { "&mut self" } else { "&self" }) | ||
255 | }) | ||
237 | }; | 256 | }; |
238 | 257 | ||
258 | if ty != impl_ty { | ||
259 | return Err(RenameError("Parameter type differs from impl block type".to_string())); | ||
260 | } | ||
261 | |||
239 | let RangeInfo { range, info: refs } = find_all_refs(sema, position, None) | 262 | let RangeInfo { range, info: refs } = find_all_refs(sema, position, None) |
240 | .ok_or_else(|| RenameError("No reference found at position".to_string()))?; | 263 | .ok_or_else(|| RenameError("No reference found at position".to_string()))?; |
241 | 264 | ||
242 | let param_range = first_param.syntax().text_range(); | ||
243 | let (param_ref, usages): (Vec<Reference>, Vec<Reference>) = refs | 265 | let (param_ref, usages): (Vec<Reference>, Vec<Reference>) = refs |
244 | .into_iter() | 266 | .into_iter() |
245 | .partition(|reference| param_range.intersect(reference.file_range.range).is_some()); | 267 | .partition(|reference| param_range.intersect(reference.file_range.range).is_some()); |
@@ -255,10 +277,7 @@ fn rename_to_self( | |||
255 | 277 | ||
256 | edits.push(SourceFileEdit { | 278 | edits.push(SourceFileEdit { |
257 | file_id: position.file_id, | 279 | file_id: position.file_id, |
258 | edit: TextEdit::replace( | 280 | edit: TextEdit::replace(param_range, String::from(self_param)), |
259 | param_range, | ||
260 | String::from(if mutable { "&mut self" } else { "&self" }), | ||
261 | ), | ||
262 | }); | 281 | }); |
263 | 282 | ||
264 | Ok(RangeInfo::new(range, SourceChange::from(edits))) | 283 | Ok(RangeInfo::new(range, SourceChange::from(edits))) |
@@ -281,7 +300,11 @@ fn text_edit_from_self_param( | |||
281 | 300 | ||
282 | let mut replacement_text = String::from(new_name); | 301 | let mut replacement_text = String::from(new_name); |
283 | replacement_text.push_str(": "); | 302 | replacement_text.push_str(": "); |
284 | replacement_text.push_str(self_param.mut_token().map_or("&", |_| "&mut ")); | 303 | match (self_param.amp_token(), self_param.mut_token()) { |
304 | (None, None) => (), | ||
305 | (Some(_), None) => replacement_text.push('&'), | ||
306 | (_, Some(_)) => replacement_text.push_str("&mut "), | ||
307 | }; | ||
285 | replacement_text.push_str(type_name.as_str()); | 308 | replacement_text.push_str(type_name.as_str()); |
286 | 309 | ||
287 | Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text)) | 310 | Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text)) |
@@ -1083,6 +1106,95 @@ impl Foo { | |||
1083 | } | 1106 | } |
1084 | "#, | 1107 | "#, |
1085 | ); | 1108 | ); |
1109 | check( | ||
1110 | "self", | ||
1111 | r#" | ||
1112 | struct Foo { i: i32 } | ||
1113 | |||
1114 | impl Foo { | ||
1115 | fn f(foo<|>: Foo) -> i32 { | ||
1116 | foo.i | ||
1117 | } | ||
1118 | } | ||
1119 | "#, | ||
1120 | r#" | ||
1121 | struct Foo { i: i32 } | ||
1122 | |||
1123 | impl Foo { | ||
1124 | fn f(self) -> i32 { | ||
1125 | self.i | ||
1126 | } | ||
1127 | } | ||
1128 | "#, | ||
1129 | ); | ||
1130 | } | ||
1131 | |||
1132 | #[test] | ||
1133 | fn test_parameter_to_self_error_no_impl() { | ||
1134 | check( | ||
1135 | "self", | ||
1136 | r#" | ||
1137 | struct Foo { i: i32 } | ||
1138 | |||
1139 | fn f(foo<|>: &mut Foo) -> i32 { | ||
1140 | foo.i | ||
1141 | } | ||
1142 | "#, | ||
1143 | "error: No impl block found for function", | ||
1144 | ); | ||
1145 | check( | ||
1146 | "self", | ||
1147 | r#" | ||
1148 | struct Foo { i: i32 } | ||
1149 | struct Bar; | ||
1150 | |||
1151 | impl Bar { | ||
1152 | fn f(foo<|>: &mut Foo) -> i32 { | ||
1153 | foo.i | ||
1154 | } | ||
1155 | } | ||
1156 | "#, | ||
1157 | "error: Parameter type differs from impl block type", | ||
1158 | ); | ||
1159 | } | ||
1160 | |||
1161 | #[test] | ||
1162 | fn test_parameter_to_self_error_not_first() { | ||
1163 | check( | ||
1164 | "self", | ||
1165 | r#" | ||
1166 | struct Foo { i: i32 } | ||
1167 | impl Foo { | ||
1168 | fn f(x: (), foo<|>: &mut Foo) -> i32 { | ||
1169 | foo.i | ||
1170 | } | ||
1171 | } | ||
1172 | "#, | ||
1173 | "error: Only the first parameter can be self", | ||
1174 | ); | ||
1175 | } | ||
1176 | |||
1177 | #[test] | ||
1178 | fn test_parameter_to_self_impl_ref() { | ||
1179 | check( | ||
1180 | "self", | ||
1181 | r#" | ||
1182 | struct Foo { i: i32 } | ||
1183 | impl &Foo { | ||
1184 | fn f(foo<|>: &Foo) -> i32 { | ||
1185 | foo.i | ||
1186 | } | ||
1187 | } | ||
1188 | "#, | ||
1189 | r#" | ||
1190 | struct Foo { i: i32 } | ||
1191 | impl &Foo { | ||
1192 | fn f(self) -> i32 { | ||
1193 | self.i | ||
1194 | } | ||
1195 | } | ||
1196 | "#, | ||
1197 | ); | ||
1086 | } | 1198 | } |
1087 | 1199 | ||
1088 | #[test] | 1200 | #[test] |
@@ -1111,6 +1223,31 @@ impl Foo { | |||
1111 | } | 1223 | } |
1112 | 1224 | ||
1113 | #[test] | 1225 | #[test] |
1226 | fn test_owned_self_to_parameter() { | ||
1227 | check( | ||
1228 | "foo", | ||
1229 | r#" | ||
1230 | struct Foo { i: i32 } | ||
1231 | |||
1232 | impl Foo { | ||
1233 | fn f(<|>self) -> i32 { | ||
1234 | self.i | ||
1235 | } | ||
1236 | } | ||
1237 | "#, | ||
1238 | r#" | ||
1239 | struct Foo { i: i32 } | ||
1240 | |||
1241 | impl Foo { | ||
1242 | fn f(foo: Foo) -> i32 { | ||
1243 | foo.i | ||
1244 | } | ||
1245 | } | ||
1246 | "#, | ||
1247 | ); | ||
1248 | } | ||
1249 | |||
1250 | #[test] | ||
1114 | fn test_self_in_path_to_parameter() { | 1251 | fn test_self_in_path_to_parameter() { |
1115 | check( | 1252 | check( |
1116 | "foo", | 1253 | "foo", |
diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs index 8e91c99d7..e10d7c3a4 100644 --- a/crates/ide/src/status.rs +++ b/crates/ide/src/status.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::{fmt, iter::FromIterator, sync::Arc}; | 1 | use std::{fmt, iter::FromIterator, sync::Arc}; |
2 | 2 | ||
3 | use hir::MacroFile; | 3 | use hir::{ExpandResult, MacroFile}; |
4 | use ide_db::base_db::{ | 4 | use ide_db::base_db::{ |
5 | salsa::debug::{DebugQueryTable, TableEntry}, | 5 | salsa::debug::{DebugQueryTable, TableEntry}, |
6 | CrateId, FileId, FileTextQuery, SourceDatabase, SourceRootId, | 6 | CrateId, FileId, FileTextQuery, SourceDatabase, SourceRootId, |
@@ -19,7 +19,7 @@ fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { | |||
19 | ide_db::base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>() | 19 | ide_db::base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>() |
20 | } | 20 | } |
21 | fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { | 21 | fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats { |
22 | hir::db::ParseMacroQuery.in_db(db).entries::<SyntaxTreeStats>() | 22 | hir::db::ParseMacroExpansionQuery.in_db(db).entries::<SyntaxTreeStats>() |
23 | } | 23 | } |
24 | 24 | ||
25 | // Feature: Status | 25 | // Feature: Status |
@@ -115,10 +115,12 @@ impl FromIterator<TableEntry<FileId, Parse<ast::SourceFile>>> for SyntaxTreeStat | |||
115 | } | 115 | } |
116 | } | 116 | } |
117 | 117 | ||
118 | impl<M> FromIterator<TableEntry<MacroFile, Option<(Parse<SyntaxNode>, M)>>> for SyntaxTreeStats { | 118 | impl<M> FromIterator<TableEntry<MacroFile, ExpandResult<Option<(Parse<SyntaxNode>, M)>>>> |
119 | for SyntaxTreeStats | ||
120 | { | ||
119 | fn from_iter<T>(iter: T) -> SyntaxTreeStats | 121 | fn from_iter<T>(iter: T) -> SyntaxTreeStats |
120 | where | 122 | where |
121 | T: IntoIterator<Item = TableEntry<MacroFile, Option<(Parse<SyntaxNode>, M)>>>, | 123 | T: IntoIterator<Item = TableEntry<MacroFile, ExpandResult<Option<(Parse<SyntaxNode>, M)>>>>, |
122 | { | 124 | { |
123 | let mut res = SyntaxTreeStats::default(); | 125 | let mut res = SyntaxTreeStats::default(); |
124 | for entry in iter { | 126 | for entry in iter { |