diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 25 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 35 |
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 | }; |
32 | use ra_db::{CrateId, CrateName, Edition, FileId}; | 32 | use ra_db::{CrateId, CrateName, Edition, FileId}; |
33 | use ra_prof::profile; | 33 | use 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( | |||
234 | fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { | 234 | fn 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 | }, |