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.rs98
1 files changed, 63 insertions, 35 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 9418903123..2bb2f80ecc 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -75,7 +75,7 @@ use hir_ty::{
TraitEnvironment, TyDefId, TyLoweringDiagnostic, ValueTyDefId, all_super_traits, autoderef,
check_orphan_rules,
consteval::try_const_usize,
- db::InternedClosureId,
+ db::{InternedClosureId, InternedCoroutineId},
diagnostics::BodyValidationDiagnostic,
direct_super_traits, known_const_to_ast,
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
@@ -92,7 +92,7 @@ use itertools::Itertools;
use rustc_hash::FxHashSet;
use rustc_type_ir::{
AliasTyKind, TypeSuperVisitable, TypeVisitable, TypeVisitor,
- inherent::{AdtDef, IntoKind, SliceLike, Term as _, Ty as _},
+ inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _},
};
use smallvec::SmallVec;
use span::{AstIdNode, Edition, FileId};
@@ -4558,16 +4558,27 @@ impl<'db> TraitRef<'db> {
}
}
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+enum AnyClosureId {
+ ClosureId(InternedClosureId),
+ CoroutineClosureId(InternedCoroutineId),
+}
+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Closure<'db> {
- id: InternedClosureId,
+ id: AnyClosureId,
subst: GenericArgs<'db>,
}
impl<'db> Closure<'db> {
fn as_ty(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
let interner = DbInterner::new_with(db, None, None);
- Ty::new_closure(interner, self.id.into(), self.subst)
+ match self.id {
+ AnyClosureId::ClosureId(id) => Ty::new_closure(interner, id.into(), self.subst),
+ AnyClosureId::CoroutineClosureId(id) => {
+ Ty::new_coroutine_closure(interner, id.into(), self.subst)
+ }
+ }
}
pub fn display_with_id(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
@@ -4585,20 +4596,28 @@ impl<'db> Closure<'db> {
}
pub fn captured_items(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db>> {
- let owner = db.lookup_intern_closure(self.id).0;
+ let AnyClosureId::ClosureId(id) = self.id else {
+ // FIXME: Infer coroutine closures' captures.
+ return Vec::new();
+ };
+ let owner = db.lookup_intern_closure(id).0;
let infer = db.infer(owner);
- let info = infer.closure_info(self.id);
+ let info = infer.closure_info(id);
info.0
.iter()
.cloned()
- .map(|capture| ClosureCapture { owner, closure: self.id, capture })
+ .map(|capture| ClosureCapture { owner, closure: id, capture })
.collect()
}
pub fn capture_types(&self, db: &'db dyn HirDatabase) -> Vec<Type<'db>> {
- let owner = db.lookup_intern_closure(self.id).0;
+ let AnyClosureId::ClosureId(id) = self.id else {
+ // FIXME: Infer coroutine closures' captures.
+ return Vec::new();
+ };
+ let owner = db.lookup_intern_closure(id).0;
let infer = db.infer(owner);
- let (captures, _) = infer.closure_info(self.id);
+ let (captures, _) = infer.closure_info(id);
let env = db.trait_environment_for_body(owner);
captures
.iter()
@@ -4607,10 +4626,22 @@ impl<'db> Closure<'db> {
}
pub fn fn_trait(&self, db: &dyn HirDatabase) -> FnTrait {
- let owner = db.lookup_intern_closure(self.id).0;
- let infer = db.infer(owner);
- let info = infer.closure_info(self.id);
- info.1
+ match self.id {
+ AnyClosureId::ClosureId(id) => {
+ let owner = db.lookup_intern_closure(id).0;
+ let infer = db.infer(owner);
+ let info = infer.closure_info(id);
+ info.1
+ }
+ AnyClosureId::CoroutineClosureId(_id) => {
+ // FIXME: Infer kind for coroutine closures.
+ match self.subst.as_coroutine_closure().kind() {
+ rustc_type_ir::ClosureKind::Fn => FnTrait::AsyncFn,
+ rustc_type_ir::ClosureKind::FnMut => FnTrait::AsyncFnMut,
+ rustc_type_ir::ClosureKind::FnOnce => FnTrait::AsyncFnOnce,
+ }
+ }
+ }
}
}
@@ -5124,28 +5155,14 @@ impl<'db> Type<'db> {
let interner = DbInterner::new_with(db, None, None);
let callee = match self.ty.kind() {
TyKind::Closure(id, subst) => Callee::Closure(id.0, subst),
+ TyKind::CoroutineClosure(id, subst) => Callee::CoroutineClosure(id.0, subst),
TyKind::FnPtr(..) => Callee::FnPtr,
TyKind::FnDef(id, _) => Callee::Def(id.0),
- kind => {
- // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment
- let (ty, kind) = if let TyKind::Ref(_, ty, _) = kind {
- (ty, ty.kind())
- } else {
- (self.ty, kind)
- };
- if let TyKind::Closure(closure, subst) = kind {
- let sig = subst
- .split_closure_args_untupled()
- .closure_sig_as_fn_ptr_ty
- .callable_sig(interner)?;
- return Some(Callable {
- ty: self.clone(),
- sig,
- callee: Callee::Closure(closure.0, subst),
- is_bound_method: false,
- });
- }
- let (fn_trait, sig) = hir_ty::callable_sig_from_fn_trait(ty, self.env.clone(), db)?;
+ // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment
+ TyKind::Ref(_, inner_ty, _) => return self.derived(inner_ty).as_callable(db),
+ _ => {
+ let (fn_trait, sig) =
+ hir_ty::callable_sig_from_fn_trait(self.ty, self.env.clone(), db)?;
return Some(Callable {
ty: self.clone(),
sig,
@@ -5165,7 +5182,12 @@ impl<'db> Type<'db> {
pub fn as_closure(&self) -> Option<Closure<'db>> {
match self.ty.kind() {
- TyKind::Closure(id, subst) => Some(Closure { id: id.0, subst }),
+ TyKind::Closure(id, subst) => {
+ Some(Closure { id: AnyClosureId::ClosureId(id.0), subst })
+ }
+ TyKind::CoroutineClosure(id, subst) => {
+ Some(Closure { id: AnyClosureId::CoroutineClosureId(id.0), subst })
+ }
_ => None,
}
}
@@ -5824,6 +5846,7 @@ pub struct Callable<'db> {
enum Callee<'db> {
Def(CallableDefId),
Closure(InternedClosureId, GenericArgs<'db>),
+ CoroutineClosure(InternedCoroutineId, GenericArgs<'db>),
FnPtr,
FnImpl(FnTrait),
}
@@ -5845,7 +5868,12 @@ impl<'db> Callable<'db> {
Callee::Def(CallableDefId::EnumVariantId(it)) => {
CallableKind::TupleEnumVariant(it.into())
}
- Callee::Closure(id, ref subst) => CallableKind::Closure(Closure { id, subst: *subst }),
+ Callee::Closure(id, subst) => {
+ CallableKind::Closure(Closure { id: AnyClosureId::ClosureId(id), subst })
+ }
+ Callee::CoroutineClosure(id, subst) => {
+ CallableKind::Closure(Closure { id: AnyClosureId::CoroutineClosureId(id), subst })
+ }
Callee::FnPtr => CallableKind::FnPtr,
Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_),
}