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 | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 5bc72c772e..ad1a9c9072 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -87,7 +87,10 @@ use hir_ty::{ GenericPredicates, InferBodyId, InferenceResult, ParamEnvAndCrate, TyDefId, TyLoweringDiagnostic, ValueTyDefId, all_super_traits, autoderef, check_orphan_rules, consteval::try_const_usize, - db::{AnonConstId, InternedClosure, InternedClosureId, InternedCoroutineClosureId}, + db::{ + AnonConstId, InternedClosure, InternedClosureId, InternedCoroutineClosureId, + InternedCoroutineId, + }, diagnostics::BodyValidationDiagnostic, direct_super_traits, known_const_to_ast, layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding}, @@ -4937,15 +4940,7 @@ impl<'db> Closure<'db> { AnyClosureId::ClosureId(it) => it.loc(db), AnyClosureId::CoroutineClosureId(it) => it.loc(db), }; - let InternedClosure { owner: infer_owner, expr: closure, .. } = closure; - let infer = InferenceResult::of(db, infer_owner); - let owner = infer_owner.expression_store_owner(db); - infer.closures_data[&closure] - .min_captures - .values() - .flatten() - .map(|capture| ClosureCapture { owner, infer_owner, closure, capture }) - .collect() + captured_items(db, closure) } pub fn fn_trait(&self, _db: &dyn HirDatabase) -> FnTrait { @@ -4964,6 +4959,34 @@ impl<'db> Closure<'db> { } } +/// A coroutine expression, including async, generator, and async-generator coroutines. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct Coroutine { + id: InternedCoroutineId, +} + +impl Coroutine { + /// Returns the values captured by this coroutine. + pub fn captured_items<'db>(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db>> { + captured_items(db, self.id.loc(db)) + } +} + +fn captured_items<'db>( + db: &'db dyn HirDatabase, + closure: InternedClosure, +) -> Vec<ClosureCapture<'db>> { + let InternedClosure { owner: infer_owner, expr: closure, .. } = closure; + let infer = InferenceResult::of(db, infer_owner); + let owner = infer_owner.expression_store_owner(db); + infer.closures_data[&closure] + .min_captures + .values() + .flatten() + .map(|capture| ClosureCapture { owner, infer_owner, closure, capture }) + .collect() +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum FnTrait { FnOnce, @@ -5952,6 +5975,14 @@ impl<'db> Type<'db> { } } + /// Returns this type as a coroutine. + pub fn as_coroutine(&self) -> Option<Coroutine> { + match self.ty.skip_binder().kind() { + TyKind::Coroutine(id, _) => Some(Coroutine { id: id.0 }), + _ => None, + } + } + pub fn is_fn(&self) -> bool { matches!(self.ty.skip_binder().kind(), TyKind::FnDef(..) | TyKind::FnPtr { .. }) } |