Skip to content

Commit b9dbce6

Browse files
authored
Merge pull request #184 from obeis/duplicate-items
Add check for duplicate items in crate
2 parents b8306ab + 390b171 commit b9dbce6

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

crates/formality-check/src/lib.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::{collections::VecDeque, fmt::Debug};
44

55
use anyhow::bail;
6+
use formality_core::Set;
67
use formality_prove::{is_definitely_not_proveable, Decls, Env};
78
use formality_rust::{
89
grammar::{Crate, CrateItem, Program, Test, TestBoundData},
@@ -71,7 +72,38 @@ impl Check<'_> {
7172
}
7273

7374
fn check_for_duplicate_items(&self) -> Fallible<()> {
74-
// FIXME: check for items with duplicate names, respecting the various Rust rules about namespaces
75+
let Program { crates } = &self.program;
76+
for c in crates.iter() {
77+
let mut items = Set::new();
78+
let mut traits = Set::new();
79+
let mut functions = Set::new();
80+
for item in c.items.iter() {
81+
match item {
82+
CrateItem::Struct(s) => {
83+
if !items.insert(&s.id) {
84+
bail!("the item name `{:?}` is defined multiple times", s.id);
85+
}
86+
}
87+
CrateItem::Enum(e) => {
88+
if !items.insert(&e.id) {
89+
bail!("the item name `{:?}` is defined multiple times", e.id);
90+
}
91+
}
92+
CrateItem::Trait(t) => {
93+
if !traits.insert(&t.id) {
94+
bail!("the trait name `{:?}` is defined multiple times", t.id);
95+
}
96+
}
97+
CrateItem::Fn(f) => {
98+
if !functions.insert(&f.id) {
99+
bail!("the function name `{:?}` is defined multiple times", f.id);
100+
}
101+
}
102+
CrateItem::TraitImpl(_) | CrateItem::NegTraitImpl(_) | CrateItem::Test(_) => {}
103+
}
104+
}
105+
}
106+
75107
Ok(())
76108
}
77109

src/test/mod.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,61 @@ fn trait_items_with_duplicate_associated_type_names() {
215215
the associated type name `Assoc` is defined multiple times"#]]
216216
);
217217
}
218+
219+
#[test]
220+
fn crate_with_duplicate_item_names() {
221+
crate::assert_err!(
222+
[
223+
crate core {
224+
struct A {}
225+
226+
enum A {}
227+
}
228+
]
229+
230+
["the item name `A` is defined multiple times",]
231+
232+
expect_test::expect![[r#"the item name `A` is defined multiple times"#]]
233+
);
234+
235+
crate::assert_err!(
236+
[
237+
crate core {
238+
trait a {}
239+
240+
trait a {}
241+
}
242+
]
243+
244+
["the trait name `a` is defined multiple times",]
245+
246+
expect_test::expect![[r#"the trait name `a` is defined multiple times"#]]
247+
);
248+
249+
crate::assert_err!(
250+
[
251+
crate core {
252+
fn a() -> () { trusted }
253+
254+
fn a() -> () { trusted }
255+
}
256+
]
257+
258+
["the function name `a` is defined multiple times",]
259+
260+
expect_test::expect![[r#"the function name `a` is defined multiple times"#]]
261+
);
262+
263+
crate::assert_ok!(
264+
//@check-pass
265+
[
266+
crate core {
267+
trait a {}
268+
269+
fn a() -> () { trusted }
270+
}
271+
]
272+
273+
expect_test::expect!["()"]
274+
);
275+
}

0 commit comments

Comments
 (0)