diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index abff466e1d5..9a54e76b8a4 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -371,7 +371,7 @@ impl<'interner> TypeChecker<'interner> { // We need to do this first since otherwise instantiating the type below // will replace each trait generic with a fresh type variable, rather than // the type used in the trait constraint (if it exists). See #4088. - if let ImplKind::TraitMethod(_, constraint, _) = &ident.impl_kind { + if let ImplKind::TraitMethod(_, constraint, assumed) = &ident.impl_kind { let the_trait = self.interner.get_trait(constraint.trait_id); assert_eq!(the_trait.generics.len(), constraint.trait_generics.len()); @@ -381,6 +381,16 @@ impl<'interner> TypeChecker<'interner> { bindings.insert(param.id(), (param.clone(), arg.clone())); } } + + // If the trait impl is already assumed to exist we should add any type bindings for `Self`. + // Otherwise `self` will be replaced with a fresh type variable, which will require the user + // to specify a redundant type annotation. + if *assumed { + bindings.insert( + the_trait.self_type_typevar_id, + (the_trait.self_type_typevar.clone(), constraint.typ.clone()), + ); + } } // An identifiers type may be forall-quantified in the case of generic functions. diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 7bf5655486b..bd81752c046 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -1430,14 +1430,14 @@ fn specify_method_types_with_turbofish() { } impl Foo { - fn generic_method(_self: Self) where U: Default { + fn generic_method(_self: Self) -> U where U: Default { U::default() } } fn main() { let foo: Foo = Foo { inner: 1 }; - foo.generic_method::(); + let _ = foo.generic_method::(); } "#; let errors = get_program_errors(src); diff --git a/noir_stdlib/src/eddsa.nr b/noir_stdlib/src/eddsa.nr index 1ab0158af8f..337969be90e 100644 --- a/noir_stdlib/src/eddsa.nr +++ b/noir_stdlib/src/eddsa.nr @@ -45,7 +45,7 @@ where H: Hasher + Default { // Ensure S < Subgroup Order assert(signature_s.lt(bjj.suborder)); // Calculate the h = H(R, A, msg) - let mut hasher: H = H::default(); + let mut hasher = H::default(); hasher.write(signature_r8_x); hasher.write(signature_r8_y); hasher.write(pub_key_x); diff --git a/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr b/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr index 709a694e77b..b880d3ae047 100644 --- a/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr +++ b/test_programs/execution_success/turbofish_call_func_diff_types/src/main.nr @@ -23,9 +23,7 @@ fn main(x: Field, y: pub Field) { fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { // Check that we can call a trait method instead of a trait implementation - // TODO(https://github.com/noir-lang/noir/issues/5063): Need to remove the need for this type annotation - // Curently, without the annotation we will get `Expression type is ambiguous` when trying to use the `hasher` - let mut hasher: H = H::default(); + let mut hasher = H::default(); // Regression that the object is converted to a mutable reference type `&mut _`. // Otherwise will see `Expected type &mut _, found type H`. // Then we need to make sure to also auto dereference later in the type checking process diff --git a/tooling/nargo_cli/src/cli/info_cmd.rs b/tooling/nargo_cli/src/cli/info_cmd.rs index 6c0709e7611..7c50e907dc9 100644 --- a/tooling/nargo_cli/src/cli/info_cmd.rs +++ b/tooling/nargo_cli/src/cli/info_cmd.rs @@ -102,7 +102,8 @@ pub(crate) fn run(args: InfoCommand, config: NargoConfig) -> Result<(), CliError } else { // Otherwise print human-readable table. if !info_report.programs.is_empty() { - let mut program_table = table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes"]); + let mut program_table = + table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes"]); for program_info in info_report.programs { let program_rows: Vec = program_info.into();