Skip to content

Commit 7929eaa

Browse files
authored
Merge pull request #916 from sbillig/enum-record
v2: enum record variant support; one-liner record def
2 parents 1d94506 + e6af581 commit 7929eaa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1117
-806
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/analyzer/src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(clippy::arc_with_non_send_sync)]
12
use crate::{
23
context::{Analysis, Constant, FunctionBody},
34
errors::{ConstEvalError, TypeError},

crates/analyzer/src/db/queries/module.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ pub fn module_used_item_map(
564564
)
565565
.value;
566566

567-
items.extend(Rc::try_unwrap(prelude_items).unwrap().into_iter());
567+
items.extend(Rc::try_unwrap(prelude_items).unwrap());
568568
}
569569

570570
Analysis::new(Rc::new(items), diagnostics.into())

crates/codegen/src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(clippy::arc_with_non_send_sync)]
12
use std::rc::Rc;
23

34
use fe_abi::{contract::AbiContract, event::AbiEvent, function::AbiFunction, types::AbiType};

crates/codegen/src/yul/runtime/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ impl RuntimeProvider for DefaultRuntimeProvider {
383383
}
384384

385385
let deref_ty = ptr_ty.deref(db.upcast());
386-
let args = std::iter::once(ptr).chain(args.into_iter()).collect();
386+
let args = std::iter::once(ptr).chain(args).collect();
387387
let legalized_ty = db.codegen_legalized_type(ptr_ty);
388388
if deref_ty.is_enum(db.upcast()) {
389389
let mut name = format!("enum_init_{}", ptr_ty.0);

crates/common/src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(clippy::arc_with_non_send_sync)]
12
use crate::files::{File, SourceFileId, Utf8Path};
23
use codespan_reporting as cs;
34
use salsa;

crates/hir/src/hir_def/item.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ use crate::{
2323

2424
use super::{
2525
scope_graph::{ScopeGraph, ScopeId},
26-
AttrListId, Body, FuncParamListId, GenericParamListId, IdentId, IngotId, Partial, TypeId,
27-
UseAlias, WhereClauseId,
26+
AttrListId, Body, FuncParamListId, GenericParamListId, IdentId, IngotId, Partial, TupleTypeId,
27+
TypeId, UseAlias, WhereClauseId,
2828
};
2929

3030
#[derive(
@@ -687,7 +687,14 @@ pub struct VariantDefListId {
687687
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
688688
pub struct VariantDef {
689689
pub name: Partial<IdentId>,
690-
pub ty: Option<TypeId>,
690+
pub kind: VariantKind,
691+
}
692+
693+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
694+
pub enum VariantKind {
695+
Unit,
696+
Tuple(TupleTypeId),
697+
Record(FieldDefListId),
691698
}
692699

693700
#[salsa::interned]

crates/hir/src/hir_def/scope_graph.rs

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010

1111
use super::{
1212
scope_graph_viz::ScopeGraphFormatter, Body, Enum, ExprId, Func, FuncParamLabel, IdentId,
13-
IngotId, ItemKind, TopLevelMod, Use, Visibility,
13+
IngotId, ItemKind, TopLevelMod, Use, VariantKind, Visibility,
1414
};
1515

1616
/// Represents a scope relation graph in a top-level module.
@@ -82,7 +82,7 @@ pub enum ScopeId {
8282
FuncParam(ItemKind, usize),
8383

8484
/// A field scope.
85-
Field(ItemKind, usize),
85+
Field(FieldParent, usize),
8686

8787
/// A variant scope.
8888
Variant(ItemKind, usize),
@@ -97,7 +97,8 @@ impl ScopeId {
9797
ScopeId::Item(item) => item.top_mod(db),
9898
ScopeId::GenericParam(item, _) => item.top_mod(db),
9999
ScopeId::FuncParam(item, _) => item.top_mod(db),
100-
ScopeId::Field(item, _) => item.top_mod(db),
100+
ScopeId::Field(FieldParent::Item(item), _) => item.top_mod(db),
101+
ScopeId::Field(FieldParent::Variant(item, _), _) => item.top_mod(db),
101102
ScopeId::Variant(item, _) => item.top_mod(db),
102103
ScopeId::Block(body, _) => body.top_mod(db),
103104
}
@@ -122,7 +123,8 @@ impl ScopeId {
122123
ScopeId::Item(item) => item,
123124
ScopeId::GenericParam(item, _) => item,
124125
ScopeId::FuncParam(item, _) => item,
125-
ScopeId::Field(item, _) => item,
126+
ScopeId::Field(FieldParent::Item(item), _) => item,
127+
ScopeId::Field(FieldParent::Variant(item, _), _) => item,
126128
ScopeId::Variant(item, _) => item,
127129
ScopeId::Block(body, _) => body.into(),
128130
}
@@ -261,11 +263,18 @@ impl ScopeId {
261263
enum_.variants(db).data(db)[idx].name.to_opt()
262264
}
263265

264-
ScopeId::Field(parent, idx) => match parent {
266+
ScopeId::Field(FieldParent::Item(parent), idx) => match parent {
265267
ItemKind::Struct(s) => s.fields(db).data(db)[idx].name.to_opt(),
266268
ItemKind::Contract(c) => c.fields(db).data(db)[idx].name.to_opt(),
267269
_ => unreachable!(),
268270
},
271+
ScopeId::Field(FieldParent::Variant(parent, vidx), fidx) => {
272+
let enum_: Enum = parent.try_into().unwrap();
273+
match enum_.variants(db).data(db)[vidx].kind {
274+
VariantKind::Record(fields) => fields.data(db)[fidx].name.to_opt(),
275+
_ => unreachable!(),
276+
}
277+
}
269278

270279
ScopeId::FuncParam(parent, idx) => {
271280
let func: Func = parent.try_into().unwrap();
@@ -297,11 +306,24 @@ impl ScopeId {
297306
Some(enum_.lazy_span().variants().variant(idx).name().into())
298307
}
299308

300-
ScopeId::Field(parent, idx) => match parent {
309+
ScopeId::Field(FieldParent::Item(parent), idx) => match parent {
301310
ItemKind::Struct(s) => Some(s.lazy_span().fields().field(idx).name().into()),
302311
ItemKind::Contract(c) => Some(c.lazy_span().fields().field(idx).name().into()),
303312
_ => unreachable!(),
304313
},
314+
ScopeId::Field(FieldParent::Variant(parent, vidx), fidx) => {
315+
let enum_: Enum = parent.try_into().unwrap();
316+
Some(
317+
enum_
318+
.lazy_span()
319+
.variants()
320+
.variant(vidx)
321+
.fields()
322+
.field(fidx)
323+
.name()
324+
.into(),
325+
)
326+
}
305327

306328
ScopeId::FuncParam(parent, idx) => {
307329
let func: Func = parent.try_into().unwrap();
@@ -353,6 +375,12 @@ impl ScopeId {
353375
}
354376
}
355377

378+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
379+
pub enum FieldParent {
380+
Item(ItemKind),
381+
Variant(ItemKind, usize),
382+
}
383+
356384
struct ScopeGraphItemIterDfs<'a> {
357385
db: &'a dyn HirDb,
358386
graph: &'a ScopeGraph,
@@ -542,7 +570,13 @@ pub struct AnonEdge();
542570
#[cfg(test)]
543571
mod tests {
544572

545-
use crate::{hir_def::ItemKind, test_db::TestDb};
573+
use crate::{
574+
hir_def::{
575+
scope_graph::{FieldParent, ScopeId},
576+
ItemKind,
577+
},
578+
test_db::TestDb,
579+
};
546580

547581
#[test]
548582
fn item_tree() {
@@ -555,7 +589,7 @@ mod tests {
555589
fn baz()
556590
}
557591
}
558-
592+
559593
enum MyEnum {}
560594
561595
mod baz {
@@ -581,4 +615,30 @@ mod tests {
581615
}
582616
}
583617
}
618+
619+
#[test]
620+
fn enum_record_fields() {
621+
let mut db = TestDb::default();
622+
623+
let text = r#"
624+
enum Foo {
625+
X { a: i8, b: i8 },
626+
}
627+
"#;
628+
629+
let file = db.standalone_file(text);
630+
let scope_graph = db.parse_source(file);
631+
let root = scope_graph.top_mod.scope();
632+
let enum_ = scope_graph.children(root).next().unwrap();
633+
assert!(matches!(enum_.item(), ItemKind::Enum(_)));
634+
635+
let variant = scope_graph.children(enum_).next().unwrap();
636+
assert!(matches!(variant, ScopeId::Variant(_, _)));
637+
638+
let field = scope_graph.children(variant).next().unwrap();
639+
assert!(matches!(
640+
field,
641+
ScopeId::Field(FieldParent::Variant(_, _), _)
642+
));
643+
}
584644
}

crates/hir/src/hir_def/types.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub enum TypeKind {
1313
Path(Partial<PathId>, GenericArgListId),
1414
SelfType,
1515
/// The `Vec` contains the types of the tuple elements.
16-
Tuple(Vec<Partial<TypeId>>),
16+
Tuple(TupleTypeId),
1717
/// The first `TypeId` is the element type, the second `Body` is the length.
1818
Array(Partial<TypeId>, Partial<Body>),
1919
}
@@ -23,3 +23,9 @@ pub struct TraitRef {
2323
pub path: Partial<PathId>,
2424
pub generic_args: GenericArgListId,
2525
}
26+
27+
#[salsa::interned]
28+
pub struct TupleTypeId {
29+
#[return_ref]
30+
pub data: Vec<Partial<TypeId>>,
31+
}

crates/hir/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub struct Jar(
4747
hir_def::VariantDefListId,
4848
hir_def::ImplItemListId,
4949
hir_def::TypeId,
50+
hir_def::TupleTypeId,
5051
hir_def::UsePathId,
5152
/// Accumulated diagnostics.
5253
ParseErrorAccumulator,

0 commit comments

Comments
 (0)