Skip to content

Commit f183c89

Browse files
committed
track adt variant and field names do not conflict
The intent of this change is to add a check for adts that enum variant names are unique, and that struct and enum field names are unique (within a given enum variant).
1 parent 3966e06 commit f183c89

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

crates/formality-check/src/adts.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use std::collections::HashSet;
2+
3+
use anyhow::bail;
14
use formality_prove::Env;
25
use formality_rust::grammar::{Adt, AdtBoundData, Field, Variant};
36
use formality_types::grammar::Fallible;
@@ -15,10 +18,17 @@ impl super::Check<'_> {
1518

1619
self.prove_where_clauses_well_formed(&env, &where_clauses, &where_clauses)?;
1720

18-
// FIXME: check names are unique or integers from 0..n
19-
20-
for Variant { name: _, fields } in &variants {
21-
for Field { name: _, ty } in fields {
21+
// names is used to check that there are no name conflicts
22+
let mut names = HashSet::new();
23+
for Variant { name, fields } in &variants {
24+
if !names.insert((name, None)) {
25+
bail!("variant \"{name:?}\" defined multiple times");
26+
}
27+
let vname = name;
28+
for Field { name, ty } in fields {
29+
if !names.insert((vname, Some(name))) {
30+
bail!("field \"{name:?}\" of variant \"{vname:?}\" defined multiple times");
31+
}
2232
self.prove_goal(&env, &where_clauses, ty.well_formed())?;
2333
}
2434
}

src/test/mod.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,39 @@ fn basic_where_clauses_fail() {
133133
expression evaluated to an empty collection: `decls.trait_invariants()`"#]]
134134
)
135135
}
136+
137+
#[test]
138+
fn basic_adt_variant_dup() {
139+
crate::assert_err!(
140+
[
141+
crate Foo {
142+
enum Bar {
143+
Baz{},
144+
Baz{},
145+
}
146+
}
147+
]
148+
149+
[ /* TODO */ ]
150+
151+
expect_test::expect![[r#"variant "Baz" defined multiple times"#]]
152+
)
153+
}
154+
155+
#[test]
156+
fn basic_adt_field_dup() {
157+
crate::assert_err!(
158+
[
159+
crate Foo {
160+
struct Bar {
161+
baz: (),
162+
baz: (),
163+
}
164+
}
165+
]
166+
167+
[ /* TODO */ ]
168+
169+
expect_test::expect![[r#"field "baz" of variant "struct" defined multiple times"#]]
170+
)
171+
}

0 commit comments

Comments
 (0)