aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Pullar-Strecker <[email protected]>2020-06-13 11:34:59 +0100
committerZac Pullar-Strecker <[email protected]>2020-06-30 09:07:08 +0100
commit1d6f291335c58aac95c1124f55d7fb0834baff2a (patch)
treef0d64776e584bf40ba8edb638596a5a03bf04002
parent108b953254e46851130e427b41cd143eee07fd02 (diff)
Move resolver into impls, work on tests
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ra_hir/src/code_model.rs37
-rw-r--r--crates/ra_ide/src/hover.rs148
-rw-r--r--crates/ra_ide/src/mock_analysis.rs2
-rw-r--r--crates/ra_ide_db/Cargo.toml1
-rw-r--r--crates/ra_ide_db/src/defs.rs17
-rw-r--r--crates/rust-analyzer/src/handlers.rs3
7 files changed, 138 insertions, 71 deletions
diff --git a/Cargo.lock b/Cargo.lock
index be97c16ff..0c1d2e8b9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1303,6 +1303,7 @@ dependencies = [
1303 "once_cell", 1303 "once_cell",
1304 "ra_db", 1304 "ra_db",
1305 "ra_hir", 1305 "ra_hir",
1306 "ra_hir_def",
1306 "ra_prof", 1307 "ra_prof",
1307 "ra_syntax", 1308 "ra_syntax",
1308 "ra_text_edit", 1309 "ra_text_edit",
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index e86077dd6..5766cc3b8 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -186,21 +186,34 @@ impl ModuleDef {
186 module.visibility_of(db, self) 186 module.visibility_of(db, self)
187 } 187 }
188 188
189 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 189 pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
190 match self { 190 match self {
191 ModuleDef::Adt(it) => Some(it.name(db)), 191 ModuleDef::Module(m) => m.name(db),
192 ModuleDef::Trait(it) => Some(it.name(db)), 192 ModuleDef::Function(m) => Some(m.name(db)),
193 ModuleDef::Function(it) => Some(it.name(db)), 193 ModuleDef::Adt(m) => Some(m.name(db)),
194 ModuleDef::EnumVariant(it) => Some(it.name(db)), 194 ModuleDef::EnumVariant(m) => Some(m.name(db)),
195 ModuleDef::TypeAlias(it) => Some(it.name(db)), 195 ModuleDef::Const(m) => {m.name(db)},
196 196 ModuleDef::Static(m) => {m.name(db)},
197 ModuleDef::Module(it) => it.name(db), 197 ModuleDef::Trait(m) => {Some(m.name(db))},
198 ModuleDef::Const(it) => it.name(db), 198 ModuleDef::TypeAlias(m) => {Some(m.name(db))},
199 ModuleDef::Static(it) => it.name(db), 199 ModuleDef::BuiltinType(m) => {Some(m.as_name())}
200
201 ModuleDef::BuiltinType(it) => Some(it.as_name()),
202 } 200 }
203 } 201 }
202
203 pub fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
204 Some(match self {
205 ModuleDef::Module(m) => Into::<ModuleId>::into(m.clone()).resolver(db),
206 ModuleDef::Function(f) => Into::<FunctionId>::into(f.clone()).resolver(db),
207 ModuleDef::Adt(adt) => Into::<AdtId>::into(adt.clone()).resolver(db),
208 ModuleDef::EnumVariant(ev) => Into::<GenericDefId>::into(Into::<GenericDef>::into(ev.clone())).resolver(db),
209 ModuleDef::Const(c) => Into::<GenericDefId>::into(Into::<GenericDef>::into(c.clone())).resolver(db),
210 ModuleDef::Static(s) => Into::<StaticId>::into(s.clone()).resolver(db),
211 ModuleDef::Trait(t) => Into::<TraitId>::into(t.clone()).resolver(db),
212 ModuleDef::TypeAlias(t) => Into::<ModuleId>::into(t.module(db)).resolver(db),
213 // TODO: This should be a resolver relative to `std`
214 ModuleDef::BuiltinType(_t) => None?
215 })
216 }
204} 217}
205 218
206pub use hir_def::{ 219pub use hir_def::{
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index 0da10a08e..34fc36a1f 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -146,7 +146,8 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
146 } 146 }
147 } { 147 } {
148 let range = sema.original_range(&node).range; 148 let range = sema.original_range(&node).range;
149 let text = hover_text_from_name_kind(db, name_kind.clone()).map(|text| rewrite_links(db, &text, &name_kind).unwrap_or(text)); 149 let text = hover_text_from_name_kind(db, name_kind.clone());
150 let text = text.map(|text| rewrite_links(db, &text, &name_kind).unwrap_or(text));
150 res.extend(text); 151 res.extend(text);
151 152
152 if !res.is_empty() { 153 if !res.is_empty() {
@@ -405,8 +406,8 @@ fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) ->
405 Err(_) => { 406 Err(_) => {
406 let link_str = String::from_utf8(link.url.clone()).unwrap(); 407 let link_str = String::from_utf8(link.url.clone()).unwrap();
407 let link_text = String::from_utf8(link.title.clone()).unwrap(); 408 let link_text = String::from_utf8(link.title.clone()).unwrap();
408 let resolved = try_resolve_path(db, definition, &link_str) 409 let resolved = try_resolve_intra(db, definition, &link_text, &link_str)
409 .or_else(|| try_resolve_intra(db, definition, &link_text, &link_str)); 410 .or_else(|| try_resolve_path(db, definition, &link_str));
410 411
411 if let Some(resolved) = resolved { 412 if let Some(resolved) = resolved {
412 link.url = resolved.as_bytes().to_vec(); 413 link.url = resolved.as_bytes().to_vec();
@@ -420,7 +421,7 @@ fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) ->
420 }); 421 });
421 let mut out = Vec::new(); 422 let mut out = Vec::new();
422 format_commonmark(doc, &ComrakOptions::default(), &mut out).ok()?; 423 format_commonmark(doc, &ComrakOptions::default(), &mut out).ok()?;
423 Some(String::from_utf8(out).unwrap()) 424 Some(String::from_utf8(out).unwrap().trim().to_string())
424} 425}
425 426
426#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] 427#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
@@ -470,32 +471,7 @@ fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str
470 let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap(); 471 let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
471 472
472 // Resolve it relative to symbol's location (according to the RFC this should consider small scopes 473 // Resolve it relative to symbol's location (according to the RFC this should consider small scopes
473 let resolver = { 474 let resolver = definition.resolver(db)?;
474 use ra_hir_def::*;
475 use hir::*;
476
477 // TODO: This should be replaced by implementing HasResolver/TryHasResolver on ModuleDef and Definition.
478 match definition {
479 Definition::ModuleDef(def) => match def {
480 ModuleDef::Module(m) => Into::<ModuleId>::into(m.clone()).resolver(db),
481 ModuleDef::Function(f) => Into::<FunctionId>::into(f.clone()).resolver(db),
482 ModuleDef::Adt(adt) => Into::<AdtId>::into(adt.clone()).resolver(db),
483 ModuleDef::EnumVariant(ev) => Into::<GenericDefId>::into(Into::<GenericDef>::into(ev.clone())).resolver(db),
484 ModuleDef::Const(c) => Into::<GenericDefId>::into(Into::<GenericDef>::into(c.clone())).resolver(db),
485 ModuleDef::Static(s) => Into::<StaticId>::into(s.clone()).resolver(db),
486 ModuleDef::Trait(t) => Into::<TraitId>::into(t.clone()).resolver(db),
487 ModuleDef::TypeAlias(t) => Into::<ModuleId>::into(t.module(db)).resolver(db),
488 // TODO: This should be a resolver relative to `std`
489 ModuleDef::BuiltinType(_t) => Into::<ModuleId>::into(definition.module(db)?).resolver(db)
490 },
491 Definition::Field(field) => Into::<VariantId>::into(Into::<VariantDef>::into(field.parent_def(db))).resolver(db),
492 Definition::Macro(m) => Into::<ModuleId>::into(m.module(db)?).resolver(db),
493 Definition::SelfType(imp) => Into::<ImplId>::into(imp.clone()).resolver(db),
494 // it's possible, read probable, that other arms of this are also unreachable
495 Definition::Local(_local) => unreachable!(),
496 Definition::TypeParam(tp) => Into::<ModuleId>::into(tp.module(db)).resolver(db)
497 }
498 };
499 475
500 // Namespace disambiguation 476 // Namespace disambiguation
501 let namespace = Namespace::from_intra_spec(link_target); 477 let namespace = Namespace::from_intra_spec(link_target);
@@ -527,7 +503,7 @@ fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str
527 get_doc_url(db, &krate)? 503 get_doc_url(db, &krate)?
528 .join(&format!("{}/", krate.display_name(db)?)).ok()? 504 .join(&format!("{}/", krate.display_name(db)?)).ok()?
529 .join(&path.segments.iter().map(|name| format!("{}", name)).join("/")).ok()? 505 .join(&path.segments.iter().map(|name| format!("{}", name)).join("/")).ok()?
530 .join(&get_symbol_filename(db, definition)?).ok()? 506 .join(&get_symbol_filename(db, &Definition::ModuleDef(def))?).ok()?
531 .into_string() 507 .into_string()
532 ) 508 )
533} 509}
@@ -637,11 +613,20 @@ mod tests {
637 613
638 use crate::mock_analysis::analysis_and_position; 614 use crate::mock_analysis::analysis_and_position;
639 615
640 fn trim_markup(s: &str) -> &str { 616 fn trim_markup(s: &str) -> String {
641 s.trim_start_matches("```rust\n").trim_end_matches("\n```") 617 s
618 .replace("``` rust", "```rust")
619 .replace("-----", "___")
620 .replace("\n\n___\n\n", "\n___\n\n")
621 .replace("\\<-", "<-")
622 .trim_start_matches("test\n```\n\n")
623 .trim_start_matches("```rust\n")
624 .trim_start_matches("test\n```\n\n```rust\n")
625 .trim_end_matches("\n```")
626 .to_string()
642 } 627 }
643 628
644 fn trim_markup_opt(s: Option<&str>) -> Option<&str> { 629 fn trim_markup_opt(s: Option<&str>) -> Option<String> {
645 s.map(trim_markup) 630 s.map(trim_markup)
646 } 631 }
647 632
@@ -689,7 +674,7 @@ fn main() {
689 ); 674 );
690 let hover = analysis.hover(position).unwrap().unwrap(); 675 let hover = analysis.hover(position).unwrap().unwrap();
691 assert_eq!(hover.range, TextRange::new(58.into(), 63.into())); 676 assert_eq!(hover.range, TextRange::new(58.into(), 63.into()));
692 assert_eq!(trim_markup_opt(hover.info.first()), Some("u32")); 677 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("u32"));
693 } 678 }
694 679
695 #[test] 680 #[test]
@@ -818,7 +803,7 @@ fn main() {
818 }; 803 };
819 } 804 }
820 "#, 805 "#,
821 &["Foo\n```\n\n```rust\nfield_a: u32"], 806 &["test::Foo\n```\n\n```rust\nfield_a: u32"],
822 ); 807 );
823 808
824 // Hovering over the field in the definition 809 // Hovering over the field in the definition
@@ -835,7 +820,7 @@ fn main() {
835 }; 820 };
836 } 821 }
837 "#, 822 "#,
838 &["Foo\n```\n\n```rust\nfield_a: u32"], 823 &["test::Foo\n```\n\n```rust\nfield_a: u32"],
839 ); 824 );
840 } 825 }
841 826
@@ -888,7 +873,7 @@ fn main() {
888 ", 873 ",
889 ); 874 );
890 let hover = analysis.hover(position).unwrap().unwrap(); 875 let hover = analysis.hover(position).unwrap().unwrap();
891 assert_eq!(trim_markup_opt(hover.info.first()), Some("Option\n```\n\n```rust\nSome")); 876 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("test::Option\n```\n\n```rust\nSome"));
892 877
893 let (analysis, position) = analysis_and_position( 878 let (analysis, position) = analysis_and_position(
894 " 879 "
@@ -901,7 +886,7 @@ fn main() {
901 ", 886 ",
902 ); 887 );
903 let hover = analysis.hover(position).unwrap().unwrap(); 888 let hover = analysis.hover(position).unwrap().unwrap();
904 assert_eq!(trim_markup_opt(hover.info.first()), Some("Option<i32>")); 889 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("Option<i32>"));
905 } 890 }
906 891
907 #[test] 892 #[test]
@@ -915,7 +900,7 @@ fn main() {
915 } 900 }
916 "#, 901 "#,
917 &[" 902 &["
918Option 903test::Option
919``` 904```
920 905
921```rust 906```rust
@@ -940,7 +925,7 @@ The None variant
940 } 925 }
941 "#, 926 "#,
942 &[" 927 &["
943Option 928test::Option
944``` 929```
945 930
946```rust 931```rust
@@ -958,14 +943,14 @@ The Some variant
958 fn hover_for_local_variable() { 943 fn hover_for_local_variable() {
959 let (analysis, position) = analysis_and_position("fn func(foo: i32) { fo<|>o; }"); 944 let (analysis, position) = analysis_and_position("fn func(foo: i32) { fo<|>o; }");
960 let hover = analysis.hover(position).unwrap().unwrap(); 945 let hover = analysis.hover(position).unwrap().unwrap();
961 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 946 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
962 } 947 }
963 948
964 #[test] 949 #[test]
965 fn hover_for_local_variable_pat() { 950 fn hover_for_local_variable_pat() {
966 let (analysis, position) = analysis_and_position("fn func(fo<|>o: i32) {}"); 951 let (analysis, position) = analysis_and_position("fn func(fo<|>o: i32) {}");
967 let hover = analysis.hover(position).unwrap().unwrap(); 952 let hover = analysis.hover(position).unwrap().unwrap();
968 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 953 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
969 } 954 }
970 955
971 #[test] 956 #[test]
@@ -976,14 +961,14 @@ fn func(foo: i32) { if true { <|>foo; }; }
976", 961",
977 ); 962 );
978 let hover = analysis.hover(position).unwrap().unwrap(); 963 let hover = analysis.hover(position).unwrap().unwrap();
979 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 964 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
980 } 965 }
981 966
982 #[test] 967 #[test]
983 fn hover_for_param_edge() { 968 fn hover_for_param_edge() {
984 let (analysis, position) = analysis_and_position("fn func(<|>foo: i32) {}"); 969 let (analysis, position) = analysis_and_position("fn func(<|>foo: i32) {}");
985 let hover = analysis.hover(position).unwrap().unwrap(); 970 let hover = analysis.hover(position).unwrap().unwrap();
986 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 971 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
987 } 972 }
988 973
989 #[test] 974 #[test]
@@ -1004,7 +989,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1004 ", 989 ",
1005 ); 990 );
1006 let hover = analysis.hover(position).unwrap().unwrap(); 991 let hover = analysis.hover(position).unwrap().unwrap();
1007 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); 992 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("Thing"));
1008 } 993 }
1009 994
1010 #[test] 995 #[test]
@@ -1028,8 +1013,8 @@ fn func(foo: i32) { if true { <|>foo; }; }
1028 ); 1013 );
1029 let hover = analysis.hover(position).unwrap().unwrap(); 1014 let hover = analysis.hover(position).unwrap().unwrap();
1030 assert_eq!( 1015 assert_eq!(
1031 trim_markup_opt(hover.info.first()), 1016 trim_markup_opt(hover.info.first()).as_deref(),
1032 Some("wrapper::Thing\n```\n\n```rust\nfn new() -> Thing") 1017 Some("test::wrapper::Thing\n```\n\n```rust\nfn new() -> Thing")
1033 ); 1018 );
1034 } 1019 }
1035 1020
@@ -1052,7 +1037,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1052 ", 1037 ",
1053 ); 1038 );
1054 let hover = analysis.hover(position).unwrap().unwrap(); 1039 let hover = analysis.hover(position).unwrap().unwrap();
1055 assert_eq!(trim_markup_opt(hover.info.first()), Some("const C: u32")); 1040 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("const C: u32"));
1056 } 1041 }
1057 1042
1058 #[test] 1043 #[test]
@@ -1068,7 +1053,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1068 ", 1053 ",
1069 ); 1054 );
1070 let hover = analysis.hover(position).unwrap().unwrap(); 1055 let hover = analysis.hover(position).unwrap().unwrap();
1071 assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); 1056 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("Thing"));
1072 1057
1073 /* FIXME: revive these tests 1058 /* FIXME: revive these tests
1074 let (analysis, position) = analysis_and_position( 1059 let (analysis, position) = analysis_and_position(
@@ -1125,7 +1110,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1125 ", 1110 ",
1126 ); 1111 );
1127 let hover = analysis.hover(position).unwrap().unwrap(); 1112 let hover = analysis.hover(position).unwrap().unwrap();
1128 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 1113 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
1129 } 1114 }
1130 1115
1131 #[test] 1116 #[test]
@@ -1142,7 +1127,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1142 ", 1127 ",
1143 ); 1128 );
1144 let hover = analysis.hover(position).unwrap().unwrap(); 1129 let hover = analysis.hover(position).unwrap().unwrap();
1145 assert_eq!(trim_markup_opt(hover.info.first()), Some("macro_rules! foo")); 1130 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("macro_rules! foo"));
1146 } 1131 }
1147 1132
1148 #[test] 1133 #[test]
@@ -1153,7 +1138,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1153 ", 1138 ",
1154 ); 1139 );
1155 let hover = analysis.hover(position).unwrap().unwrap(); 1140 let hover = analysis.hover(position).unwrap().unwrap();
1156 assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); 1141 assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
1157 } 1142 }
1158 1143
1159 #[test] 1144 #[test]
@@ -1415,6 +1400,59 @@ fn func(foo: i32) { if true { <|>foo; }; }
1415 } 1400 }
1416 1401
1417 #[test] 1402 #[test]
1403 fn test_hover_path_link() {
1404 check_hover_result(
1405 r"
1406 //- /lib.rs
1407 pub struct Foo;
1408 /// [Foo](struct.Foo.html)
1409 pub struct B<|>ar
1410 ",
1411 &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"]
1412 );
1413 }
1414
1415 #[test]
1416 fn test_hover_intra_link() {
1417 check_hover_result(
1418 r"
1419 //- /lib.rs
1420 pub struct Foo;
1421 /// [Foo](Foo)
1422 pub struct B<|>ar
1423 ",
1424 &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"]
1425 );
1426 }
1427
1428 #[test]
1429 fn test_hover_intra_link_shortlink() {
1430 check_hover_result(
1431 r"
1432 //- /lib.rs
1433 pub struct Foo;
1434 /// [Foo]
1435 pub struct B<|>ar
1436 ",
1437 &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"]
1438 );
1439 }
1440
1441 #[test]
1442 fn test_hover_intra_link_namespaced() {
1443 check_hover_result(
1444 r"
1445 //- /lib.rs
1446 pub struct Foo;
1447 fn Foo() {}
1448 /// [Foo()]
1449 pub struct B<|>ar
1450 ",
1451 &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"]
1452 );
1453 }
1454
1455 #[test]
1418 fn test_hover_macro_generated_struct_fn_doc_comment() { 1456 fn test_hover_macro_generated_struct_fn_doc_comment() {
1419 mark::check!(hover_macro_generated_struct_fn_doc_comment); 1457 mark::check!(hover_macro_generated_struct_fn_doc_comment);
1420 1458
@@ -1438,7 +1476,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1438 bar.fo<|>o(); 1476 bar.fo<|>o();
1439 } 1477 }
1440 "#, 1478 "#,
1441 &["Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\n Do the foo"], 1479 &["test::Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\nDo the foo"],
1442 ); 1480 );
1443 } 1481 }
1444 1482
@@ -1466,7 +1504,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1466 bar.fo<|>o(); 1504 bar.fo<|>o();
1467 } 1505 }
1468 "#, 1506 "#,
1469 &["Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\nDo the foo"], 1507 &["test::Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\nDo the foo"],
1470 ); 1508 );
1471 } 1509 }
1472 1510
diff --git a/crates/ra_ide/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs
index 889b84c59..490ee0dc3 100644
--- a/crates/ra_ide/src/mock_analysis.rs
+++ b/crates/ra_ide/src/mock_analysis.rs
@@ -99,7 +99,7 @@ impl MockAnalysis {
99 root_crate = Some(crate_graph.add_crate_root( 99 root_crate = Some(crate_graph.add_crate_root(
100 file_id, 100 file_id,
101 edition, 101 edition,
102 None, 102 Some(CrateName::new("test").unwrap()),
103 cfg, 103 cfg,
104 env, 104 env,
105 Default::default(), 105 Default::default(),
diff --git a/crates/ra_ide_db/Cargo.toml b/crates/ra_ide_db/Cargo.toml
index c3921bd40..b14206c9b 100644
--- a/crates/ra_ide_db/Cargo.toml
+++ b/crates/ra_ide_db/Cargo.toml
@@ -24,6 +24,7 @@ ra_text_edit = { path = "../ra_text_edit" }
24ra_db = { path = "../ra_db" } 24ra_db = { path = "../ra_db" }
25ra_prof = { path = "../ra_prof" } 25ra_prof = { path = "../ra_prof" }
26test_utils = { path = "../test_utils" } 26test_utils = { path = "../test_utils" }
27ra_hir_def = { path = "../ra_hir_def" }
27 28
28# ra_ide should depend only on the top-level `hir` package. if you need 29# ra_ide should depend only on the top-level `hir` package. if you need
29# something from some `hir_xxx` subpackage, reexport the API via `hir`. 30# something from some `hir_xxx` subpackage, reexport the API via `hir`.
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 3ef5e74b6..a158169e3 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -7,7 +7,7 @@
7 7
8use hir::{ 8use hir::{
9 Field, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, Name, PathResolution, 9 Field, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, Name, PathResolution,
10 Semantics, TypeParam, Visibility, 10 Semantics, TypeParam, Visibility, db::{DefDatabase, HirDatabase},
11}; 11};
12use ra_prof::profile; 12use ra_prof::profile;
13use ra_syntax::{ 13use ra_syntax::{
@@ -16,6 +16,7 @@ use ra_syntax::{
16}; 16};
17 17
18use crate::RootDatabase; 18use crate::RootDatabase;
19use ra_hir_def::resolver::{Resolver, HasResolver};
19 20
20// FIXME: a more precise name would probably be `Symbol`? 21// FIXME: a more precise name would probably be `Symbol`?
21#[derive(Debug, PartialEq, Eq, Copy, Clone)] 22#[derive(Debug, PartialEq, Eq, Copy, Clone)]
@@ -76,6 +77,20 @@ impl Definition {
76 }; 77 };
77 Some(name) 78 Some(name)
78 } 79 }
80
81 pub fn resolver<D: HirDatabase + DefDatabase>(&self, db: &D) -> Option<Resolver> {
82 use hir::VariantDef;
83 use ra_hir_def::*;
84 Some(match self {
85 Definition::ModuleDef(def) => def.resolver(db)?,
86 Definition::Field(field) => Into::<VariantId>::into(Into::<VariantDef>::into(field.parent_def(db))).resolver(db),
87 Definition::Macro(m) => Into::<ModuleId>::into(m.module(db)?).resolver(db),
88 Definition::SelfType(imp) => Into::<ImplId>::into(imp.clone()).resolver(db),
89 // it's possible, read probable, that other arms of this are also unreachable
90 Definition::Local(_local) => unreachable!(),
91 Definition::TypeParam(tp) => Into::<ModuleId>::into(tp.module(db)).resolver(db)
92 })
93 }
79} 94}
80 95
81#[derive(Debug)] 96#[derive(Debug)]
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 951006771..6c0d3e19c 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -4,8 +4,7 @@
4 4
5use std::{ 5use std::{
6 io::Write as _, 6 io::Write as _,
7 process::{self, Stdio}, 7 process::{self, Stdio}
8 sync::Arc
9}; 8};
10 9
11use lsp_server::ErrorCode; 10use lsp_server::ErrorCode;