diff options
-rw-r--r-- | crates/completion/src/completions/attribute.rs | 14 | ||||
-rw-r--r-- | crates/hir/src/code_model.rs | 18 | ||||
-rw-r--r-- | crates/ide/src/display/navigation_target.rs | 14 | ||||
-rw-r--r-- | crates/ide/src/doc_links.rs | 30 | ||||
-rw-r--r-- | crates/ide/src/goto_definition.rs | 88 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 16 | ||||
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 26 | ||||
-rw-r--r-- | crates/ide/src/references.rs | 5 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/highlight.rs | 8 | ||||
-rw-r--r-- | crates/ide_db/src/defs.rs | 36 | ||||
-rw-r--r-- | crates/ide_db/src/search.rs | 2 |
11 files changed, 200 insertions, 57 deletions
diff --git a/crates/completion/src/completions/attribute.rs b/crates/completion/src/completions/attribute.rs index 3a29b5203..a52ca107e 100644 --- a/crates/completion/src/completions/attribute.rs +++ b/crates/completion/src/completions/attribute.rs | |||
@@ -21,15 +21,17 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) | |||
21 | 21 | ||
22 | let attribute = ctx.attribute_under_caret.as_ref()?; | 22 | let attribute = ctx.attribute_under_caret.as_ref()?; |
23 | match (attribute.path(), attribute.token_tree()) { | 23 | match (attribute.path(), attribute.token_tree()) { |
24 | (Some(path), Some(token_tree)) => match path.to_string().as_str() { | 24 | (Some(path), Some(token_tree)) => { |
25 | "derive" => complete_derive(acc, ctx, token_tree), | 25 | let path = path.syntax().text(); |
26 | "feature" => complete_lint(acc, ctx, token_tree, FEATURES), | 26 | if path == "derive" { |
27 | "allow" | "warn" | "deny" | "forbid" => { | 27 | complete_derive(acc, ctx, token_tree) |
28 | } else if path == "feature" { | ||
29 | complete_lint(acc, ctx, token_tree, FEATURES) | ||
30 | } else if path == "allow" || path == "warn" || path == "deny" || path == "forbid" { | ||
28 | complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINT_COMPLETIONS); | 31 | complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINT_COMPLETIONS); |
29 | complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); | 32 | complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); |
30 | } | 33 | } |
31 | _ => {} | 34 | } |
32 | }, | ||
33 | (_, Some(_token_tree)) => {} | 35 | (_, Some(_token_tree)) => {} |
34 | _ => complete_attribute_start(acc, ctx, attribute), | 36 | _ => complete_attribute_start(acc, ctx, attribute), |
35 | } | 37 | } |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index cc1938333..6cbf5cecf 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -1263,6 +1263,24 @@ pub enum GenericParam { | |||
1263 | } | 1263 | } |
1264 | impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam); | 1264 | impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam); |
1265 | 1265 | ||
1266 | impl GenericParam { | ||
1267 | pub fn module(self, db: &dyn HirDatabase) -> Module { | ||
1268 | match self { | ||
1269 | GenericParam::TypeParam(it) => it.module(db), | ||
1270 | GenericParam::LifetimeParam(it) => it.module(db), | ||
1271 | GenericParam::ConstParam(it) => it.module(db), | ||
1272 | } | ||
1273 | } | ||
1274 | |||
1275 | pub fn name(self, db: &dyn HirDatabase) -> Name { | ||
1276 | match self { | ||
1277 | GenericParam::TypeParam(it) => it.name(db), | ||
1278 | GenericParam::LifetimeParam(it) => it.name(db), | ||
1279 | GenericParam::ConstParam(it) => it.name(db), | ||
1280 | } | ||
1281 | } | ||
1282 | } | ||
1283 | |||
1266 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1284 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1267 | pub struct TypeParam { | 1285 | pub struct TypeParam { |
1268 | pub(crate) id: TypeParamId, | 1286 | pub(crate) id: TypeParamId, |
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index e24c78301..4eecae697 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs | |||
@@ -215,10 +215,8 @@ impl TryToNav for Definition { | |||
215 | Definition::ModuleDef(it) => it.try_to_nav(db), | 215 | Definition::ModuleDef(it) => it.try_to_nav(db), |
216 | Definition::SelfType(it) => it.try_to_nav(db), | 216 | Definition::SelfType(it) => it.try_to_nav(db), |
217 | Definition::Local(it) => Some(it.to_nav(db)), | 217 | Definition::Local(it) => Some(it.to_nav(db)), |
218 | Definition::TypeParam(it) => it.try_to_nav(db), | 218 | Definition::GenericParam(it) => it.try_to_nav(db), |
219 | Definition::LifetimeParam(it) => it.try_to_nav(db), | ||
220 | Definition::Label(it) => Some(it.to_nav(db)), | 219 | Definition::Label(it) => Some(it.to_nav(db)), |
221 | Definition::ConstParam(it) => it.try_to_nav(db), | ||
222 | } | 220 | } |
223 | } | 221 | } |
224 | } | 222 | } |
@@ -389,6 +387,16 @@ impl TryToNav for hir::AssocItem { | |||
389 | } | 387 | } |
390 | } | 388 | } |
391 | 389 | ||
390 | impl TryToNav for hir::GenericParam { | ||
391 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { | ||
392 | match self { | ||
393 | hir::GenericParam::TypeParam(it) => it.try_to_nav(db), | ||
394 | hir::GenericParam::ConstParam(it) => it.try_to_nav(db), | ||
395 | hir::GenericParam::LifetimeParam(it) => it.try_to_nav(db), | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | |||
392 | impl ToNav for hir::Local { | 400 | impl ToNav for hir::Local { |
393 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 401 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
394 | let src = self.source(db); | 402 | let src = self.source(db); |
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 1ff818de2..91f4241f9 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! Resolves and rewrites links in markdown documentation. | 1 | //! Resolves and rewrites links in markdown documentation. |
2 | 2 | ||
3 | use std::{convert::TryFrom, iter::once}; | 3 | use std::{convert::TryFrom, iter::once, ops::Range}; |
4 | 4 | ||
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; | 6 | use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; |
@@ -61,6 +61,30 @@ pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Defi | |||
61 | out | 61 | out |
62 | } | 62 | } |
63 | 63 | ||
64 | pub(crate) fn extract_definitions_from_markdown( | ||
65 | markdown: &str, | ||
66 | ) -> Vec<(String, Option<hir::Namespace>, Range<usize>)> { | ||
67 | let mut res = vec![]; | ||
68 | let mut cb = |link: BrokenLink| { | ||
69 | Some(( | ||
70 | /*url*/ link.reference.to_owned().into(), | ||
71 | /*title*/ link.reference.to_owned().into(), | ||
72 | )) | ||
73 | }; | ||
74 | let doc = Parser::new_with_broken_link_callback(markdown, Options::empty(), Some(&mut cb)); | ||
75 | for (event, range) in doc.into_offset_iter() { | ||
76 | match event { | ||
77 | Event::Start(Tag::Link(_link_type, ref target, ref title)) => { | ||
78 | let link = if target.is_empty() { title } else { target }; | ||
79 | let (link, ns) = parse_link(link); | ||
80 | res.push((link.to_string(), ns, range)); | ||
81 | } | ||
82 | _ => {} | ||
83 | } | ||
84 | } | ||
85 | res | ||
86 | } | ||
87 | |||
64 | /// Remove all links in markdown documentation. | 88 | /// Remove all links in markdown documentation. |
65 | pub(crate) fn remove_links(markdown: &str) -> String { | 89 | pub(crate) fn remove_links(markdown: &str) -> String { |
66 | let mut drop_link = false; | 90 | let mut drop_link = false; |
@@ -192,9 +216,7 @@ fn rewrite_intra_doc_link( | |||
192 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), | 216 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), |
193 | Definition::SelfType(_) | 217 | Definition::SelfType(_) |
194 | | Definition::Local(_) | 218 | | Definition::Local(_) |
195 | | Definition::TypeParam(_) | 219 | | Definition::GenericParam(_) |
196 | | Definition::ConstParam(_) | ||
197 | | Definition::LifetimeParam(_) | ||
198 | | Definition::Label(_) => return None, | 220 | | Definition::Label(_) => return None, |
199 | }?; | 221 | }?; |
200 | let krate = resolved.module(db)?.krate(); | 222 | let krate = resolved.module(db)?.krate(); |
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 95b4cb9e3..c20185b16 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -1,14 +1,20 @@ | |||
1 | use either::Either; | 1 | use either::Either; |
2 | use hir::Semantics; | 2 | use hir::{HasAttrs, ModuleDef, Semantics}; |
3 | use ide_db::{ | 3 | use ide_db::{ |
4 | base_db::FileId, | 4 | base_db::FileId, |
5 | defs::{NameClass, NameRefClass}, | 5 | defs::{Definition, NameClass, NameRefClass}, |
6 | symbol_index, RootDatabase, | 6 | symbol_index, RootDatabase, |
7 | }; | 7 | }; |
8 | use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; | 8 | use syntax::{ |
9 | ast::{self, NameOwner}, | ||
10 | match_ast, AstNode, AstToken, | ||
11 | SyntaxKind::*, | ||
12 | SyntaxToken, TextSize, TokenAtOffset, T, | ||
13 | }; | ||
9 | 14 | ||
10 | use crate::{ | 15 | use crate::{ |
11 | display::{ToNav, TryToNav}, | 16 | display::{ToNav, TryToNav}, |
17 | doc_links::extract_definitions_from_markdown, | ||
12 | FilePosition, NavigationTarget, RangeInfo, SymbolKind, | 18 | FilePosition, NavigationTarget, RangeInfo, SymbolKind, |
13 | }; | 19 | }; |
14 | 20 | ||
@@ -30,6 +36,10 @@ pub(crate) fn goto_definition( | |||
30 | let original_token = pick_best(file.token_at_offset(position.offset))?; | 36 | let original_token = pick_best(file.token_at_offset(position.offset))?; |
31 | let token = sema.descend_into_macros(original_token.clone()); | 37 | let token = sema.descend_into_macros(original_token.clone()); |
32 | let parent = token.parent(); | 38 | let parent = token.parent(); |
39 | if let Some(comment) = ast::Comment::cast(token.clone()) { | ||
40 | let nav = def_for_doc_comment(&sema, position, &comment)?.try_to_nav(db)?; | ||
41 | return Some(RangeInfo::new(original_token.text_range(), vec![nav])); | ||
42 | } | ||
33 | 43 | ||
34 | let nav_targets = match_ast! { | 44 | let nav_targets = match_ast! { |
35 | match parent { | 45 | match parent { |
@@ -68,11 +78,66 @@ pub(crate) fn goto_definition( | |||
68 | Some(RangeInfo::new(original_token.text_range(), nav_targets)) | 78 | Some(RangeInfo::new(original_token.text_range(), nav_targets)) |
69 | } | 79 | } |
70 | 80 | ||
81 | fn def_for_doc_comment( | ||
82 | sema: &Semantics<RootDatabase>, | ||
83 | position: FilePosition, | ||
84 | doc_comment: &ast::Comment, | ||
85 | ) -> Option<hir::ModuleDef> { | ||
86 | let parent = doc_comment.syntax().parent(); | ||
87 | let db = sema.db; | ||
88 | let (link, ns) = extract_positioned_link_from_comment(position, doc_comment)?; | ||
89 | let link = &link; | ||
90 | let name = match_ast! { | ||
91 | match parent { | ||
92 | ast::Name(name) => Some(name), | ||
93 | ast::Fn(func) => func.name(), | ||
94 | _ => None, | ||
95 | } | ||
96 | }?; | ||
97 | let definition = NameClass::classify(&sema, &name).and_then(|d| d.defined(sema.db))?; | ||
98 | match definition { | ||
99 | Definition::ModuleDef(def) => match def { | ||
100 | ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns), | ||
101 | ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns), | ||
102 | ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns), | ||
103 | ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns), | ||
104 | ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns), | ||
105 | ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns), | ||
106 | ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns), | ||
107 | ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, link, ns), | ||
108 | ModuleDef::BuiltinType(_) => return None, | ||
109 | }, | ||
110 | Definition::Macro(it) => it.resolve_doc_path(db, link, ns), | ||
111 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), | ||
112 | Definition::SelfType(_) | ||
113 | | Definition::Local(_) | ||
114 | | Definition::GenericParam(_) | ||
115 | | Definition::Label(_) => return None, | ||
116 | } | ||
117 | } | ||
118 | |||
119 | fn extract_positioned_link_from_comment( | ||
120 | position: FilePosition, | ||
121 | comment: &ast::Comment, | ||
122 | ) -> Option<(String, Option<hir::Namespace>)> { | ||
123 | let comment_range = comment.syntax().text_range(); | ||
124 | let doc_comment = comment.doc_comment()?; | ||
125 | let def_links = extract_definitions_from_markdown(doc_comment); | ||
126 | let (def_link, ns, _) = def_links.iter().min_by_key(|(_, _, def_link_range)| { | ||
127 | let matched_position = comment_range.start() + TextSize::from(def_link_range.start as u32); | ||
128 | match position.offset.checked_sub(matched_position) { | ||
129 | Some(distance) => distance, | ||
130 | None => comment_range.end(), | ||
131 | } | ||
132 | })?; | ||
133 | Some((def_link.to_string(), ns.clone())) | ||
134 | } | ||
135 | |||
71 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | 136 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { |
72 | return tokens.max_by_key(priority); | 137 | return tokens.max_by_key(priority); |
73 | fn priority(n: &SyntaxToken) -> usize { | 138 | fn priority(n: &SyntaxToken) -> usize { |
74 | match n.kind() { | 139 | match n.kind() { |
75 | IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 2, | 140 | IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | COMMENT => 2, |
76 | kind if kind.is_trivia() => 0, | 141 | kind if kind.is_trivia() => 0, |
77 | _ => 1, | 142 | _ => 1, |
78 | } | 143 | } |
@@ -1145,4 +1210,19 @@ fn foo<'foo>(_: &'foo ()) { | |||
1145 | }"#, | 1210 | }"#, |
1146 | ) | 1211 | ) |
1147 | } | 1212 | } |
1213 | |||
1214 | #[test] | ||
1215 | fn goto_def_for_intra_rustdoc_link_same_file() { | ||
1216 | check( | ||
1217 | r#" | ||
1218 | /// Blah, [`bar`](bar) .. [`foo`](foo)$0 has [`bar`](bar) | ||
1219 | pub fn bar() { } | ||
1220 | |||
1221 | /// You might want to see [`std::fs::read()`] too. | ||
1222 | pub fn foo() { } | ||
1223 | //^^^ | ||
1224 | |||
1225 | }"#, | ||
1226 | ) | ||
1227 | } | ||
1148 | } | 1228 | } |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 939efa43f..e331f8886 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use hir::{ | 1 | use hir::{ |
2 | Adt, AsAssocItem, AssocItemContainer, FieldSource, HasAttrs, HasSource, HirDisplay, Module, | 2 | Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource, |
3 | ModuleDef, ModuleSource, Semantics, | 3 | HirDisplay, Module, ModuleDef, ModuleSource, Semantics, |
4 | }; | 4 | }; |
5 | use ide_db::base_db::SourceDatabase; | 5 | use ide_db::base_db::SourceDatabase; |
6 | use ide_db::{ | 6 | use ide_db::{ |
@@ -220,12 +220,12 @@ fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { | |||
220 | } | 220 | } |
221 | }; | 221 | }; |
222 | 222 | ||
223 | if let Definition::TypeParam(it) = def { | 223 | if let Definition::GenericParam(GenericParam::TypeParam(it)) = def { |
224 | it.trait_bounds(db).into_iter().for_each(|it| push_new_def(it.into())); | 224 | it.trait_bounds(db).into_iter().for_each(|it| push_new_def(it.into())); |
225 | } else { | 225 | } else { |
226 | let ty = match def { | 226 | let ty = match def { |
227 | Definition::Local(it) => it.ty(db), | 227 | Definition::Local(it) => it.ty(db), |
228 | Definition::ConstParam(it) => it.ty(db), | 228 | Definition::GenericParam(GenericParam::ConstParam(it)) => it.ty(db), |
229 | _ => return None, | 229 | _ => return None, |
230 | }; | 230 | }; |
231 | 231 | ||
@@ -357,9 +357,11 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
357 | }) | 357 | }) |
358 | } | 358 | } |
359 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), | 359 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), |
360 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), | 360 | Definition::GenericParam(it) => match it { |
361 | Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))), | 361 | GenericParam::TypeParam(it) => Some(Markup::fenced_block(&it.display(db))), |
362 | Definition::ConstParam(it) => from_def_source(db, it, None), | 362 | GenericParam::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), |
363 | GenericParam::ConstParam(it) => from_def_source(db, it, None), | ||
364 | }, | ||
363 | }; | 365 | }; |
364 | 366 | ||
365 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> | 367 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> |
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index a74829cd0..3e9a65d9c 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -353,13 +353,25 @@ fn is_argument_similar_to_param_name( | |||
353 | } | 353 | } |
354 | match get_string_representation(argument) { | 354 | match get_string_representation(argument) { |
355 | None => false, | 355 | None => false, |
356 | Some(mut repr) => { | 356 | Some(argument_string) => { |
357 | let param_name = param_name.to_ascii_lowercase(); | 357 | let num_leading_underscores = |
358 | let argument_string = { | 358 | argument_string.bytes().take_while(|&c| c == b'_').count(); |
359 | repr.make_ascii_lowercase(); | 359 | |
360 | repr.trim_start_matches('_') | 360 | // Does the argument name begin with the parameter name? Ignore leading underscores. |
361 | }; | 361 | let mut arg_bytes = argument_string.bytes().skip(num_leading_underscores); |
362 | argument_string.starts_with(¶m_name) || argument_string.ends_with(¶m_name) | 362 | let starts_with_pattern = param_name.bytes().all( |
363 | |expected| matches!(arg_bytes.next(), Some(actual) if expected.eq_ignore_ascii_case(&actual)), | ||
364 | ); | ||
365 | |||
366 | if starts_with_pattern { | ||
367 | return true; | ||
368 | } | ||
369 | |||
370 | // Does the argument name end with the parameter name? | ||
371 | let mut arg_bytes = argument_string.bytes().skip(num_leading_underscores); | ||
372 | param_name.bytes().rev().all( | ||
373 | |expected| matches!(arg_bytes.next_back(), Some(actual) if expected.eq_ignore_ascii_case(&actual)), | ||
374 | ) | ||
363 | } | 375 | } |
364 | } | 376 | } |
365 | } | 377 | } |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index c95ed669c..0d5cd5f9a 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -130,7 +130,10 @@ pub(crate) fn find_all_refs( | |||
130 | kind = ReferenceKind::FieldShorthandForLocal; | 130 | kind = ReferenceKind::FieldShorthandForLocal; |
131 | } | 131 | } |
132 | } | 132 | } |
133 | } else if matches!(def, Definition::LifetimeParam(_) | Definition::Label(_)) { | 133 | } else if matches!( |
134 | def, | ||
135 | Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_) | ||
136 | ) { | ||
134 | kind = ReferenceKind::Lifetime; | 137 | kind = ReferenceKind::Lifetime; |
135 | }; | 138 | }; |
136 | 139 | ||
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 1a88975d2..20eccf3c6 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs | |||
@@ -328,8 +328,11 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
328 | } | 328 | } |
329 | }, | 329 | }, |
330 | Definition::SelfType(_) => HlTag::Symbol(SymbolKind::Impl), | 330 | Definition::SelfType(_) => HlTag::Symbol(SymbolKind::Impl), |
331 | Definition::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), | 331 | Definition::GenericParam(it) => match it { |
332 | Definition::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), | 332 | hir::GenericParam::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), |
333 | hir::GenericParam::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), | ||
334 | hir::GenericParam::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), | ||
335 | }, | ||
333 | Definition::Local(local) => { | 336 | Definition::Local(local) => { |
334 | let tag = if local.is_param(db) { | 337 | let tag = if local.is_param(db) { |
335 | HlTag::Symbol(SymbolKind::ValueParam) | 338 | HlTag::Symbol(SymbolKind::ValueParam) |
@@ -345,7 +348,6 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | |||
345 | } | 348 | } |
346 | return h; | 349 | return h; |
347 | } | 350 | } |
348 | Definition::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), | ||
349 | Definition::Label(_) => HlTag::Symbol(SymbolKind::Label), | 351 | Definition::Label(_) => HlTag::Symbol(SymbolKind::Label), |
350 | } | 352 | } |
351 | .into() | 353 | .into() |
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index be1c64b03..d68fe42b0 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -6,8 +6,8 @@ | |||
6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). | 6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). |
7 | 7 | ||
8 | use hir::{ | 8 | use hir::{ |
9 | db::HirDatabase, ConstParam, Crate, Field, HasVisibility, Impl, Label, LifetimeParam, Local, | 9 | db::HirDatabase, Crate, Field, GenericParam, HasVisibility, Impl, Label, Local, MacroDef, |
10 | MacroDef, Module, ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility, | 10 | Module, ModuleDef, Name, PathResolution, Semantics, Visibility, |
11 | }; | 11 | }; |
12 | use syntax::{ | 12 | use syntax::{ |
13 | ast::{self, AstNode}, | 13 | ast::{self, AstNode}, |
@@ -24,9 +24,7 @@ pub enum Definition { | |||
24 | ModuleDef(ModuleDef), | 24 | ModuleDef(ModuleDef), |
25 | SelfType(Impl), | 25 | SelfType(Impl), |
26 | Local(Local), | 26 | Local(Local), |
27 | TypeParam(TypeParam), | 27 | GenericParam(GenericParam), |
28 | LifetimeParam(LifetimeParam), | ||
29 | ConstParam(ConstParam), | ||
30 | Label(Label), | 28 | Label(Label), |
31 | } | 29 | } |
32 | 30 | ||
@@ -38,9 +36,7 @@ impl Definition { | |||
38 | Definition::ModuleDef(it) => it.module(db), | 36 | Definition::ModuleDef(it) => it.module(db), |
39 | Definition::SelfType(it) => Some(it.module(db)), | 37 | Definition::SelfType(it) => Some(it.module(db)), |
40 | Definition::Local(it) => Some(it.module(db)), | 38 | Definition::Local(it) => Some(it.module(db)), |
41 | Definition::TypeParam(it) => Some(it.module(db)), | 39 | Definition::GenericParam(it) => Some(it.module(db)), |
42 | Definition::LifetimeParam(it) => Some(it.module(db)), | ||
43 | Definition::ConstParam(it) => Some(it.module(db)), | ||
44 | Definition::Label(it) => Some(it.module(db)), | 40 | Definition::Label(it) => Some(it.module(db)), |
45 | } | 41 | } |
46 | } | 42 | } |
@@ -52,9 +48,7 @@ impl Definition { | |||
52 | Definition::ModuleDef(def) => def.definition_visibility(db), | 48 | Definition::ModuleDef(def) => def.definition_visibility(db), |
53 | Definition::SelfType(_) => None, | 49 | Definition::SelfType(_) => None, |
54 | Definition::Local(_) => None, | 50 | Definition::Local(_) => None, |
55 | Definition::TypeParam(_) => None, | 51 | Definition::GenericParam(_) => None, |
56 | Definition::LifetimeParam(_) => None, | ||
57 | Definition::ConstParam(_) => None, | ||
58 | Definition::Label(_) => None, | 52 | Definition::Label(_) => None, |
59 | } | 53 | } |
60 | } | 54 | } |
@@ -80,9 +74,7 @@ impl Definition { | |||
80 | }, | 74 | }, |
81 | Definition::SelfType(_) => return None, | 75 | Definition::SelfType(_) => return None, |
82 | Definition::Local(it) => it.name(db)?, | 76 | Definition::Local(it) => it.name(db)?, |
83 | Definition::TypeParam(it) => it.name(db), | 77 | Definition::GenericParam(it) => it.name(db), |
84 | Definition::LifetimeParam(it) => it.name(db), | ||
85 | Definition::ConstParam(it) => it.name(db), | ||
86 | Definition::Label(it) => it.name(db), | 78 | Definition::Label(it) => it.name(db), |
87 | }; | 79 | }; |
88 | Some(name) | 80 | Some(name) |
@@ -235,11 +227,11 @@ impl NameClass { | |||
235 | }, | 227 | }, |
236 | ast::TypeParam(it) => { | 228 | ast::TypeParam(it) => { |
237 | let def = sema.to_def(&it)?; | 229 | let def = sema.to_def(&it)?; |
238 | Some(NameClass::Definition(Definition::TypeParam(def))) | 230 | Some(NameClass::Definition(Definition::GenericParam(def.into()))) |
239 | }, | 231 | }, |
240 | ast::ConstParam(it) => { | 232 | ast::ConstParam(it) => { |
241 | let def = sema.to_def(&it)?; | 233 | let def = sema.to_def(&it)?; |
242 | Some(NameClass::Definition(Definition::ConstParam(def))) | 234 | Some(NameClass::Definition(Definition::GenericParam(def.into()))) |
243 | }, | 235 | }, |
244 | _ => None, | 236 | _ => None, |
245 | } | 237 | } |
@@ -257,7 +249,7 @@ impl NameClass { | |||
257 | match parent { | 249 | match parent { |
258 | ast::LifetimeParam(it) => { | 250 | ast::LifetimeParam(it) => { |
259 | let def = sema.to_def(&it)?; | 251 | let def = sema.to_def(&it)?; |
260 | Some(NameClass::Definition(Definition::LifetimeParam(def))) | 252 | Some(NameClass::Definition(Definition::GenericParam(def.into()))) |
261 | }, | 253 | }, |
262 | ast::Label(it) => { | 254 | ast::Label(it) => { |
263 | let def = sema.to_def(&it)?; | 255 | let def = sema.to_def(&it)?; |
@@ -393,7 +385,8 @@ impl NameRefClass { | |||
393 | | SyntaxKind::WHERE_PRED | 385 | | SyntaxKind::WHERE_PRED |
394 | | SyntaxKind::REF_TYPE => sema | 386 | | SyntaxKind::REF_TYPE => sema |
395 | .resolve_lifetime_param(lifetime) | 387 | .resolve_lifetime_param(lifetime) |
396 | .map(Definition::LifetimeParam) | 388 | .map(GenericParam::LifetimeParam) |
389 | .map(Definition::GenericParam) | ||
397 | .map(NameRefClass::Definition), | 390 | .map(NameRefClass::Definition), |
398 | // lifetime bounds, as in the 'b in 'a: 'b aren't wrapped in TypeBound nodes so we gotta check | 391 | // lifetime bounds, as in the 'b in 'a: 'b aren't wrapped in TypeBound nodes so we gotta check |
399 | // if our lifetime is in a LifetimeParam without being the constrained lifetime | 392 | // if our lifetime is in a LifetimeParam without being the constrained lifetime |
@@ -401,7 +394,8 @@ impl NameRefClass { | |||
401 | != Some(lifetime) => | 394 | != Some(lifetime) => |
402 | { | 395 | { |
403 | sema.resolve_lifetime_param(lifetime) | 396 | sema.resolve_lifetime_param(lifetime) |
404 | .map(Definition::LifetimeParam) | 397 | .map(GenericParam::LifetimeParam) |
398 | .map(Definition::GenericParam) | ||
405 | .map(NameRefClass::Definition) | 399 | .map(NameRefClass::Definition) |
406 | } | 400 | } |
407 | _ => None, | 401 | _ => None, |
@@ -422,10 +416,10 @@ impl From<PathResolution> for Definition { | |||
422 | Definition::ModuleDef(def) | 416 | Definition::ModuleDef(def) |
423 | } | 417 | } |
424 | PathResolution::Local(local) => Definition::Local(local), | 418 | PathResolution::Local(local) => Definition::Local(local), |
425 | PathResolution::TypeParam(par) => Definition::TypeParam(par), | 419 | PathResolution::TypeParam(par) => Definition::GenericParam(par.into()), |
426 | PathResolution::Macro(def) => Definition::Macro(def), | 420 | PathResolution::Macro(def) => Definition::Macro(def), |
427 | PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), | 421 | PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), |
428 | PathResolution::ConstParam(par) => Definition::ConstParam(par), | 422 | PathResolution::ConstParam(par) => Definition::GenericParam(par.into()), |
429 | } | 423 | } |
430 | } | 424 | } |
431 | } | 425 | } |
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 37b06027c..773bfbc2c 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -136,7 +136,7 @@ impl Definition { | |||
136 | return SearchScope::new(res); | 136 | return SearchScope::new(res); |
137 | } | 137 | } |
138 | 138 | ||
139 | if let Definition::LifetimeParam(param) = self { | 139 | if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self { |
140 | let range = match param.parent(db) { | 140 | let range = match param.parent(db) { |
141 | hir::GenericDef::Function(it) => { | 141 | hir::GenericDef::Function(it) => { |
142 | it.source(db).and_then(|src| Some(src.value.syntax().text_range())) | 142 | it.source(db).and_then(|src| Some(src.value.syntax().text_range())) |