Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
| -rw-r--r-- | crates/hir/src/lib.rs | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index db3121d3cd..0cbc75726b 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -45,7 +45,7 @@ use hir_def::{ body::BodyDiagnostic, data::{adt::VariantData, TraitFlags}, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, - hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, Pat}, + hir::{BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat}, item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode}, lang_item::LangItemTarget, layout::{self, ReprOptions, TargetDataLayout}, @@ -2470,20 +2470,31 @@ impl Param { } pub fn as_local(&self, db: &dyn HirDatabase) -> Option<Local> { - let parent = match self.func { - Callee::Def(CallableDefId::FunctionId(it)) => DefWithBodyId::FunctionId(it), - Callee::Closure(closure, _) => db.lookup_intern_closure(closure.into()).0, - _ => return None, - }; - let body = db.body(parent); - if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) { - Some(Local { parent, binding_id: self_param }) - } else if let Pat::Bind { id, .. } = - &body[body.params[self.idx - body.self_param.is_some() as usize]] - { - Some(Local { parent, binding_id: *id }) - } else { - None + match self.func { + Callee::Def(CallableDefId::FunctionId(it)) => { + let parent = DefWithBodyId::FunctionId(it); + let body = db.body(parent); + if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) { + Some(Local { parent, binding_id: self_param }) + } else if let Pat::Bind { id, .. } = + &body[body.params[self.idx - body.self_param.is_some() as usize]] + { + Some(Local { parent, binding_id: *id }) + } else { + None + } + } + Callee::Closure(closure, _) => { + let c = db.lookup_intern_closure(closure.into()); + let body = db.body(c.0); + if let Expr::Closure { args, .. } = &body[c.1] { + if let Pat::Bind { id, .. } = &body[args[self.idx]] { + return Some(Local { parent: c.0, binding_id: *id }); + } + } + None + } + _ => None, } } @@ -2756,6 +2767,15 @@ impl Trait { traits.iter().map(|tr| Trait::from(*tr)).collect() } + pub fn function(self, db: &dyn HirDatabase, name: impl PartialEq<Name>) -> Option<Function> { + db.trait_data(self.id).items.iter().find(|(n, _)| name == *n).and_then( + |&(_, it)| match it { + AssocItemId::FunctionId(id) => Some(Function { id }), + _ => None, + }, + ) + } + pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> { db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() } @@ -4673,6 +4693,10 @@ impl Type { matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Bool)) } + pub fn is_str(&self) -> bool { + matches!(self.ty.kind(Interner), TyKind::Str) + } + pub fn is_never(&self) -> bool { matches!(self.ty.kind(Interner), TyKind::Never) } |