Skip to content

Commit

Permalink
fmt and clippy
Browse files Browse the repository at this point in the history
  • Loading branch information
vezenovm committed Jul 18, 2024
1 parent 8897de8 commit aebb975
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
14 changes: 12 additions & 2 deletions compiler/noirc_frontend/src/elaborator/trait_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,16 @@ impl<'context> Elaborator<'context> {
let mut substituted_method_ids = HashSet::default();
for method_constraint in method.trait_constraints.iter() {
let substituted_constraint_type = method_constraint.typ.substitute(&bindings);
substituted_method_ids
.insert((substituted_constraint_type, method_constraint.trait_id));
let substituted_trait_generics = method_constraint
.trait_generics
.iter()
.map(|generic| generic.substitute(&bindings))
.collect::<Vec<_>>();
substituted_method_ids.insert((
substituted_constraint_type,
method_constraint.trait_id,
substituted_trait_generics,
));
}

for override_trait_constraint in override_meta.trait_constraints.clone() {
Expand All @@ -183,11 +191,13 @@ impl<'context> Elaborator<'context> {
if !substituted_method_ids.contains(&(
override_trait_constraint.typ.clone(),
override_trait_constraint.trait_id,
override_trait_constraint.trait_generics.clone(),
)) {
let the_trait = self.interner.get_trait(override_trait_constraint.trait_id);
self.push_err(DefCollectorErrorKind::ImplIsStricterThanTrait {
constraint_typ: override_trait_constraint.typ,
constraint_name: the_trait.name.0.contents.clone(),
constraint_generics: override_trait_constraint.trait_generics,
constraint_span: override_trait_constraint.span,
trait_method_name: method.name.0.contents.clone(),
trait_method_span: method.location.span,
Expand Down
14 changes: 12 additions & 2 deletions compiler/noirc_frontend/src/hir/def_collector/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ pub enum DefCollectorErrorKind {
ImplIsStricterThanTrait {
constraint_typ: crate::Type,
constraint_name: String,
constraint_generics: Vec<crate::Type>,
constraint_span: Span,
trait_method_name: String,
trait_method_span: Span,
Expand Down Expand Up @@ -259,10 +260,19 @@ impl<'a> From<&'a DefCollectorErrorKind> for Diagnostic {
ident.0.span(),
)
}
DefCollectorErrorKind::ImplIsStricterThanTrait { constraint_typ, constraint_name: constraint, constraint_span, trait_method_name, trait_method_span } => {
DefCollectorErrorKind::ImplIsStricterThanTrait { constraint_typ, constraint_name, constraint_generics, constraint_span, trait_method_name, trait_method_span } => {
let mut constraint_name_with_generics = constraint_name.to_owned();
if !constraint_generics.is_empty() {
constraint_name_with_generics.push('<');
for generic in constraint_generics.iter() {
constraint_name_with_generics.push_str(generic.to_string().as_str());
}
constraint_name_with_generics.push('>');
}

let mut diag = Diagnostic::simple_error(
"impl has stricter requirements than trait".to_string(),
format!("impl has extra requirement `{constraint_typ}: {constraint}`"),
format!("impl has extra requirement `{constraint_typ}: {constraint_name_with_generics}`"),
*constraint_span,
);
diag.add_secondary(format!("definition of `{trait_method_name}` from trait"), *trait_method_span);
Expand Down
33 changes: 33 additions & 0 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,39 @@ fn trait_impl_where_clause_stricter_pass() {
}
}

#[test]
fn impl_stricter_than_trait_different_trait_generics() {
let src = r#"
trait Foo<T> {
fn foo<U>() where T: T2<T>;
}
impl<A> Foo<A> for () {
// Should be A: T2<A>
fn foo<B>() where A: T2<B> {}
}
trait T2<C> {}
"#;

let errors = get_program_errors(src);
assert_eq!(errors.len(), 1);
if let CompilationError::DefinitionError(DefCollectorErrorKind::ImplIsStricterThanTrait {
constraint_typ,
constraint_name,
constraint_generics,
..
}) = &errors[0].0
{
dbg!(constraint_name.as_str());
assert!(matches!(constraint_typ.to_string().as_str(), "A"));
assert!(matches!(constraint_name.as_str(), "T2"));
assert!(matches!(constraint_generics[0].to_string().as_str(), "B"));
} else {
panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0].0);
}
}

#[test]
fn impl_not_found_for_inner_impl() {
// We want to guarantee that we get a no impl found error
Expand Down

0 comments on commit aebb975

Please sign in to comment.