Unnamed repository; edit this file 'description' to name the repository.
Add `ClosureKind` to `InternedClosure`
It doesn't add much weight, and it's useful for retrieval.
Chayim Refael Friedman 3 weeks ago
parent 0089b5d · commit 4ad089b
-rw-r--r--crates/hir-def/src/hir.rs6
-rw-r--r--crates/hir-ty/src/db.rs11
-rw-r--r--crates/hir-ty/src/display.rs44
-rw-r--r--crates/hir-ty/src/infer/closure.rs17
-rw-r--r--crates/hir-ty/src/infer/coerce.rs2
-rw-r--r--crates/hir-ty/src/mir/lower.rs2
-rw-r--r--crates/hir-ty/src/next_solver/interner.rs111
-rw-r--r--crates/hir-ty/src/next_solver/ty.rs4
-rw-r--r--crates/hir/src/has_source.rs2
-rw-r--r--crates/hir/src/lib.rs2
10 files changed, 76 insertions, 125 deletions
diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs
index 6bea505757..125a393bd9 100644
--- a/crates/hir-def/src/hir.rs
+++ b/crates/hir-def/src/hir.rs
@@ -524,14 +524,14 @@ pub enum InlineAsmRegOrRegClass {
RegClass(Symbol),
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CoroutineKind {
Async,
Gen,
AsyncGen,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ClosureKind {
Closure,
OldCoroutine(Movability),
@@ -564,7 +564,7 @@ pub enum CaptureBy {
Ref,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Movability {
Static,
Movable,
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 65b2d53398..2e130c1028 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -6,8 +6,12 @@ use either::Either;
use hir_def::{
AdtId, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId,
ExpressionStoreOwnerId, FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId,
- StaticId, TraitId, TypeAliasId, VariantId, builtin_derive::BuiltinDeriveImplMethod,
- db::DefDatabase, expr_store::ExpressionStore, hir::ExprId, layout::TargetDataLayout,
+ StaticId, TraitId, TypeAliasId, VariantId,
+ builtin_derive::BuiltinDeriveImplMethod,
+ db::DefDatabase,
+ expr_store::ExpressionStore,
+ hir::{ClosureKind, ExprId},
+ layout::TargetDataLayout,
};
use la_arena::ArenaMap;
use salsa::plumbing::AsId;
@@ -229,10 +233,11 @@ pub struct InternedOpaqueTyId {
pub loc: ImplTraitId,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct InternedClosure {
pub owner: ExpressionStoreOwnerId,
pub expr: ExprId,
+ pub kind: ClosureKind,
}
#[salsa_macros::interned(constructor = new_impl, no_lifetime, debug, revisions = usize::MAX)]
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 0b06c10e1c..ca3723f8ef 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -51,7 +51,7 @@ use stdx::never;
use crate::{
CallableDefId, FnAbi, ImplTraitId, MemoryMap, ParamEnvAndCrate, consteval,
- db::{HirDatabase, InternedClosure},
+ db::HirDatabase,
generics::generics,
layout::Layout,
lower::GenericPredicates,
@@ -1552,16 +1552,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
TyKind::CoroutineClosure(id, args) => {
let id = id.0;
- let closure_kind = match id.loc(db) {
- InternedClosure(owner, expr_id) => {
- match &ExpressionStore::of(db, owner)[expr_id] {
- hir_def::hir::Expr::Closure {
- closure_kind: HirClosureKind::CoroutineClosure(kind),
- ..
- } => *kind,
- expr => panic!("invalid expr for coroutine closure: {expr:?}"),
- }
- }
+ let closure_kind = match id.loc(db).kind {
+ HirClosureKind::CoroutineClosure(kind) => kind,
+ kind => panic!("invalid kind for coroutine closure: {kind:?}"),
};
let closure_label = match closure_kind {
CoroutineKind::Async => "async closure",
@@ -1726,16 +1719,11 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
TyKind::Infer(..) => write!(f, "_")?,
TyKind::Coroutine(coroutine_id, subst) => {
- let InternedClosure { owner, expr: expr_id } = coroutine_id.0.loc(db);
+ let kind = coroutine_id.0.loc(db).kind;
let CoroutineArgsParts { resume_ty, yield_ty, return_ty, .. } =
subst.split_coroutine_args();
- let body = ExpressionStore::of(db, owner);
- let expr = &body[expr_id];
- match expr {
- hir_def::hir::Expr::Closure {
- closure_kind: HirClosureKind::Coroutine { kind: CoroutineKind::Async, .. },
- ..
- } => {
+ match kind {
+ HirClosureKind::Coroutine { kind: CoroutineKind::Async, .. } => {
let future_trait = f.lang_items().Future;
let output = future_trait.and_then(|t| {
t.trait_items(db)
@@ -1761,10 +1749,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
return_ty.hir_fmt(f)?;
write!(f, ">")?;
}
- hir_def::hir::Expr::Closure {
- closure_kind: HirClosureKind::Coroutine { kind: CoroutineKind::Gen, .. },
- ..
- } => {
+ HirClosureKind::Coroutine { kind: CoroutineKind::Gen, .. } => {
let iterator_trait = f.lang_items().Iterator;
let item = iterator_trait.and_then(|t| {
t.trait_items(db)
@@ -1790,11 +1775,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
yield_ty.hir_fmt(f)?;
write!(f, ">")?;
}
- hir_def::hir::Expr::Closure {
- closure_kind:
- HirClosureKind::Coroutine { kind: CoroutineKind::AsyncGen, .. },
- ..
- } => {
+ HirClosureKind::Coroutine { kind: CoroutineKind::AsyncGen, .. } => {
let async_iterator_trait = f.lang_items().AsyncIterator;
let item = async_iterator_trait.and_then(|t| {
t.trait_items(db)
@@ -1822,10 +1803,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
item_ty.hir_fmt(f)?;
write!(f, ">")?;
}
- hir_def::hir::Expr::Closure {
- closure_kind: HirClosureKind::OldCoroutine(..),
- ..
- } => {
+ HirClosureKind::OldCoroutine(..) => {
if f.display_kind.is_source_code() {
return Err(HirDisplayError::DisplaySourceCodeError(
DisplaySourceCodeError::Coroutine,
@@ -1841,7 +1819,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
write!(f, " -> ")?;
return_ty.hir_fmt(f)?;
}
- _ => panic!("invalid expr for coroutine: {expr:?}"),
+ _ => panic!("invalid kind for coroutine: {kind:?}"),
}
}
TyKind::CoroutineWitness(..) => write!(f, "{{coroutine witness}}")?,
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 86e82eb222..f90f135919 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -95,6 +95,8 @@ impl<'db> InferenceContext<'_, 'db> {
let tupled_upvars_ty = self.table.next_ty_var(closure_expr.into());
+ let closure_loc =
+ InternedClosure { owner: self.owner, expr: closure_expr, kind: closure_kind };
// FIXME: We could probably actually just unify this further --
// instead of having a `FnSig` and a `Option<CoroutineTypes>`,
// we can have a `ClosureSignature { Coroutine { .. }, Closure { .. } }`,
@@ -132,10 +134,7 @@ impl<'db> InferenceContext<'_, 'db> {
},
);
- let closure_id = InternedClosureId::new(
- self.db,
- InternedClosure { owner: self.owner, expr: closure_expr },
- );
+ let closure_id = InternedClosureId::new(self.db, closure_loc);
(Ty::new_closure(interner, closure_id.into(), closure_args.args), None)
}
@@ -185,10 +184,7 @@ impl<'db> InferenceContext<'_, 'db> {
},
);
- let coroutine_id = InternedCoroutineId::new(
- self.db,
- InternedClosure { owner: self.owner, expr: closure_expr },
- );
+ let coroutine_id = InternedCoroutineId::new(self.db, closure_loc);
(
Ty::new_coroutine(interner, coroutine_id.into(), coroutine_args.args),
@@ -260,10 +256,7 @@ impl<'db> InferenceContext<'_, 'db> {
let coroutine_upvars_ty = self.table.next_ty_var(closure_expr.into());
- let coroutine_closure_id = InternedCoroutineClosureId::new(
- self.db,
- InternedClosure { owner: self.owner, expr: closure_expr },
- );
+ let coroutine_closure_id = InternedCoroutineClosureId::new(self.db, closure_loc);
// We need to turn the liberated signature that we got from HIR, which
// looks something like `|Args...| -> T`, into a signature that is suitable
diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs
index 1c355c2065..ddff23e840 100644
--- a/crates/hir-ty/src/infer/coerce.rs
+++ b/crates/hir-ty/src/infer/coerce.rs
@@ -1601,7 +1601,7 @@ fn coerce<'db>(
}
fn is_capturing_closure(db: &dyn HirDatabase, closure: InternedClosureId) -> bool {
- let InternedClosure { owner, expr } = closure.loc(db);
+ let InternedClosure { owner, expr, .. } = closure.loc(db);
upvars_mentioned(db, owner)
.is_some_and(|upvars| upvars.get(&expr).is_some_and(|upvars| !upvars.is_empty()))
}
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 11972e64d0..7dcc00858e 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -2144,7 +2144,7 @@ pub fn mir_body_for_closure_query<'db>(
db: &'db dyn HirDatabase,
closure: InternedClosureId,
) -> Result<'db, Arc<MirBody>> {
- let InternedClosure { owner, expr } = closure.loc(db);
+ let InternedClosure { owner, expr, .. } = closure.loc(db);
let body_owner =
owner.as_def_with_body().expect("MIR lowering should only happen for body-owned closures");
let body = Body::of(db, body_owner);
diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs
index 46ad4488a6..b8b8d15347 100644
--- a/crates/hir-ty/src/next_solver/interner.rs
+++ b/crates/hir-ty/src/next_solver/interner.rs
@@ -14,6 +14,7 @@ use hir_def::{
ItemContainerId, StructId, UnionId, VariantId,
attrs::AttrFlags,
expr_store::{Body, ExpressionStore},
+ hir::{ClosureKind as HirClosureKind, CoroutineKind as HirCoroutineKind},
lang_item::LangItems,
signatures::{
EnumSignature, FieldData, FnFlags, FunctionSignature, ImplFlags, ImplSignature,
@@ -1311,28 +1312,35 @@ impl<'db> Interner for DbInterner<'db> {
}
fn coroutine_movability(self, def_id: Self::CoroutineId) -> rustc_ast_ir::Movability {
- // FIXME: Make this a query? I don't believe this can be accessed from bodies other than
- // the current infer query, except with revealed opaques - is it rare enough to not matter?
- let InternedClosure { owner, expr: expr_id } = def_id.0.loc(self.db);
- let store = ExpressionStore::of(self.db, owner);
- let expr = &store[expr_id];
- match *expr {
- hir_def::hir::Expr::Closure { closure_kind, .. } => match closure_kind {
- hir_def::hir::ClosureKind::OldCoroutine(movability) => match movability {
- hir_def::hir::Movability::Static => rustc_ast_ir::Movability::Static,
- hir_def::hir::Movability::Movable => rustc_ast_ir::Movability::Movable,
- },
- hir_def::hir::ClosureKind::Coroutine { .. } => rustc_ast_ir::Movability::Static,
- _ => panic!("unexpected expression for a coroutine: {expr:?}"),
+ match def_id.0.loc(self.db).kind {
+ hir_def::hir::ClosureKind::OldCoroutine(movability) => match movability {
+ hir_def::hir::Movability::Static => rustc_ast_ir::Movability::Static,
+ hir_def::hir::Movability::Movable => rustc_ast_ir::Movability::Movable,
},
- _ => panic!("unexpected expression for a coroutine: {expr:?}"),
+ hir_def::hir::ClosureKind::Coroutine { .. } => rustc_ast_ir::Movability::Static,
+ kind => panic!("unexpected kind for a coroutine: {kind:?}"),
}
}
fn coroutine_for_closure(self, def_id: Self::CoroutineClosureId) -> Self::CoroutineId {
- let InternedClosure { owner, expr: coroutine_closure_expr } = def_id.0.loc(self.db);
+ let InternedClosure { owner, expr: coroutine_closure_expr, kind: coroutine_closure_kind } =
+ def_id.0.loc(self.db);
+ let coroutine_closure_kind = match coroutine_closure_kind {
+ HirClosureKind::CoroutineClosure(it) => it,
+ _ => {
+ panic!("invalid kind closure kind {coroutine_closure_kind:?} for coroutine closure")
+ }
+ };
let coroutine_expr = ExpressionStore::coroutine_for_closure(coroutine_closure_expr);
- InternedCoroutineId::new(self.db, InternedClosure { owner, expr: coroutine_expr }).into()
+ let coroutine_kind = hir_def::hir::ClosureKind::Coroutine {
+ kind: coroutine_closure_kind,
+ source: hir_def::hir::CoroutineSource::Closure,
+ };
+ InternedCoroutineId::new(
+ self.db,
+ InternedClosure { owner, expr: coroutine_expr, kind: coroutine_kind },
+ )
+ .into()
}
fn generics_require_sized_self(self, def_id: Self::DefId) -> bool {
@@ -1936,63 +1944,27 @@ impl<'db> Interner for DbInterner<'db> {
}
fn is_general_coroutine(self, def_id: Self::CoroutineId) -> bool {
- // FIXME: Make this a query? I don't believe this can be accessed from bodies other than
- // the current infer query, except with revealed opaques - is it rare enough to not matter?
- let InternedClosure { owner, expr: expr_id } = def_id.0.loc(self.db);
- let store = ExpressionStore::of(self.db, owner);
- matches!(
- store[expr_id],
- hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::OldCoroutine(_),
- ..
- }
- )
+ matches!(def_id.0.loc(self.db).kind, HirClosureKind::OldCoroutine(_))
}
fn coroutine_is_async(self, def_id: Self::CoroutineId) -> bool {
- // FIXME: Make this a query? I don't believe this can be accessed from bodies other than
- // the current infer query, except with revealed opaques - is it rare enough to not matter?
- let InternedClosure { owner, expr: expr_id } = def_id.0.loc(self.db);
- let store = ExpressionStore::of(self.db, owner);
matches!(
- store[expr_id],
- hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::Coroutine {
- kind: hir_def::hir::CoroutineKind::Async,
- ..
- },
- ..
- }
+ def_id.0.loc(self.db).kind,
+ HirClosureKind::Coroutine { kind: HirCoroutineKind::Async, .. }
)
}
fn coroutine_is_gen(self, def_id: Self::CoroutineId) -> bool {
- let InternedClosure(owner, expr_id) = def_id.0.loc(self.db);
- let store = ExpressionStore::of(self.db, owner);
matches!(
- store[expr_id],
- hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::Coroutine {
- kind: hir_def::hir::CoroutineKind::Gen,
- ..
- },
- ..
- }
+ def_id.0.loc(self.db).kind,
+ HirClosureKind::Coroutine { kind: HirCoroutineKind::Gen, .. }
)
}
fn coroutine_is_async_gen(self, def_id: Self::CoroutineId) -> bool {
- let InternedClosure(owner, expr_id) = def_id.0.loc(self.db);
- let store = ExpressionStore::of(self.db, owner);
matches!(
- store[expr_id],
- hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::Coroutine {
- kind: hir_def::hir::CoroutineKind::AsyncGen,
- ..
- },
- ..
- }
+ def_id.0.loc(self.db).kind,
+ HirClosureKind::Coroutine { kind: HirCoroutineKind::AsyncGen, .. }
)
}
@@ -2104,17 +2076,20 @@ impl<'db> Interner for DbInterner<'db> {
// Collect coroutines.
let body = Body::of(self.db, def_id);
body.exprs().for_each(|(expr_id, expr)| {
- if matches!(
- expr,
- hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::Coroutine { .. }
- | hir_def::hir::ClosureKind::OldCoroutine(_),
- ..
- }
- ) {
+ if let hir_def::hir::Expr::Closure {
+ closure_kind:
+ kind @ (hir_def::hir::ClosureKind::Coroutine { .. }
+ | hir_def::hir::ClosureKind::OldCoroutine(_)),
+ ..
+ } = *expr
+ {
let coroutine = InternedCoroutineId::new(
self.db,
- InternedClosure { owner: ExpressionStoreOwnerId::Body(def_id), expr: expr_id },
+ InternedClosure {
+ owner: ExpressionStoreOwnerId::Body(def_id),
+ expr: expr_id,
+ kind,
+ },
);
result.push(coroutine.into());
}
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs
index e8945a77c3..22595214b4 100644
--- a/crates/hir-ty/src/next_solver/ty.rs
+++ b/crates/hir-ty/src/next_solver/ty.rs
@@ -27,7 +27,7 @@ use rustc_type_ir::{
use crate::{
FnAbi,
- db::{HirDatabase, InternedClosure},
+ db::HirDatabase,
lower::GenericPredicates,
next_solver::{
AdtDef, AliasTy, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const,
@@ -757,7 +757,7 @@ impl<'db> Ty<'db> {
}
}
TyKind::Coroutine(coroutine_id, _args) => {
- let InternedClosure { owner, expr: _ } = coroutine_id.0.loc(db);
+ let owner = coroutine_id.0.loc(db).owner;
let krate = owner.krate(db);
if let Some(future_trait) = hir_def::lang_item::lang_items(db, krate).Future {
// This is only used by type walking.
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index 36e6bdf3fb..3e7745c090 100644
--- a/crates/hir/src/has_source.rs
+++ b/crates/hir/src/has_source.rs
@@ -293,7 +293,7 @@ impl HasSource for Param<'_> {
.map(|value| InFile { file_id, value })
}
Callee::Closure(closure, _) => {
- let InternedClosure { owner, expr: expr_id } = closure.loc(db);
+ let InternedClosure { owner, expr: expr_id, .. } = closure.loc(db);
let (_, source_map) = ExpressionStore::with_source_map(db, owner);
let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?;
let root = db.parse_or_expand(file_id);
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 150f90fa97..df9f743224 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -5165,7 +5165,7 @@ impl<'db> Closure<'db> {
AnyClosureId::ClosureId(it) => it.loc(db),
AnyClosureId::CoroutineClosureId(it) => it.loc(db),
};
- let InternedClosure { owner, expr: closure } = closure;
+ let InternedClosure { owner, expr: closure, .. } = closure;
let infer = InferenceResult::of(db, owner);
let param_env = body_param_env_from_has_crate(db, owner);
infer.closures_data[&closure]