Skip to content

Commit 5d3dbb5

Browse files
Check trait items for duplicate function names or duplicate associated type names
1 parent 915661b commit 5d3dbb5

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

crates/formality-check/src/traits.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use anyhow::bail;
12
use fn_error_context::context;
3+
use formality_core::Set;
24
use formality_prove::Env;
35
use formality_rust::grammar::{
46
AssociatedTy, AssociatedTyBoundData, Fn, Trait, TraitBoundData, TraitItem, WhereClause,
@@ -31,8 +33,27 @@ impl super::Check<'_> {
3133
Ok(())
3234
}
3335

34-
fn check_trait_items_have_unique_names(&self, _trait_items: &[TraitItem]) -> Fallible<()> {
35-
// FIXME:
36+
fn check_trait_items_have_unique_names(&self, trait_items: &[TraitItem]) -> Fallible<()> {
37+
let mut functions = Set::new();
38+
let mut associated_types = Set::new();
39+
for trait_item in trait_items {
40+
match trait_item {
41+
TraitItem::Fn(f) => {
42+
if !functions.insert(&f.id) {
43+
bail!("the function name `{:?}` is defined multiple times", f.id);
44+
}
45+
}
46+
TraitItem::AssociatedTy(associated_ty) => {
47+
let AssociatedTy { id, .. } = associated_ty;
48+
if !associated_types.insert(id) {
49+
bail!(
50+
"the associated type name `{:?}` is defined multiple times",
51+
id
52+
);
53+
}
54+
}
55+
}
56+
}
3657
Ok(())
3758
}
3859

src/test/mod.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,48 @@ fn basic_where_clauses_fail() {
133133
expression evaluated to an empty collection: `decls.trait_invariants()`"#]]
134134
)
135135
}
136+
137+
#[test]
138+
fn trait_items_with_duplicate_fn_names() {
139+
crate::assert_err!(
140+
[
141+
crate core {
142+
trait A {
143+
fn a() -> ();
144+
fn a() -> ();
145+
}
146+
}
147+
]
148+
149+
[ /* TODO */ ]
150+
151+
expect_test::expect![[r#"
152+
check_trait(A)
153+
154+
Caused by:
155+
the function name `a` is defined multiple times"#]]
156+
157+
);
158+
}
159+
160+
#[test]
161+
fn trait_items_with_duplicate_associated_type_names() {
162+
crate::assert_err!(
163+
[
164+
crate core {
165+
trait A {
166+
type Assoc : [];
167+
type Assoc : [];
168+
}
169+
}
170+
]
171+
172+
[ /* TODO */ ]
173+
174+
expect_test::expect![[r#"
175+
check_trait(A)
176+
177+
Caused by:
178+
the associated type name `Assoc` is defined multiple times"#]]
179+
);
180+
}

0 commit comments

Comments
 (0)