aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model.rs25
1 files changed, 18 insertions, 7 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 }