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.
| -rw-r--r-- | crates/hir-def/src/hir.rs | 6 | ||||
| -rw-r--r-- | crates/hir-ty/src/db.rs | 11 | ||||
| -rw-r--r-- | crates/hir-ty/src/display.rs | 44 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/closure.rs | 17 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/coerce.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/lower.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/next_solver/interner.rs | 111 | ||||
| -rw-r--r-- | crates/hir-ty/src/next_solver/ty.rs | 4 | ||||
| -rw-r--r-- | crates/hir/src/has_source.rs | 2 | ||||
| -rw-r--r-- | crates/hir/src/lib.rs | 2 |
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] |