Skip to content

Commit 8e8d997

Browse files
committed
Split enum variants out of enum_data query
1 parent dff1896 commit 8e8d997

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,
@@ -203,28 +207,16 @@ impl StructData {
203207
}
204208
}
205209

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

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

@@ -233,13 +225,6 @@ impl EnumData {
233225
Some(id)
234226
}
235227

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

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

170+
#[salsa::invoke_actual(EnumVariants::enum_variants_query)]
171+
fn enum_variants(&self, e: EnumId) -> Arc<EnumVariants>;
172+
170173
#[salsa::transparent]
171174
#[salsa::invoke_actual(EnumVariantData::enum_variant_data_query)]
172175
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
@@ -801,7 +801,7 @@ pub(crate) fn adt_datum_query(
801801
}
802802
hir_def::AdtId::EnumId(id) => {
803803
let variants = db
804-
.enum_data(id)
804+
.enum_variants(id)
805805
.variants
806806
.iter()
807807
.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
@@ -309,7 +309,7 @@ pub(crate) fn const_eval_discriminant_variant(
309309
let value = match prev_idx {
310310
Some(prev_idx) => {
311311
1 + db.const_eval_discriminant(
312-
db.enum_data(loc.parent).variants[prev_idx as usize].0,
312+
db.enum_variants(loc.parent).variants[prev_idx as usize].0,
313313
)?
314314
}
315315
_ => 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
@@ -642,7 +642,7 @@ fn missing_match_arms<'p>(
642642
}
643643

644644
let non_empty_enum = match scrut_ty.as_adt() {
645-
Some((AdtId::EnumId(e), _)) => !cx.db.enum_data(e).variants.is_empty(),
645+
Some((AdtId::EnumId(e), _)) => !cx.db.enum_variants(e).variants.is_empty(),
646646
_ => false,
647647
};
648648
let display_target = DisplayTarget::from_crate(cx.db, krate);

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
@@ -1587,7 +1587,7 @@ impl<'a> InferenceContext<'a> {
15871587
// If we can resolve to an enum variant, it takes priority over associated type
15881588
// of the same name.
15891589
if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
1590-
let enum_data = self.db.enum_data(id);
1590+
let enum_data = self.db.enum_variants(id);
15911591
if let Some(variant) = enum_data.variant(current_segment.name) {
15921592
return if remaining_segments.len() == 1 {
15931593
(ty, Some(variant.into()))
@@ -1701,7 +1701,7 @@ impl<'a> InferenceContext<'a> {
17011701
let segment = path.segments().last().unwrap();
17021702
// this could be an enum variant or associated type
17031703
if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
1704-
let enum_data = self.db.enum_data(enum_id);
1704+
let enum_data = self.db.enum_variants(enum_id);
17051705
if let Some(variant) = enum_data.variant(segment) {
17061706
return (ty, Some(variant.into()));
17071707
}

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
@@ -54,13 +54,13 @@ pub fn layout_of_adt_query(
5454
(r, data.repr.unwrap_or_default())
5555
}
5656
AdtId::EnumId(e) => {
57-
let data = db.enum_data(e);
58-
let r = data
57+
let variants = db.enum_variants(e);
58+
let r = variants
5959
.variants
6060
.iter()
6161
.map(|&(v, _)| handle_variant(v.into(), &db.enum_variant_data(v).variant_data))
6262
.collect::<Result<SmallVec<_>, _>>()?;
63-
(r, data.repr.unwrap_or_default())
63+
(r, db.enum_data(e).repr.unwrap_or_default())
6464
}
6565
};
6666
let variants = variants
@@ -80,7 +80,7 @@ pub fn layout_of_adt_query(
8080
|min, max| repr_discr(dl, &repr, min, max).unwrap_or((Integer::I8, false)),
8181
variants.iter_enumerated().filter_map(|(id, _)| {
8282
let AdtId::EnumId(e) = def else { return None };
83-
let d = db.const_eval_discriminant(db.enum_data(e).variants[id.0].0).ok()?;
83+
let d = db.const_eval_discriminant(db.enum_variants(e).variants[id.0].0).ok()?;
8484
Some((id, d))
8585
}),
8686
// 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
@@ -1641,7 +1641,8 @@ impl Evaluator<'_> {
16411641
match &layout.variants {
16421642
Variants::Empty => unreachable!(),
16431643
Variants::Single { index } => {
1644-
let r = self.const_eval_discriminant(self.db.enum_data(e).variants[index.0].0)?;
1644+
let r =
1645+
self.const_eval_discriminant(self.db.enum_variants(e).variants[index.0].0)?;
16451646
Ok(r)
16461647
}
16471648
Variants::Multiple { tag, tag_encoding, variants, .. } => {
@@ -1666,7 +1667,7 @@ impl Evaluator<'_> {
16661667
.unwrap_or(*untagged_variant)
16671668
.0;
16681669
let result =
1669-
self.const_eval_discriminant(self.db.enum_data(e).variants[idx].0)?;
1670+
self.const_eval_discriminant(self.db.enum_variants(e).variants[idx].0)?;
16701671
Ok(result)
16711672
}
16721673
}

crates/hir-ty/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ pub(crate) fn visit_module(
481481
visit_body(db, &body, cb);
482482
}
483483
ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => {
484-
db.enum_data(it).variants.iter().for_each(|&(it, _)| {
484+
db.enum_variants(it).variants.iter().for_each(|&(it, _)| {
485485
let body = db.body(it.into());
486486
cb(it.into());
487487
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
@@ -369,7 +369,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
369369
let (var_id, var_layout) = match &layout.variants {
370370
hir_def::layout::Variants::Empty => unreachable!(),
371371
hir_def::layout::Variants::Single { index } => {
372-
(db.enum_data(e).variants[index.0].0, layout)
372+
(db.enum_variants(e).variants[index.0].0, layout)
373373
}
374374
hir_def::layout::Variants::Multiple { tag, tag_encoding, variants, .. } => {
375375
let size = tag.size(target_data_layout).bytes_usize();
@@ -379,7 +379,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
379379
TagEncoding::Direct => {
380380
let (var_idx, layout) =
381381
variants.iter_enumerated().find_map(|(var_idx, v)| {
382-
let def = db.enum_data(e).variants[var_idx.0].0;
382+
let def = db.enum_variants(e).variants[var_idx.0].0;
383383
(db.const_eval_discriminant(def) == Ok(tag)).then_some((def, v))
384384
})?;
385385
(var_idx, layout)
@@ -392,7 +392,7 @@ pub(crate) fn detect_variant_from_bytes<'a>(
392392
.filter(|x| x != untagged_variant)
393393
.nth(candidate_tag)
394394
.unwrap_or(*untagged_variant);
395-
(db.enum_data(e).variants[variant.0].0, &variants[variant])
395+
(db.enum_variants(e).variants[variant.0].0, &variants[variant])
396396
}
397397
}
398398
}

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
@@ -1519,7 +1519,11 @@ impl Enum {
15191519
}
15201520

15211521
pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> {
1522-
db.enum_data(self.id).variants.iter().map(|&(id, _)| Variant { id }).collect()
1522+
db.enum_variants(self.id).variants.iter().map(|&(id, _)| Variant { id }).collect()
1523+
}
1524+
1525+
pub fn num_variants(self, db: &dyn HirDatabase) -> usize {
1526+
db.enum_variants(self.id).variants.len()
15231527
}
15241528

15251529
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)