aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs115
1 files changed, 113 insertions, 2 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 1a9f6cc76..ffd5278ec 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -26,8 +26,8 @@ use hir_ty::{
26 autoderef, 26 autoderef,
27 display::{HirDisplayError, HirFormatter}, 27 display::{HirDisplayError, HirFormatter},
28 expr::ExprValidator, 28 expr::ExprValidator,
29 method_resolution, ApplicationTy, Canonical, InEnvironment, Substs, TraitEnvironment, Ty, 29 method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs,
30 TyDefId, TypeCtor, 30 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;
@@ -186,6 +186,22 @@ impl ModuleDef {
186 186
187 module.visibility_of(db, self) 187 module.visibility_of(db, self)
188 } 188 }
189
190 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
191 match self {
192 ModuleDef::Adt(it) => Some(it.name(db)),
193 ModuleDef::Trait(it) => Some(it.name(db)),
194 ModuleDef::Function(it) => Some(it.name(db)),
195 ModuleDef::EnumVariant(it) => Some(it.name(db)),
196 ModuleDef::TypeAlias(it) => Some(it.name(db)),
197
198 ModuleDef::Module(it) => it.name(db),
199 ModuleDef::Const(it) => it.name(db),
200 ModuleDef::Static(it) => it.name(db),
201
202 ModuleDef::BuiltinType(it) => Some(it.as_name()),
203 }
204 }
189} 205}
190 206
191pub use hir_def::{ 207pub use hir_def::{
@@ -1359,6 +1375,27 @@ impl Type {
1359 Some(adt.into()) 1375 Some(adt.into())
1360 } 1376 }
1361 1377
1378 pub fn as_dyn_trait(&self) -> Option<Trait> {
1379 self.ty.value.dyn_trait().map(Into::into)
1380 }
1381
1382 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
1383 self.ty.value.impl_trait_bounds(db).map(|it| {
1384 it.into_iter()
1385 .filter_map(|pred| match pred {
1386 hir_ty::GenericPredicate::Implemented(trait_ref) => {
1387 Some(Trait::from(trait_ref.trait_))
1388 }
1389 _ => None,
1390 })
1391 .collect()
1392 })
1393 }
1394
1395 pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
1396 self.ty.value.associated_type_parent_trait(db).map(Into::into)
1397 }
1398
1362 // FIXME: provide required accessors such that it becomes implementable from outside. 1399 // FIXME: provide required accessors such that it becomes implementable from outside.
1363 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { 1400 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1364 match (&self.ty.value, &other.ty.value) { 1401 match (&self.ty.value, &other.ty.value) {
@@ -1380,6 +1417,80 @@ impl Type {
1380 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() }, 1417 ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
1381 } 1418 }
1382 } 1419 }
1420
1421 pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
1422 // TypeWalk::walk for a Ty at first visits parameters and only after that the Ty itself.
1423 // We need a different order here.
1424
1425 fn walk_substs(
1426 db: &dyn HirDatabase,
1427 type_: &Type,
1428 substs: &Substs,
1429 cb: &mut impl FnMut(Type),
1430 ) {
1431 for ty in substs.iter() {
1432 walk_type(db, &type_.derived(ty.clone()), cb);
1433 }
1434 }
1435
1436 fn walk_bounds(
1437 db: &dyn HirDatabase,
1438 type_: &Type,
1439 bounds: &[GenericPredicate],
1440 cb: &mut impl FnMut(Type),
1441 ) {
1442 for pred in bounds {
1443 match pred {
1444 GenericPredicate::Implemented(trait_ref) => {
1445 cb(type_.clone());
1446 walk_substs(db, type_, &trait_ref.substs, cb);
1447 }
1448 _ => (),
1449 }
1450 }
1451 }
1452
1453 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
1454 let ty = type_.ty.value.strip_references();
1455 match ty {
1456 Ty::Apply(ApplicationTy { ctor, parameters }) => {
1457 match ctor {
1458 TypeCtor::Adt(_) => {
1459 cb(type_.derived(ty.clone()));
1460 }
1461 TypeCtor::AssociatedType(_) => {
1462 if let Some(_) = ty.associated_type_parent_trait(db) {
1463 cb(type_.derived(ty.clone()));
1464 }
1465 }
1466 _ => (),
1467 }
1468
1469 // adt params, tuples, etc...
1470 walk_substs(db, type_, parameters, cb);
1471 }
1472 Ty::Opaque(opaque_ty) => {
1473 if let Some(bounds) = ty.impl_trait_bounds(db) {
1474 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1475 }
1476
1477 walk_substs(db, type_, &opaque_ty.parameters, cb);
1478 }
1479 Ty::Placeholder(_) => {
1480 if let Some(bounds) = ty.impl_trait_bounds(db) {
1481 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1482 }
1483 }
1484 Ty::Dyn(bounds) => {
1485 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
1486 }
1487
1488 _ => (),
1489 }
1490 }
1491
1492 walk_type(db, self, &mut cb);
1493 }
1383} 1494}
1384 1495
1385impl HirDisplay for Type { 1496impl HirDisplay for Type {