aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs25
-rw-r--r--crates/ra_ide/src/hover.rs35
2 files changed, 36 insertions, 24 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index c22eb451b..64b9a4cc3 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -27,7 +27,7 @@ use hir_ty::{
27 display::{HirDisplayError, HirFormatter}, 27 display::{HirDisplayError, HirFormatter},
28 expr::ExprValidator, 28 expr::ExprValidator,
29 method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, OpaqueTyId, 29 method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, OpaqueTyId,
30 Substs, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, 30 Substs, TraitEnvironment, Ty, TyDefId, TypeCtor,
31}; 31};
32use ra_db::{CrateId, CrateName, Edition, FileId}; 32use ra_db::{CrateId, CrateName, Edition, FileId};
33use ra_prof::profile; 33use ra_prof::profile;
@@ -1381,7 +1381,7 @@ impl Type {
1381 } 1381 }
1382 } 1382 }
1383 1383
1384 /// Returns a flattened list of all the ADTs and Traits mentioned in the type 1384 /// Returns a flattened list of all ADTs and Traits mentioned in the type
1385 pub fn flattened_type_items(&self, db: &dyn HirDatabase) -> Vec<AdtOrTrait> { 1385 pub fn flattened_type_items(&self, db: &dyn HirDatabase) -> Vec<AdtOrTrait> {
1386 fn push_new_item(item: AdtOrTrait, acc: &mut Vec<AdtOrTrait>) { 1386 fn push_new_item(item: AdtOrTrait, acc: &mut Vec<AdtOrTrait>) {
1387 if !acc.contains(&item) { 1387 if !acc.contains(&item) {
@@ -1398,7 +1398,7 @@ impl Type {
1398 match p { 1398 match p {
1399 GenericPredicate::Implemented(trait_ref) => { 1399 GenericPredicate::Implemented(trait_ref) => {
1400 push_new_item(Trait::from(trait_ref.trait_).into(), acc); 1400 push_new_item(Trait::from(trait_ref.trait_).into(), acc);
1401 walk_types(db, &trait_ref.substs, acc); 1401 walk_substs(db, &trait_ref.substs, acc);
1402 } 1402 }
1403 GenericPredicate::Projection(_) => {} 1403 GenericPredicate::Projection(_) => {}
1404 GenericPredicate::Error => (), 1404 GenericPredicate::Error => (),
@@ -1406,8 +1406,11 @@ impl Type {
1406 } 1406 }
1407 } 1407 }
1408 1408
1409 fn walk_types<T: TypeWalk>(db: &dyn HirDatabase, tw: &T, acc: &mut Vec<AdtOrTrait>) { 1409 // TypeWalk::walk does not preserve items order!
1410 tw.walk(&mut |ty| walk_type(db, ty, acc)); 1410 fn walk_substs(db: &dyn HirDatabase, substs: &Substs, acc: &mut Vec<AdtOrTrait>) {
1411 for ty in substs.iter() {
1412 walk_type(db, ty, acc);
1413 }
1411 } 1414 }
1412 1415
1413 fn walk_type(db: &dyn HirDatabase, ty: &Ty, acc: &mut Vec<AdtOrTrait>) { 1416 fn walk_type(db: &dyn HirDatabase, ty: &Ty, acc: &mut Vec<AdtOrTrait>) {
@@ -1415,10 +1418,18 @@ impl Type {
1415 Ty::Apply(ApplicationTy { ctor, parameters, .. }) => { 1418 Ty::Apply(ApplicationTy { ctor, parameters, .. }) => {
1416 match ctor { 1419 match ctor {
1417 TypeCtor::Adt(adt_id) => push_new_item(Adt::from(*adt_id).into(), acc), 1420 TypeCtor::Adt(adt_id) => push_new_item(Adt::from(*adt_id).into(), acc),
1421 TypeCtor::AssociatedType(type_alias_id) => {
1422 let trait_id = match type_alias_id.lookup(db.upcast()).container {
1423 AssocContainerId::TraitId(it) => it,
1424 _ => panic!("not an associated type"),
1425 };
1426
1427 push_new_item(Trait::from(trait_id).into(), acc);
1428 }
1418 _ => (), 1429 _ => (),
1419 } 1430 }
1420 // adt params, tuples, etc... 1431 // adt params, tuples, etc...
1421 walk_types(db, parameters, acc); 1432 walk_substs(db, parameters, acc);
1422 } 1433 }
1423 Ty::Dyn(predicates) => { 1434 Ty::Dyn(predicates) => {
1424 push_bounds(db, predicates, acc); 1435 push_bounds(db, predicates, acc);
@@ -1451,7 +1462,7 @@ impl Type {
1451 } 1462 }
1452 }; 1463 };
1453 push_bounds(db, &bounds.value, acc); 1464 push_bounds(db, &bounds.value, acc);
1454 walk_types(db, &opaque_ty.parameters, acc); 1465 walk_substs(db, &opaque_ty.parameters, acc);
1455 } 1466 }
1456 _ => (), 1467 _ => (),
1457 } 1468 }
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index c434e5c8b..c4ee2ff79 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -234,9 +234,10 @@ fn runnable_action(
234fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { 234fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
235 match def { 235 match def {
236 Definition::Local(it) => { 236 Definition::Local(it) => {
237 let ty = it.ty(db); 237 let targets = it
238 let v = ty.flattened_type_items(db); 238 .ty(db)
239 let targets = v.into_iter() 239 .flattened_type_items(db)
240 .into_iter()
240 .map(|it| HoverGotoTypeData { 241 .map(|it| HoverGotoTypeData {
241 mod_path: adt_or_trait_mod_path(db, &it), 242 mod_path: adt_or_trait_mod_path(db, &it),
242 nav: it.to_nav(db), 243 nav: it.to_nav(db),
@@ -1980,7 +1981,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1980 } 1981 }
1981 1982
1982 #[test] 1983 #[test]
1983 fn test_hover_arg_goto_type_action() { 1984 fn test_hover_goto_type_action_links_order() {
1984 let (_, actions) = check_hover_result( 1985 let (_, actions) = check_hover_result(
1985 " 1986 "
1986 //- /lib.rs 1987 //- /lib.rs
@@ -1988,10 +1989,10 @@ fn func(foo: i32) { if true { <|>foo; }; }
1988 trait DynTrait<T> {} 1989 trait DynTrait<T> {}
1989 struct B<T> {} 1990 struct B<T> {}
1990 struct S {} 1991 struct S {}
1991 1992
1992 fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<S>>>) {} 1993 fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
1993 ", 1994 ",
1994 &["&impl ImplTrait<B<dyn DynTrait<S>>>"], 1995 &["&impl ImplTrait<B<dyn DynTrait<B<S>>>>"],
1995 ); 1996 );
1996 assert_debug_snapshot!(actions, 1997 assert_debug_snapshot!(actions,
1997 @r###" 1998 @r###"
@@ -2018,20 +2019,20 @@ fn func(foo: i32) { if true { <|>foo; }; }
2018 }, 2019 },
2019 }, 2020 },
2020 HoverGotoTypeData { 2021 HoverGotoTypeData {
2021 mod_path: "S", 2022 mod_path: "B",
2022 nav: NavigationTarget { 2023 nav: NavigationTarget {
2023 file_id: FileId( 2024 file_id: FileId(
2024 1, 2025 1,
2025 ), 2026 ),
2026 full_range: 58..69, 2027 full_range: 43..57,
2027 name: "S", 2028 name: "B",
2028 kind: STRUCT_DEF, 2029 kind: STRUCT_DEF,
2029 focus_range: Some( 2030 focus_range: Some(
2030 65..66, 2031 50..51,
2031 ), 2032 ),
2032 container_name: None, 2033 container_name: None,
2033 description: Some( 2034 description: Some(
2034 "struct S", 2035 "struct B",
2035 ), 2036 ),
2036 docs: None, 2037 docs: None,
2037 }, 2038 },
@@ -2056,20 +2057,20 @@ fn func(foo: i32) { if true { <|>foo; }; }
2056 }, 2057 },
2057 }, 2058 },
2058 HoverGotoTypeData { 2059 HoverGotoTypeData {
2059 mod_path: "B", 2060 mod_path: "S",
2060 nav: NavigationTarget { 2061 nav: NavigationTarget {
2061 file_id: FileId( 2062 file_id: FileId(
2062 1, 2063 1,
2063 ), 2064 ),
2064 full_range: 43..57, 2065 full_range: 58..69,
2065 name: "B", 2066 name: "S",
2066 kind: STRUCT_DEF, 2067 kind: STRUCT_DEF,
2067 focus_range: Some( 2068 focus_range: Some(
2068 50..51, 2069 65..66,
2069 ), 2070 ),
2070 container_name: None, 2071 container_name: None,
2071 description: Some( 2072 description: Some(
2072 "struct B", 2073 "struct S",
2073 ), 2074 ),
2074 docs: None, 2075 docs: None,
2075 }, 2076 },