diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/code_model.rs | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 62eccf475..cc1938333 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -5,9 +5,7 @@ use arrayvec::ArrayVec; | |||
5 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; | 5 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; |
6 | use either::Either; | 6 | use either::Either; |
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | adt::ReprKind, | 8 | adt::{ReprKind, StructKind, VariantData}, |
9 | adt::StructKind, | ||
10 | adt::VariantData, | ||
11 | builtin_type::BuiltinType, | 9 | builtin_type::BuiltinType, |
12 | expr::{BindingAnnotation, LabelId, Pat, PatId}, | 10 | expr::{BindingAnnotation, LabelId, Pat, PatId}, |
13 | import_map, | 11 | import_map, |
@@ -31,7 +29,7 @@ use hir_expand::{ | |||
31 | }; | 29 | }; |
32 | use hir_ty::{ | 30 | use hir_ty::{ |
33 | autoderef, | 31 | autoderef, |
34 | display::{HirDisplayError, HirFormatter}, | 32 | display::{write_bounds_like_dyn_trait, HirDisplayError, HirFormatter}, |
35 | method_resolution, | 33 | method_resolution, |
36 | traits::{FnTrait, Solution, SolutionVariables}, | 34 | traits::{FnTrait, Solution, SolutionVariables}, |
37 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, | 35 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, |
@@ -745,6 +743,18 @@ impl Function { | |||
745 | db.function_data(self.id).name.clone() | 743 | db.function_data(self.id).name.clone() |
746 | } | 744 | } |
747 | 745 | ||
746 | /// Get this function's return type | ||
747 | pub fn ret_type(self, db: &dyn HirDatabase) -> Type { | ||
748 | let resolver = self.id.resolver(db.upcast()); | ||
749 | let ret_type = &db.function_data(self.id).ret_type; | ||
750 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | ||
751 | let environment = TraitEnvironment::lower(db, &resolver); | ||
752 | Type { | ||
753 | krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate, | ||
754 | ty: InEnvironment { value: Ty::from_hir_ext(&ctx, ret_type).0, environment }, | ||
755 | } | ||
756 | } | ||
757 | |||
748 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { | 758 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { |
749 | if !db.function_data(self.id).has_self_param { | 759 | if !db.function_data(self.id).has_self_param { |
750 | return None; | 760 | return None; |
@@ -1278,6 +1288,18 @@ impl TypeParam { | |||
1278 | } | 1288 | } |
1279 | } | 1289 | } |
1280 | 1290 | ||
1291 | pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { | ||
1292 | db.generic_predicates_for_param(self.id) | ||
1293 | .into_iter() | ||
1294 | .filter_map(|pred| match &pred.value { | ||
1295 | hir_ty::GenericPredicate::Implemented(trait_ref) => { | ||
1296 | Some(Trait::from(trait_ref.trait_)) | ||
1297 | } | ||
1298 | _ => None, | ||
1299 | }) | ||
1300 | .collect() | ||
1301 | } | ||
1302 | |||
1281 | pub fn default(self, db: &dyn HirDatabase) -> Option<Type> { | 1303 | pub fn default(self, db: &dyn HirDatabase) -> Option<Type> { |
1282 | let params = db.generic_defaults(self.id.parent); | 1304 | let params = db.generic_defaults(self.id.parent); |
1283 | let local_idx = hir_ty::param_idx(db, self.id)?; | 1305 | let local_idx = hir_ty::param_idx(db, self.id)?; |
@@ -1293,6 +1315,20 @@ impl TypeParam { | |||
1293 | } | 1315 | } |
1294 | } | 1316 | } |
1295 | 1317 | ||
1318 | impl HirDisplay for TypeParam { | ||
1319 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
1320 | write!(f, "{}", self.name(f.db))?; | ||
1321 | let bounds = f.db.generic_predicates_for_param(self.id); | ||
1322 | let substs = Substs::type_params(f.db, self.id.parent); | ||
1323 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | ||
1324 | if !(predicates.is_empty() || f.omit_verbose_types()) { | ||
1325 | write!(f, ": ")?; | ||
1326 | write_bounds_like_dyn_trait(&predicates, f)?; | ||
1327 | } | ||
1328 | Ok(()) | ||
1329 | } | ||
1330 | } | ||
1331 | |||
1296 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1332 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1297 | pub struct LifetimeParam { | 1333 | pub struct LifetimeParam { |
1298 | pub(crate) id: LifetimeParamId, | 1334 | pub(crate) id: LifetimeParamId, |
@@ -1331,6 +1367,12 @@ impl ConstParam { | |||
1331 | pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef { | 1367 | pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef { |
1332 | self.id.parent.into() | 1368 | self.id.parent.into() |
1333 | } | 1369 | } |
1370 | |||
1371 | pub fn ty(self, db: &dyn HirDatabase) -> Type { | ||
1372 | let def = self.id.parent; | ||
1373 | let krate = def.module(db.upcast()).krate; | ||
1374 | Type::new(db, krate, def, db.const_param_ty(self.id)) | ||
1375 | } | ||
1334 | } | 1376 | } |
1335 | 1377 | ||
1336 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 1378 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -1600,9 +1642,10 @@ impl Type { | |||
1600 | } | 1642 | } |
1601 | 1643 | ||
1602 | pub fn is_fn(&self) -> bool { | 1644 | pub fn is_fn(&self) -> bool { |
1603 | matches!(&self.ty.value, | 1645 | matches!( |
1604 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) | | 1646 | &self.ty.value, |
1605 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. }) | 1647 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) |
1648 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. }) | ||
1606 | ) | 1649 | ) |
1607 | } | 1650 | } |
1608 | 1651 | ||