Skip to content

Commit 4e741e3

Browse files
committed
Split enum variants out of enum_data query
1 parent b2816be commit 4e741e3

File tree

21 files changed

+74
-52
lines changed

21 files changed

+74
-52
lines changed

crates/hir-def/src/data/adt.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,16 @@ bitflags! {
5656
#[derive(Debug, Clone, PartialEq, Eq)]
5757
pub struct EnumData {
5858
pub name: Name,
59-
pub variants: Box<[(EnumVariantId, Name)]>,
6059
pub repr: Option<ReprOptions>,
6160
pub visibility: RawVisibility,
6261
pub rustc_has_incoherent_inherent_impls: bool,
6362
}
6463

64+
#[derive(Debug, Clone, PartialEq, Eq)]
65+
pub struct EnumVariants {
66+
pub variants: Box<[(EnumVariantId, Name)]>,
67+
}
68+
6569
#[derive(Debug, Clone, PartialEq, Eq)]
6670
pub struct EnumVariantData {
6771
pub name: Name,
@@ -202,28 +206,16 @@ impl StructData {
202206
}
203207
}
204208

205-
impl EnumData {
206-
pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
209+
impl EnumVariants {
210+
pub(crate) fn enum_variants_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumVariants> {
207211
let loc = e.lookup(db);
208-
let krate = loc.container.krate;
209212
let item_tree = loc.id.item_tree(db);
210-
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
211-
let rustc_has_incoherent_inherent_impls = item_tree
212-
.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into())
213-
.by_key(&sym::rustc_has_incoherent_inherent_impls)
214-
.exists();
215-
216-
let enum_ = &item_tree[loc.id.value];
217213

218-
Arc::new(EnumData {
219-
name: enum_.name.clone(),
214+
Arc::new(EnumVariants {
220215
variants: loc.container.def_map(db).enum_definitions[&e]
221216
.iter()
222217
.map(|&id| (id, item_tree[id.lookup(db).id.value].name.clone()))
223218
.collect(),
224-
repr,
225-
visibility: item_tree[enum_.visibility].clone(),
226-
rustc_has_incoherent_inherent_impls,
227219
})
228220
}
229221

@@ -232,13 +224,6 @@ impl EnumData {
232224
Some(id)
233225
}
234226

235-
pub fn variant_body_type(&self) -> IntegerType {
236-
match self.repr {
237-
Some(ReprOptions { int: Some(builtin), .. }) => builtin,
238-
_ => IntegerType::Pointer(true),
239-
}
240-
}
241-
242227
// [Adopted from rustc](https://github.com/rust-lang/rust/blob/bd53aa3bf7a24a70d763182303bd75e5fc51a9af/compiler/rustc_middle/src/ty/adt.rs#L446-L448)
243228
pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool {
244229
self.variants.iter().all(|(v, _)| {
@@ -261,6 +246,35 @@ impl EnumData {
261246
}
262247
}
263248

249+
impl EnumData {
250+
pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
251+
let loc = e.lookup(db);
252+
let krate = loc.container.krate;
253+
let item_tree = loc.id.item_tree(db);
254+
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
255+
let rustc_has_incoherent_inherent_impls = item_tree
256+
.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into())
257+
.by_key(&sym::rustc_has_incoherent_inherent_impls)
258+
.exists();
259+
260+
let enum_ = &item_tree[loc.id.value];
261+
262+
Arc::new(EnumData {
263+
name: enum_.name.clone(),
264+
repr,
265+
visibility: item_tree[enum_.visibility].clone(),
266+
rustc_has_incoherent_inherent_impls,
267+
})
268+
}
269+
270+
pub fn variant_body_type(&self) -> IntegerType {
271+
match self.repr {
272+
Some(ReprOptions { int: Some(builtin), .. }) => builtin,
273+
_ => IntegerType::Pointer(true),
274+
}
275+
}
276+
}
277+
264278
impl EnumVariantData {
265279
#[inline]
266280
pub(crate) fn enum_variant_data_query(

crates/hir-def/src/db.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use triomphe::Arc;
1111
use crate::{
1212
attr::{Attrs, AttrsWithOwner},
1313
data::{
14-
adt::{EnumData, EnumVariantData, StructData, VariantData},
14+
adt::{EnumData, EnumVariantData, EnumVariants, StructData, VariantData},
1515
ConstData, ExternCrateDeclData, FunctionData, ImplData, Macro2Data, MacroRulesData,
1616
ProcMacroData, StaticData, TraitAliasData, TraitData, TypeAliasData,
1717
},
@@ -138,6 +138,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
138138
#[ra_salsa::invoke(EnumData::enum_data_query)]
139139
fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
140140

141+
#[ra_salsa::invoke(EnumVariants::enum_variants_query)]
142+
fn enum_variants(&self, e: EnumId) -> Arc<EnumVariants>;
143+
141144
#[ra_salsa::transparent]
142145
#[ra_salsa::invoke(EnumVariantData::enum_variant_data_query)]
143146
fn enum_variant_data(&self, id: EnumVariantId) -> Arc<EnumVariantData>;

crates/hir-ty/src/chalk_db.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ pub(crate) fn adt_datum_query(
793793
}
794794
hir_def::AdtId::EnumId(id) => {
795795
let variants = db
796-
.enum_data(id)
796+
.enum_variants(id)
797797
.variants
798798
.iter()
799799
.map(|&(variant_id, _)| variant_id_to_fields(variant_id.into()))

crates/hir-ty/src/consteval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ pub(crate) fn const_eval_discriminant_variant(
298298
let value = match prev_idx {
299299
Some(prev_idx) => {
300300
1 + db.const_eval_discriminant(
301-
db.enum_data(loc.parent).variants[prev_idx as usize].0,
301+
db.enum_variants(loc.parent).variants[prev_idx as usize].0,
302302
)?
303303
}
304304
_ => 0,

crates/hir-ty/src/diagnostics/decl_check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ impl<'a> DeclValidator<'a> {
394394

395395
/// Check incorrect names for enum variants.
396396
fn validate_enum_variants(&mut self, enum_id: EnumId) {
397-
let data = self.db.enum_data(enum_id);
397+
let data = self.db.enum_variants(enum_id);
398398

399399
for (variant_id, _) in data.variants.iter() {
400400
self.validate_enum_variant_fields(*variant_id);

crates/hir-ty/src/diagnostics/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ fn missing_match_arms<'p>(
644644

645645
let edition = cx.db.crate_graph()[krate].edition;
646646
let non_empty_enum = match scrut_ty.as_adt() {
647-
Some((AdtId::EnumId(e), _)) => !cx.db.enum_data(e).variants.is_empty(),
647+
Some((AdtId::EnumId(e), _)) => !cx.db.enum_variants(e).variants.is_empty(),
648648
_ => false,
649649
};
650650
if arms_is_empty && !non_empty_enum {

crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ impl EnumVariantContiguousIndex {
4949
}
5050

5151
fn to_enum_variant_id(self, db: &dyn HirDatabase, eid: EnumId) -> EnumVariantId {
52-
db.enum_data(eid).variants[self.0].0
52+
db.enum_variants(eid).variants[self.0].0
5353
}
5454
}
5555

@@ -449,7 +449,7 @@ impl PatCx for MatchCheckCtx<'_> {
449449
TyKind::Scalar(Scalar::Int(..) | Scalar::Uint(..)) => unhandled(),
450450
TyKind::Array(..) | TyKind::Slice(..) => unhandled(),
451451
&TyKind::Adt(AdtId(adt @ hir_def::AdtId::EnumId(enum_id)), ref subst) => {
452-
let enum_data = cx.db.enum_data(enum_id);
452+
let enum_data = cx.db.enum_variants(enum_id);
453453
let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive(adt);
454454

455455
if enum_data.variants.is_empty() && !is_declared_nonexhaustive {

crates/hir-ty/src/drop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironm
7272
// Unions cannot have fields with destructors.
7373
AdtId::UnionId(_) => DropGlue::None,
7474
AdtId::EnumId(id) => db
75-
.enum_data(id)
75+
.enum_variants(id)
7676
.variants
7777
.iter()
7878
.map(|&(variant, _)| {

crates/hir-ty/src/infer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,7 +1586,7 @@ impl<'a> InferenceContext<'a> {
15861586
// If we can resolve to an enum variant, it takes priority over associated type
15871587
// of the same name.
15881588
if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
1589-
let enum_data = self.db.enum_data(id);
1589+
let enum_data = self.db.enum_variants(id);
15901590
if let Some(variant) = enum_data.variant(current_segment.name) {
15911591
return if remaining_segments.len() == 1 {
15921592
(ty, Some(variant.into()))
@@ -1700,7 +1700,7 @@ impl<'a> InferenceContext<'a> {
17001700
let segment = path.segments().last().unwrap();
17011701
// this could be an enum variant or associated type
17021702
if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
1703-
let enum_data = self.db.enum_data(enum_id);
1703+
let enum_data = self.db.enum_variants(enum_id);
17041704
if let Some(variant) = enum_data.variant(segment) {
17051705
return (ty, Some(variant.into()));
17061706
}

crates/hir-ty/src/infer/cast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl CastTy {
4343
let (AdtId::EnumId(id), _) = t.as_adt()? else {
4444
return None;
4545
};
46-
let enum_data = table.db.enum_data(id);
46+
let enum_data = table.db.enum_variants(id);
4747
if enum_data.is_payload_free(table.db.upcast()) {
4848
Some(Self::Int(Int::CEnum))
4949
} else {

crates/hir-ty/src/infer/closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ impl InferenceContext<'_> {
963963
if let Some(variant) = self.result.variant_resolution_for_pat(p) {
964964
let adt = variant.adt_id(self.db.upcast());
965965
let is_multivariant = match adt {
966-
hir_def::AdtId::EnumId(e) => self.db.enum_data(e).variants.len() != 1,
966+
hir_def::AdtId::EnumId(e) => self.db.enum_variants(e).variants.len() != 1,
967967
_ => false,
968968
};
969969
if is_multivariant {

crates/hir-ty/src/infer/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ impl InferenceContext<'_> {
398398
Some((AdtId::EnumId(e), subst)) => (e, subst),
399399
_ => return None,
400400
};
401-
let enum_data = self.db.enum_data(enum_id);
401+
let enum_data = self.db.enum_variants(enum_id);
402402
let variant = enum_data.variant(name)?;
403403
self.write_variant_resolution(id, variant.into());
404404
Some((ValueNs::EnumVariantId(variant), subst.clone()))

crates/hir-ty/src/inhabitedness.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl UninhabitedFrom<'_> {
9898
AdtId::UnionId(_) => CONTINUE_OPAQUELY_INHABITED,
9999
AdtId::StructId(s) => self.visit_variant(s.into(), subst),
100100
AdtId::EnumId(e) => {
101-
let enum_data = self.db.enum_data(e);
101+
let enum_data = self.db.enum_variants(e);
102102

103103
for &(variant, _) in enum_data.variants.iter() {
104104
let variant_inhabitedness = self.visit_variant(variant.into(), subst);

crates/hir-ty/src/layout/adt.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ pub fn layout_of_adt_query(
5858
(r, data.repr.unwrap_or_default())
5959
}
6060
AdtId::EnumId(e) => {
61-
let data = db.enum_data(e);
62-
let r = data
61+
let variants = db.enum_variants(e);
62+
let r = variants
6363
.variants
6464
.iter()
6565
.map(|&(v, _)| handle_variant(v.into(), &db.enum_variant_data(v).variant_data))
6666
.collect::<Result<SmallVec<_>, _>>()?;
67-
(r, data.repr.unwrap_or_default())
67+
(r, db.enum_data(e).repr.unwrap_or_default())
6868
}
6969
};
7070
let variants = variants
@@ -84,7 +84,7 @@ pub fn layout_of_adt_query(
8484
|min, max| repr_discr(dl, &repr, min, max).unwrap_or((Integer::I8, false)),
8585
variants.iter_enumerated().filter_map(|(id, _)| {
8686
let AdtId::EnumId(e) = def else { return None };
87-
let d = db.const_eval_discriminant(db.enum_data(e).variants[id.0].0).ok()?;
87+
let d = db.const_eval_discriminant(db.enum_variants(e).variants[id.0].0).ok()?;
8888
Some((id, d))
8989
}),
9090
// FIXME: The current code for niche-filling relies on variant indices

crates/hir-ty/src/mir/eval.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,7 +1638,8 @@ impl Evaluator<'_> {
16381638
match &layout.variants {
16391639
Variants::Empty => unreachable!(),
16401640
Variants::Single { index } => {
1641-
let r = self.const_eval_discriminant(self.db.enum_data(e).variants[index.0].0)?;
1641+
let r =
1642+
self.const_eval_discriminant(self.db.enum_variants(e).variants[index.0].0)?;
16421643
Ok(r)
16431644
}
16441645
Variants::Multiple { tag, tag_encoding, variants, .. } => {
@@ -1663,7 +1664,7 @@ impl Evaluator<'_> {
16631664
.unwrap_or(*untagged_variant)
16641665
.0;
16651666
let result =
1666-
self.const_eval_discriminant(self.db.enum_data(e).variants[idx].0)?;
1667+
self.const_eval_discriminant(self.db.enum_variants(e).variants[idx].0)?;
16671668
Ok(result)
16681669
}
16691670
}

crates/hir-ty/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ pub(crate) fn visit_module(
476476
visit_body(db, &body, cb);
477477
}
478478
ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => {
479-
db.enum_data(it).variants.iter().for_each(|&(it, _)| {
479+
db.enum_variants(it).variants.iter().for_each(|&(it, _)| {
480480
let body = db.body(it.into());
481481
cb(it.into());
482482
visit_body(db, &body, cb);

crates/hir-ty/src/utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
372372
let (var_id, var_layout) = match &layout.variants {
373373
hir_def::layout::Variants::Empty => unreachable!(),
374374
hir_def::layout::Variants::Single { index } => {
375-
(db.enum_data(e).variants[index.0].0, layout)
375+
(db.enum_variants(e).variants[index.0].0, layout)
376376
}
377377
hir_def::layout::Variants::Multiple { tag, tag_encoding, variants, .. } => {
378378
let size = tag.size(target_data_layout).bytes_usize();
@@ -382,7 +382,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
382382
TagEncoding::Direct => {
383383
let (var_idx, layout) =
384384
variants.iter_enumerated().find_map(|(var_idx, v)| {
385-
let def = db.enum_data(e).variants[var_idx.0].0;
385+
let def = db.enum_variants(e).variants[var_idx.0].0;
386386
(db.const_eval_discriminant(def) == Ok(tag)).then_some((def, v))
387387
})?;
388388
(var_idx, layout)
@@ -395,7 +395,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
395395
.filter(|x| x != untagged_variant)
396396
.nth(candidate_tag)
397397
.unwrap_or(*untagged_variant);
398-
(db.enum_data(e).variants[variant.0].0, &variants[variant])
398+
(db.enum_variants(e).variants[variant.0].0, &variants[variant])
399399
}
400400
}
401401
}

crates/hir-ty/src/variance.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ impl Context<'_> {
206206
AdtId::StructId(s) => add_constraints_from_variant(VariantId::StructId(s)),
207207
AdtId::UnionId(u) => add_constraints_from_variant(VariantId::UnionId(u)),
208208
AdtId::EnumId(e) => {
209-
db.enum_data(e).variants.iter().for_each(|&(variant, _)| {
209+
db.enum_variants(e).variants.iter().for_each(|&(variant, _)| {
210210
add_constraints_from_variant(VariantId::EnumVariantId(variant))
211211
});
212212
}

crates/hir/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1487,7 +1487,11 @@ impl Enum {
14871487
}
14881488

14891489
pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> {
1490-
db.enum_data(self.id).variants.iter().map(|&(id, _)| Variant { id }).collect()
1490+
db.enum_variants(self.id).variants.iter().map(|&(id, _)| Variant { id }).collect()
1491+
}
1492+
1493+
pub fn num_variants(self, db: &dyn HirDatabase) -> usize {
1494+
db.enum_variants(self.id).variants.len()
14911495
}
14921496

14931497
pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {

crates/hir/src/semantics/child_by_source.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl ChildBySource for EnumId {
182182
let tree = loc.id.item_tree(db);
183183
let ast_id_map = db.ast_id_map(loc.id.file_id());
184184

185-
db.enum_data(*self).variants.iter().for_each(|&(variant, _)| {
185+
db.enum_variants(*self).variants.iter().for_each(|&(variant, _)| {
186186
res[keys::ENUM_VARIANT]
187187
.insert(ast_id_map.get(tree[variant.lookup(db).id.value].ast_id), variant);
188188
});

crates/ide-completion/src/completions/pattern.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Completes constants and paths in unqualified patterns.
22
3-
use hir::{db::DefDatabase, AssocItem, ScopeDef};
3+
use hir::{AssocItem, ScopeDef};
44
use ide_db::syntax_helpers::suggest_name;
55
use syntax::ast::Pat;
66

@@ -60,7 +60,7 @@ pub(crate) fn complete_pattern(
6060
}
6161

6262
let refutable = pattern_ctx.refutability == PatternRefutability::Refutable;
63-
let single_variant_enum = |enum_: hir::Enum| ctx.db.enum_data(enum_.into()).variants.len() == 1;
63+
let single_variant_enum = |enum_: hir::Enum| enum_.num_variants(ctx.db) == 1;
6464

6565
if let Some(hir::Adt::Enum(e)) =
6666
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())

0 commit comments

Comments
 (0)