From 283ec13fc06dda7ec4d22955e2d2eb96aaff95fd Mon Sep 17 00:00:00 2001 From: vsrs Date: Wed, 10 Jun 2020 22:56:49 +0300 Subject: [PATCH] Fix type "items" order. --- crates/ra_hir/src/code_model.rs | 25 ++++++++++++++++------- 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 c22eb451b96..64b9a4cc3a6 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -27,7 +27,7 @@ use hir_ty::{ display::{HirDisplayError, HirFormatter}, expr::ExprValidator, method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, OpaqueTyId, - Substs, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, + Substs, TraitEnvironment, Ty, TyDefId, TypeCtor, }; use ra_db::{CrateId, CrateName, Edition, FileId}; use ra_prof::profile; @@ -1381,7 +1381,7 @@ impl Type { } } - /// Returns a flattened list of all the ADTs and Traits mentioned in the type + /// Returns a flattened list of all ADTs and Traits mentioned in the type pub fn flattened_type_items(&self, db: &dyn HirDatabase) -> Vec { fn push_new_item(item: AdtOrTrait, acc: &mut Vec) { if !acc.contains(&item) { @@ -1398,7 +1398,7 @@ impl Type { match p { GenericPredicate::Implemented(trait_ref) => { push_new_item(Trait::from(trait_ref.trait_).into(), acc); - walk_types(db, &trait_ref.substs, acc); + walk_substs(db, &trait_ref.substs, acc); } GenericPredicate::Projection(_) => {} GenericPredicate::Error => (), @@ -1406,8 +1406,11 @@ impl Type { } } - fn walk_types(db: &dyn HirDatabase, tw: &T, acc: &mut Vec) { - tw.walk(&mut |ty| walk_type(db, ty, acc)); + // TypeWalk::walk does not preserve items order! + fn walk_substs(db: &dyn HirDatabase, substs: &Substs, acc: &mut Vec) { + for ty in substs.iter() { + walk_type(db, ty, acc); + } } fn walk_type(db: &dyn HirDatabase, ty: &Ty, acc: &mut Vec) { @@ -1415,10 +1418,18 @@ impl Type { Ty::Apply(ApplicationTy { ctor, parameters, .. }) => { match ctor { TypeCtor::Adt(adt_id) => push_new_item(Adt::from(*adt_id).into(), acc), + TypeCtor::AssociatedType(type_alias_id) => { + let trait_id = match type_alias_id.lookup(db.upcast()).container { + AssocContainerId::TraitId(it) => it, + _ => panic!("not an associated type"), + }; + + push_new_item(Trait::from(trait_id).into(), acc); + } _ => (), } // adt params, tuples, etc... - walk_types(db, parameters, acc); + walk_substs(db, parameters, acc); } Ty::Dyn(predicates) => { push_bounds(db, predicates, acc); @@ -1451,7 +1462,7 @@ impl Type { } }; push_bounds(db, &bounds.value, acc); - walk_types(db, &opaque_ty.parameters, acc); + walk_substs(db, &opaque_ty.parameters, acc); } _ => (), } diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index c434e5c8b69..c4ee2ff796b 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -234,9 +234,10 @@ fn runnable_action( fn goto_type_action(db: &RootDatabase, def: Definition) -> Option { match def { Definition::Local(it) => { - let ty = it.ty(db); - let v = ty.flattened_type_items(db); - let targets = v.into_iter() + let targets = it + .ty(db) + .flattened_type_items(db) + .into_iter() .map(|it| HoverGotoTypeData { mod_path: adt_or_trait_mod_path(db, &it), nav: it.to_nav(db), @@ -1980,7 +1981,7 @@ fn func(foo: i32) { if true { <|>foo; }; } } #[test] - fn test_hover_arg_goto_type_action() { + fn test_hover_goto_type_action_links_order() { let (_, actions) = check_hover_result( " //- /lib.rs @@ -1988,10 +1989,10 @@ fn func(foo: i32) { if true { <|>foo; }; } trait DynTrait {} struct B {} struct S {} - - fn foo(a<|>rg: &impl ImplTrait>>) {} + + fn foo(a<|>rg: &impl ImplTrait>>>) {} ", - &["&impl ImplTrait>>"], + &["&impl ImplTrait>>>"], ); assert_debug_snapshot!(actions, @r###" @@ -2018,20 +2019,20 @@ fn func(foo: i32) { if true { <|>foo; }; } }, }, HoverGotoTypeData { - mod_path: "S", + mod_path: "B", nav: NavigationTarget { file_id: FileId( 1, ), - full_range: 58..69, - name: "S", + full_range: 43..57, + name: "B", kind: STRUCT_DEF, focus_range: Some( - 65..66, + 50..51, ), container_name: None, description: Some( - "struct S", + "struct B", ), docs: None, }, @@ -2056,20 +2057,20 @@ fn func(foo: i32) { if true { <|>foo; }; } }, }, HoverGotoTypeData { - mod_path: "B", + mod_path: "S", nav: NavigationTarget { file_id: FileId( 1, ), - full_range: 43..57, - name: "B", + full_range: 58..69, + name: "S", kind: STRUCT_DEF, focus_range: Some( - 50..51, + 65..66, ), container_name: None, description: Some( - "struct B", + "struct S", ), docs: None, },