Skip to content

Commit 15ce6cf

Browse files
authored
Merge pull request #175 from shua/uniq
track adt variant and field names do not conflict
2 parents 8732bc3 + 61cf9b5 commit 15ce6cf

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

crates/formality-check/src/adts.rs

Lines changed: 17 additions & 2 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;
@@ -6,6 +9,20 @@ impl super::Check<'_> {
69
pub(super) fn check_adt(&self, adt: &Adt) -> Fallible<()> {
710
let Adt { id: _, binder } = adt;
811

12+
// names is used to check that there are no name conflicts
13+
let mut names = HashSet::new();
14+
for Variant { name, fields } in &adt.binder.peek().variants {
15+
if !names.insert((name, None)) {
16+
bail!("variant \"{name:?}\" defined multiple times");
17+
}
18+
let vname = name;
19+
for Field { name, ty: _ } in fields {
20+
if !names.insert((vname, Some(name))) {
21+
bail!("field \"{name:?}\" of variant \"{vname:?}\" defined multiple times");
22+
}
23+
}
24+
}
25+
926
let mut env = Env::default();
1027

1128
let AdtBoundData {
@@ -15,8 +32,6 @@ impl super::Check<'_> {
1532

1633
self.prove_where_clauses_well_formed(&env, &where_clauses, &where_clauses)?;
1734

18-
// FIXME: check names are unique or integers from 0..n
19-
2035
for Variant { name: _, fields } in &variants {
2136
for Field { name: _, ty } in fields {
2237
self.prove_goal(&env, &where_clauses, ty.well_formed())?;

src/test/mod.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,42 @@ fn basic_where_clauses_fail() {
135135
)
136136
}
137137

138+
#[test]
139+
fn basic_adt_variant_dup() {
140+
crate::assert_err!(
141+
[
142+
crate Foo {
143+
enum Bar {
144+
Baz{},
145+
Baz{},
146+
}
147+
}
148+
]
149+
150+
[ r#"variant "Baz" defined multiple times"#, ]
151+
152+
expect_test::expect![[r#"variant "Baz" defined multiple times"#]]
153+
)
154+
}
155+
156+
#[test]
157+
fn basic_adt_field_dup() {
158+
crate::assert_err!(
159+
[
160+
crate Foo {
161+
struct Bar {
162+
baz: (),
163+
baz: (),
164+
}
165+
}
166+
]
167+
168+
[ r#"field "baz" of variant "struct" defined multiple times"#, ]
169+
170+
expect_test::expect![[r#"field "baz" of variant "struct" defined multiple times"#]]
171+
)
172+
}
173+
138174
#[test]
139175
fn trait_items_with_duplicate_fn_names() {
140176
crate::assert_err!(

0 commit comments

Comments
 (0)