diff --git a/crates/formality-check/src/traits.rs b/crates/formality-check/src/traits.rs index 22791031..d319f652 100644 --- a/crates/formality-check/src/traits.rs +++ b/crates/formality-check/src/traits.rs @@ -1,4 +1,6 @@ +use anyhow::bail; use fn_error_context::context; +use formality_core::Set; use formality_prove::Env; use formality_rust::grammar::{ AssociatedTy, AssociatedTyBoundData, Fn, Trait, TraitBoundData, TraitItem, WhereClause, @@ -31,8 +33,27 @@ impl super::Check<'_> { Ok(()) } - fn check_trait_items_have_unique_names(&self, _trait_items: &[TraitItem]) -> Fallible<()> { - // FIXME: + fn check_trait_items_have_unique_names(&self, trait_items: &[TraitItem]) -> Fallible<()> { + let mut functions = Set::new(); + let mut associated_types = Set::new(); + for trait_item in trait_items { + match trait_item { + TraitItem::Fn(f) => { + if !functions.insert(&f.id) { + bail!("the function name `{:?}` is defined multiple times", f.id); + } + } + TraitItem::AssociatedTy(associated_ty) => { + let AssociatedTy { id, .. } = associated_ty; + if !associated_types.insert(id) { + bail!( + "the associated type name `{:?}` is defined multiple times", + id + ); + } + } + } + } Ok(()) } diff --git a/src/test/mod.rs b/src/test/mod.rs index b525f96e..9fc7bd87 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -133,3 +133,48 @@ fn basic_where_clauses_fail() { expression evaluated to an empty collection: `decls.trait_invariants()`"#]] ) } + +#[test] +fn trait_items_with_duplicate_fn_names() { + crate::assert_err!( + [ + crate core { + trait A { + fn a() -> (); + fn a() -> (); + } + } + ] + + [ /* TODO */ ] + + expect_test::expect![[r#" + check_trait(A) + + Caused by: + the function name `a` is defined multiple times"#]] + + ); +} + +#[test] +fn trait_items_with_duplicate_associated_type_names() { + crate::assert_err!( + [ + crate core { + trait A { + type Assoc : []; + type Assoc : []; + } + } + ] + + [ /* TODO */ ] + + expect_test::expect![[r#" + check_trait(A) + + Caused by: + the associated type name `Assoc` is defined multiple times"#]] + ); +}