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.rs54
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)
}