about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <me@lukaswirth.dev>2025-06-15 08:43:22 +0200
committerLukas Wirth <me@lukaswirth.dev>2025-06-15 09:03:44 +0200
commit0d5fde22b1645dcd851e284840da561d933d00e3 (patch)
tree569ec96c93f8f800fc9a69d2830ef718a276a4e3
parent535b9744b651d424c60b195ba15bae3e9c79b61e (diff)
downloadrust-0d5fde22b1645dcd851e284840da561d933d00e3.tar.gz
rust-0d5fde22b1645dcd851e284840da561d933d00e3.zip
Idiomatic salsa use for enum variants query
-rw-r--r--src/tools/rust-analyzer/Cargo.toml4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/db.rs20
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/find_path.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/signatures.rs15
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/drop.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tls.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/variance.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs2
33 files changed, 81 insertions, 77 deletions
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index c5f061cad7d..c791d741b02 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -134,7 +134,9 @@ pulldown-cmark-to-cmark = "10.0.4"
 pulldown-cmark = { version = "0.9.6", default-features = false }
 rayon = "1.10.0"
 rowan = "=0.15.15"
-salsa = { version = "0.22.0", default-features = false, features = ["rayon","salsa_unstable"] }
+# Ideally we'd not enable the macros feature but unfortunately the `tracked` attribute does not work
+# on impls without it
+salsa = { version = "0.22.0", default-features = true, features = ["rayon","salsa_unstable", "macros"] }
 salsa-macros = "0.22.0"
 semver = "1.0.26"
 serde = { version = "1.0.219" }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
index f024f04efe0..2fc79c3809f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -8,7 +8,6 @@ use hir_expand::{
 use intern::{Symbol, sym};
 use la_arena::ArenaMap;
 use syntax::{AstPtr, ast};
-use thin_vec::ThinVec;
 use triomphe::Arc;
 
 use crate::{
@@ -32,9 +31,9 @@ use crate::{
         diagnostics::DefDiagnostics,
     },
     signatures::{
-        ConstSignature, EnumSignature, EnumVariants, FunctionSignature, ImplSignature,
-        InactiveEnumVariantCode, StaticSignature, StructSignature, TraitAliasSignature,
-        TraitSignature, TypeAliasSignature, UnionSignature, VariantFields,
+        ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature,
+        StructSignature, TraitAliasSignature, TraitSignature, TypeAliasSignature, UnionSignature,
+        VariantFields,
     },
     tt,
     visibility::{self, Visibility},
@@ -121,19 +120,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
         id: VariantId,
     ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>);
 
-    // FIXME: Should we make this transparent? The only unstable thing in `enum_variants_with_diagnostics()`
-    // is ast ids, and ast ids are pretty stable now.
-    #[salsa::tracked]
-    fn enum_variants(&self, id: EnumId) -> Arc<EnumVariants> {
-        self.enum_variants_with_diagnostics(id).0
-    }
-
-    #[salsa::invoke(EnumVariants::enum_variants_query)]
-    fn enum_variants_with_diagnostics(
-        &self,
-        id: EnumId,
-    ) -> (Arc<EnumVariants>, Option<Arc<ThinVec<InactiveEnumVariantCode>>>);
-
     #[salsa::transparent]
     #[salsa::invoke(ImplItems::impl_items_query)]
     fn impl_items(&self, e: ImplId) -> Arc<ImplItems>;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
index bb75621c7e0..6ebc0d8dfd9 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs
@@ -137,7 +137,7 @@ fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Opt
         let loc = variant.lookup(ctx.db);
         if let Some(mut path) = find_path_inner(ctx, ItemInNs::Types(loc.parent.into()), max_len) {
             path.push_segment(
-                ctx.db.enum_variants(loc.parent).variants[loc.index as usize].1.clone(),
+                loc.parent.enum_variants(ctx.db).variants[loc.index as usize].1.clone(),
             );
             return Some(path);
         }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
index 8f071cd953a..c0e30ac7956 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
@@ -125,7 +125,7 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangIt
                 }
                 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
                     lang_items.collect_lang_item(db, e, LangItemTarget::EnumId);
-                    db.enum_variants(e).variants.iter().for_each(|&(id, _, _)| {
+                    e.enum_variants(db).variants.iter().for_each(|&(id, _, _)| {
                         lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant);
                     });
                 }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index e7ab2b4d77d..be5bb57ade6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -51,6 +51,7 @@ pub mod visibility;
 
 use intern::{Interned, sym};
 pub use rustc_abi as layout;
+use thin_vec::ThinVec;
 use triomphe::Arc;
 
 pub use crate::signatures::LocalFieldId;
@@ -88,7 +89,7 @@ use crate::{
     db::DefDatabase,
     hir::generics::{LocalLifetimeParamId, LocalTypeOrConstParamId},
     nameres::{LocalDefMap, block_def_map, crate_def_map, crate_local_def_map},
-    signatures::VariantFields,
+    signatures::{EnumVariants, InactiveEnumVariantCode, VariantFields},
 };
 
 type FxIndexMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
@@ -253,6 +254,21 @@ impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
 pub type EnumLoc = ItemLoc<ast::Enum>;
 impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
 
+impl EnumId {
+    #[inline]
+    pub fn enum_variants(self, db: &dyn DefDatabase) -> &EnumVariants {
+        &self.enum_variants_with_diagnostics(db).0
+    }
+
+    #[inline]
+    pub fn enum_variants_with_diagnostics(
+        self,
+        db: &dyn DefDatabase,
+    ) -> &(EnumVariants, Option<ThinVec<InactiveEnumVariantCode>>) {
+        EnumVariants::of(db, self)
+    }
+}
+
 type ConstLoc = AssocItemLoc<ast::Const>;
 impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
 
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index 29f94ac2dca..3a2faae366f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -995,9 +995,8 @@ impl<'db> DefCollector<'db> {
                     Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => {
                         cov_mark::hit!(glob_enum);
                         // glob import from enum => just import all the variants
-                        let resolutions = self
-                            .db
-                            .enum_variants(e)
+                        let resolutions = e
+                            .enum_variants(self.db)
                             .variants
                             .iter()
                             .map(|&(variant, ref name, _)| {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
index e0e32a77735..ca39173d477 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs
@@ -528,8 +528,8 @@ impl DefMap {
                     // enum variant
                     cov_mark::hit!(can_import_enum_variant);
 
-                    let res = db
-                        .enum_variants(e)
+                    let res = e
+                        .enum_variants(db)
                         .variants
                         .iter()
                         .find(|(_, name, _)| name == segment)
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
index 858aa055edf..77e706caed7 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
@@ -172,8 +172,7 @@ fn no() {}
                 "ast_id_map_shim",
                 "parse_shim",
                 "real_span_map_shim",
-                "enum_variants_shim",
-                "enum_variants_with_diagnostics_shim",
+                "of_",
             ]
         "#]],
         expect![[r#"
@@ -182,7 +181,7 @@ fn no() {}
                 "ast_id_map_shim",
                 "file_item_tree_query",
                 "real_span_map_shim",
-                "enum_variants_with_diagnostics_shim",
+                "of_",
             ]
         "#]],
     );
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs
index b7d29f54d08..c8080790117 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs
@@ -884,11 +884,13 @@ pub struct EnumVariants {
     pub variants: Box<[(EnumVariantId, Name, FieldsShape)]>,
 }
 
+#[salsa::tracked]
 impl EnumVariants {
-    pub(crate) fn enum_variants_query(
+    #[salsa::tracked(returns(ref))]
+    pub(crate) fn of(
         db: &dyn DefDatabase,
         e: EnumId,
-    ) -> (Arc<EnumVariants>, Option<Arc<ThinVec<InactiveEnumVariantCode>>>) {
+    ) -> (EnumVariants, Option<ThinVec<InactiveEnumVariantCode>>) {
         let loc = e.lookup(db);
         let source = loc.source(db);
         let ast_id_map = db.ast_id_map(source.file_id);
@@ -898,7 +900,7 @@ impl EnumVariants {
         let cfg_options = loc.container.krate.cfg_options(db);
         let mut index = 0;
         let Some(variants) = source.value.variant_list() else {
-            return (Arc::new(EnumVariants { variants: Box::default() }), None);
+            return (EnumVariants { variants: Box::default() }, None);
         };
         let variants = variants
             .variants()
@@ -926,12 +928,11 @@ impl EnumVariants {
             })
             .collect();
 
-        (
-            Arc::new(EnumVariants { variants }),
-            diagnostics.is_empty().not().then(|| Arc::new(diagnostics)),
-        )
+        (EnumVariants { variants }, diagnostics.is_empty().not().then_some(diagnostics))
     }
+}
 
+impl EnumVariants {
     pub fn variant(&self, name: &Name) -> Option<EnumVariantId> {
         self.variants.iter().find_map(|(v, n, _)| if n == name { Some(*v) } else { None })
     }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
index f658e236658..cf439245137 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
@@ -823,8 +823,8 @@ pub(crate) fn adt_datum_query(
             (rust_ir::AdtKind::Struct, vec![variant_id_to_fields(id.into())])
         }
         hir_def::AdtId::EnumId(id) => {
-            let variants = db
-                .enum_variants(id)
+            let variants = id
+                .enum_variants(db)
                 .variants
                 .iter()
                 .map(|&(variant_id, _, _)| variant_id_to_fields(variant_id.into()))
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
index f903b06d65e..24530a5f67c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs
@@ -286,7 +286,7 @@ pub(crate) fn const_eval_discriminant_variant(
         let value = match prev_idx {
             Some(prev_idx) => {
                 1 + db.const_eval_discriminant(
-                    db.enum_variants(loc.parent).variants[prev_idx as usize].0,
+                    loc.parent.enum_variants(db).variants[prev_idx as usize].0,
                 )?
             }
             _ => 0,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
index fae129fddbf..1873f12fb7c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -395,7 +395,7 @@ impl<'a> DeclValidator<'a> {
 
     /// Check incorrect names for enum variants.
     fn validate_enum_variants(&mut self, enum_id: EnumId) {
-        let data = self.db.enum_variants(enum_id);
+        let data = enum_id.enum_variants(self.db);
 
         for (variant_id, _, _) in data.variants.iter() {
             self.validate_enum_variant_fields(*variant_id);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
index 9eb7ffe1c71..df2eb410b99 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
@@ -642,7 +642,7 @@ fn missing_match_arms<'p>(
     }
 
     let non_empty_enum = match scrut_ty.as_adt() {
-        Some((AdtId::EnumId(e), _)) => !cx.db.enum_variants(e).variants.is_empty(),
+        Some((AdtId::EnumId(e), _)) => !e.enum_variants(cx.db).variants.is_empty(),
         _ => false,
     };
     let display_target = DisplayTarget::from_crate(cx.db, krate);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
index 7df22a45cb4..916876d4ac9 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
@@ -328,7 +328,7 @@ impl HirDisplay for Pat {
                             write!(
                                 f,
                                 "{}",
-                                f.db.enum_variants(loc.parent).variants[loc.index as usize]
+                                loc.parent.enum_variants(f.db).variants[loc.index as usize]
                                     .1
                                     .display(f.db, f.edition())
                             )?;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index 0914b5aac50..2873a3e09e7 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -50,7 +50,7 @@ impl EnumVariantContiguousIndex {
     }
 
     fn to_enum_variant_id(self, db: &dyn HirDatabase, eid: EnumId) -> EnumVariantId {
-        db.enum_variants(eid).variants[self.0].0
+        eid.enum_variants(db).variants[self.0].0
     }
 }
 
@@ -458,7 +458,7 @@ impl PatCx for MatchCheckCtx<'_> {
             TyKind::Scalar(Scalar::Int(..) | Scalar::Uint(..)) => unhandled(),
             TyKind::Array(..) | TyKind::Slice(..) => unhandled(),
             &TyKind::Adt(AdtId(adt @ hir_def::AdtId::EnumId(enum_id)), ref subst) => {
-                let enum_data = cx.db.enum_variants(enum_id);
+                let enum_data = enum_id.enum_variants(cx.db);
                 let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive(adt);
 
                 if enum_data.variants.is_empty() && !is_declared_nonexhaustive {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index f210dd8799f..da21f08a1e1 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -914,7 +914,7 @@ fn render_const_scalar(
                     write!(
                         f,
                         "{}",
-                        f.db.enum_variants(loc.parent).variants[loc.index as usize]
+                        loc.parent.enum_variants(f.db).variants[loc.index as usize]
                             .1
                             .display(f.db, f.edition())
                     )?;
@@ -1208,7 +1208,7 @@ impl HirDisplay for Ty {
                         write!(
                             f,
                             "{}",
-                            db.enum_variants(loc.parent).variants[loc.index as usize]
+                            loc.parent.enum_variants(db).variants[loc.index as usize]
                                 .1
                                 .display(db, f.edition())
                         )?
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
index b9b0f982866..5577be890da 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
@@ -67,8 +67,8 @@ pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironm
                 }
                 // Unions cannot have fields with destructors.
                 AdtId::UnionId(_) => DropGlue::None,
-                AdtId::EnumId(id) => db
-                    .enum_variants(id)
+                AdtId::EnumId(id) => id
+                    .enum_variants(db)
                     .variants
                     .iter()
                     .map(|&(variant, _, _)| {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index 14eb7160753..80478f19371 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -1673,7 +1673,7 @@ impl<'db> InferenceContext<'db> {
                     // If we can resolve to an enum variant, it takes priority over associated type
                     // of the same name.
                     if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
-                        let enum_data = self.db.enum_variants(id);
+                        let enum_data = id.enum_variants(self.db);
                         if let Some(variant) = enum_data.variant(current_segment.name) {
                             return if remaining_segments.len() == 1 {
                                 (ty, Some(variant.into()))
@@ -1792,7 +1792,7 @@ impl<'db> InferenceContext<'db> {
                 let segment = path.segments().last().unwrap();
                 // this could be an enum variant or associated type
                 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
-                    let enum_data = self.db.enum_variants(enum_id);
+                    let enum_data = enum_id.enum_variants(self.db);
                     if let Some(variant) = enum_data.variant(segment) {
                         return (ty, Some(variant.into()));
                     }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
index 10d85792c9d..8d345defdc1 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
@@ -43,7 +43,7 @@ impl CastTy {
                 let (AdtId::EnumId(id), _) = t.as_adt()? else {
                     return None;
                 };
-                let enum_data = table.db.enum_variants(id);
+                let enum_data = id.enum_variants(table.db);
                 if enum_data.is_payload_free(table.db) { Some(Self::Int(Int::CEnum)) } else { None }
             }
             TyKind::Raw(m, ty) => Some(Self::Ptr(ty.clone(), *m)),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
index bd57ca89162..d1432cacf8d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
@@ -1360,7 +1360,7 @@ impl InferenceContext<'_> {
                 if let Some(variant) = self.result.variant_resolution_for_pat(p) {
                     let adt = variant.adt_id(self.db);
                     let is_multivariant = match adt {
-                        hir_def::AdtId::EnumId(e) => self.db.enum_variants(e).variants.len() != 1,
+                        hir_def::AdtId::EnumId(e) => e.enum_variants(self.db).variants.len() != 1,
                         _ => false,
                     };
                     if is_multivariant {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
index 9d4bbe53464..c327c13b664 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs
@@ -397,7 +397,7 @@ impl InferenceContext<'_> {
             Some((AdtId::EnumId(e), subst)) => (e, subst),
             _ => return None,
         };
-        let enum_data = self.db.enum_variants(enum_id);
+        let enum_data = enum_id.enum_variants(self.db);
         let variant = enum_data.variant(name)?;
         self.write_variant_resolution(id, variant.into());
         Some((ValueNs::EnumVariantId(variant), subst.clone()))
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
index 8be812d8d5e..79a99321f10 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
@@ -113,7 +113,7 @@ impl UninhabitedFrom<'_> {
             AdtId::UnionId(_) => CONTINUE_OPAQUELY_INHABITED,
             AdtId::StructId(s) => self.visit_variant(s.into(), subst),
             AdtId::EnumId(e) => {
-                let enum_data = self.db.enum_variants(e);
+                let enum_data = e.enum_variants(self.db);
 
                 for &(variant, _, _) in enum_data.variants.iter() {
                     let variant_inhabitedness = self.visit_variant(variant.into(), subst);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
index a886c33d157..dff986fec3c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
@@ -56,7 +56,7 @@ pub fn layout_of_adt_query(
             (r, data.repr.unwrap_or_default(), false)
         }
         AdtId::EnumId(e) => {
-            let variants = db.enum_variants(e);
+            let variants = e.enum_variants(db);
             let r = variants
                 .variants
                 .iter()
@@ -82,7 +82,7 @@ pub fn layout_of_adt_query(
             |min, max| repr_discr(dl, &repr, min, max).unwrap_or((Integer::I8, false)),
             variants.iter_enumerated().filter_map(|(id, _)| {
                 let AdtId::EnumId(e) = def else { return None };
-                let d = db.const_eval_discriminant(db.enum_variants(e).variants[id.0].0).ok()?;
+                let d = db.const_eval_discriminant(e.enum_variants(db).variants[id.0].0).ok()?;
                 Some((id, d))
             }),
             // FIXME: The current code for niche-filling relies on variant indices
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index da6e4e5d8a1..a8156ec375b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -1631,7 +1631,7 @@ impl Evaluator<'_> {
             Variants::Empty => unreachable!(),
             Variants::Single { index } => {
                 let r =
-                    self.const_eval_discriminant(self.db.enum_variants(e).variants[index.0].0)?;
+                    self.const_eval_discriminant(e.enum_variants(self.db).variants[index.0].0)?;
                 Ok(r)
             }
             Variants::Multiple { tag, tag_encoding, variants, .. } => {
@@ -1656,7 +1656,7 @@ impl Evaluator<'_> {
                             .unwrap_or(*untagged_variant)
                             .0;
                         let result =
-                            self.const_eval_discriminant(self.db.enum_variants(e).variants[idx].0)?;
+                            self.const_eval_discriminant(e.enum_variants(self.db).variants[idx].0)?;
                         Ok(result)
                     }
                 }
@@ -2775,8 +2775,8 @@ impl Evaluator<'_> {
                 let name = format!(
                     "{}::{}",
                     self.db.enum_signature(loc.parent).name.display(db, edition),
-                    self.db
-                        .enum_variants(loc.parent)
+                    loc.parent
+                        .enum_variants(self.db)
                         .variant_name_by_id(variant)
                         .unwrap()
                         .display(db, edition),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index ef1f215500c..71e038b92f0 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -1925,8 +1925,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
                 let name = format!(
                     "{}::{}",
                     self.db.enum_signature(loc.parent).name.display(db, edition),
-                    self.db
-                        .enum_variants(loc.parent)
+                    loc.parent
+                        .enum_variants(self.db)
                         .variant_name_by_id(variant)
                         .unwrap()
                         .display(db, edition),
@@ -2155,7 +2155,7 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi
             .to_string(),
         DefWithBodyId::VariantId(it) => {
             let loc = it.lookup(db);
-            db.enum_variants(loc.parent).variants[loc.index as usize]
+            loc.parent.enum_variants(db).variants[loc.index as usize]
                 .1
                 .display(db, edition)
                 .to_string()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
index 91dc2627d18..8764e48b538 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
@@ -68,7 +68,8 @@ impl MirBody {
                     this,
                     "enum {}::{} = ",
                     db.enum_signature(loc.parent).name.display(db, edition),
-                    db.enum_variants(loc.parent)
+                    loc.parent
+                        .enum_variants(db)
                         .variant_name_by_id(id)
                         .unwrap()
                         .display(db, edition),
@@ -335,7 +336,7 @@ impl<'a> MirPrettyCtx<'a> {
                             w!(
                                 this,
                                 " as {}).{}",
-                                this.db.enum_variants(loc.parent).variants[loc.index as usize]
+                                loc.parent.enum_variants(this.db).variants[loc.index as usize]
                                     .1
                                     .display(this.db, this.display_target.edition),
                                 name.display(this.db, this.display_target.edition)
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs
index 48af7b2e32a..f2812570ed5 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests.rs
@@ -479,7 +479,7 @@ pub(crate) fn visit_module(
                     visit_body(db, &body, cb);
                 }
                 ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => {
-                    db.enum_variants(it).variants.iter().for_each(|&(it, _, _)| {
+                    it.enum_variants(db).variants.iter().for_each(|&(it, _, _)| {
                         let body = db.body(it.into());
                         cb(it.into());
                         visit_body(db, &body, cb);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
index f5911e2161d..f53409af2b3 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
@@ -109,7 +109,7 @@ impl DebugContext<'_> {
             CallableDefId::StructId(s) => self.0.struct_signature(s).name.clone(),
             CallableDefId::EnumVariantId(e) => {
                 let loc = e.lookup(self.0);
-                self.0.enum_variants(loc.parent).variants[loc.index as usize].1.clone()
+                loc.parent.enum_variants(self.0).variants[loc.index as usize].1.clone()
             }
         };
         match def {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
index f797e60b05e..867c7ea0878 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -355,7 +355,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
     let (var_id, var_layout) = match &layout.variants {
         hir_def::layout::Variants::Empty => unreachable!(),
         hir_def::layout::Variants::Single { index } => {
-            (db.enum_variants(e).variants[index.0].0, layout)
+            (e.enum_variants(db).variants[index.0].0, layout)
         }
         hir_def::layout::Variants::Multiple { tag, tag_encoding, variants, .. } => {
             let size = tag.size(target_data_layout).bytes_usize();
@@ -365,7 +365,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
                 TagEncoding::Direct => {
                     let (var_idx, layout) =
                         variants.iter_enumerated().find_map(|(var_idx, v)| {
-                            let def = db.enum_variants(e).variants[var_idx.0].0;
+                            let def = e.enum_variants(db).variants[var_idx.0].0;
                             (db.const_eval_discriminant(def) == Ok(tag)).then_some((def, v))
                         })?;
                     (var_idx, layout)
@@ -378,7 +378,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
                         .filter(|x| x != untagged_variant)
                         .nth(candidate_tag)
                         .unwrap_or(*untagged_variant);
-                    (db.enum_variants(e).variants[variant.0].0, &variants[variant])
+                    (e.enum_variants(db).variants[variant.0].0, &variants[variant])
                 }
             }
         }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
index 62478d4fd86..08a215fecf6 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
@@ -213,7 +213,7 @@ impl Context<'_> {
                     AdtId::StructId(s) => add_constraints_from_variant(VariantId::StructId(s)),
                     AdtId::UnionId(u) => add_constraints_from_variant(VariantId::UnionId(u)),
                     AdtId::EnumId(e) => {
-                        db.enum_variants(e).variants.iter().for_each(|&(variant, _, _)| {
+                        e.enum_variants(db).variants.iter().for_each(|&(variant, _, _)| {
                             add_constraints_from_variant(VariantId::EnumVariantId(variant))
                         });
                     }
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index c746b88c5b1..597da0a3cbd 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -688,7 +688,7 @@ impl Module {
                         Adt::Enum(e) => {
                             let source_map = db.enum_signature_with_source_map(e.id).1;
                             expr_store_diagnostics(db, acc, &source_map);
-                            let (variants, diagnostics) = db.enum_variants_with_diagnostics(e.id);
+                            let (variants, diagnostics) = e.id.enum_variants_with_diagnostics(db);
                             let file = e.id.lookup(db).id.file_id;
                             let ast_id_map = db.ast_id_map(file);
                             if let Some(diagnostics) = &diagnostics {
@@ -1504,11 +1504,11 @@ impl Enum {
     }
 
     pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> {
-        db.enum_variants(self.id).variants.iter().map(|&(id, _, _)| Variant { id }).collect()
+        self.id.enum_variants(db).variants.iter().map(|&(id, _, _)| Variant { id }).collect()
     }
 
     pub fn num_variants(self, db: &dyn HirDatabase) -> usize {
-        db.enum_variants(self.id).variants.len()
+        self.id.enum_variants(db).variants.len()
     }
 
     pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {
@@ -1606,7 +1606,7 @@ impl Variant {
     pub fn name(self, db: &dyn HirDatabase) -> Name {
         let lookup = self.id.lookup(db);
         let enum_ = lookup.parent;
-        db.enum_variants(enum_).variants[lookup.index as usize].1.clone()
+        enum_.enum_variants(db).variants[lookup.index as usize].1.clone()
     }
 
     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
index ea44451a8ee..0d0bbe367ec 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
@@ -205,7 +205,7 @@ impl ChildBySource for EnumId {
 
         let ast_id_map = db.ast_id_map(loc.id.file_id);
 
-        db.enum_variants(*self).variants.iter().for_each(|&(variant, _, _)| {
+        self.enum_variants(db).variants.iter().for_each(|&(variant, _, _)| {
             res[keys::ENUM_VARIANT].insert(ast_id_map.get(variant.lookup(db).id.value), variant);
         });
         let (_, source_map) = db.enum_signature_with_source_map(*self);
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 09b61524d60..3273358b78e 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -829,7 +829,7 @@ impl<'db> SourceAnalyzer<'db> {
                                 handle_variants(id.into(), subst, &mut container)?
                             }
                             AdtId::EnumId(id) => {
-                                let variants = db.enum_variants(id);
+                                let variants = id.enum_variants(db);
                                 let variant = variants.variant(&field_name.as_name())?;
                                 container = Either::Left((variant, subst.clone()));
                                 (Either::Left(Variant { id: variant }), id.into(), subst.clone())