diff --git a/.github/critical_libraries_status/noir-lang/noir_bigcurve/.failures.jsonl b/.github/critical_libraries_status/noir-lang/noir_bigcurve/.failures.jsonl index a5126ebd409..e69de29bb2d 100644 --- a/.github/critical_libraries_status/noir-lang/noir_bigcurve/.failures.jsonl +++ b/.github/critical_libraries_status/noir-lang/noir_bigcurve/.failures.jsonl @@ -1 +0,0 @@ -{"suite":"noir_bigcurve","name":"utils::derive_offset_generators::test_compute_and_print_offset_generators"} diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index 78fe390c7a3..6f7672af806 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -4,7 +4,7 @@ use noirc_errors::{Located, Location}; use rustc_hash::FxHashSet as HashSet; use crate::{ - DataType, Kind, QuotedType, Shared, Type, TypeVariable, + DataType, Kind, QuotedType, Shared, Type, TypeBindings, TypeVariable, ast::{ ArrayLiteral, AsTraitPath, BinaryOpKind, BlockExpression, CallExpression, CastExpression, ConstrainExpression, ConstrainKind, ConstructorExpression, Expression, ExpressionKind, @@ -1474,6 +1474,9 @@ impl Elaborator<'_> { let constraint = TraitConstraint { typ, trait_bound }; let the_trait = self.interner.get_trait(constraint.trait_bound.trait_id); + let self_type = the_trait.self_type_typevar.clone(); + let kind = the_trait.self_type_typevar.kind(); + let Some(definition) = the_trait.find_method_or_constant(path.impl_item.as_str(), self.interner) else { @@ -1496,7 +1499,21 @@ impl Elaborator<'_> { let id = self.interner.push_expr(HirExpression::Ident(ident.clone(), None)); self.interner.push_expr_location(id, location); - let typ = self.type_check_variable(ident, id, None); + let mut bindings = TypeBindings::default(); + + // In `::method` we know `Self` is `Type` so we bind that now + bindings.insert(self_type.id(), (self_type, kind, constraint.typ.clone())); + + // TODO: set this to `true`. See https://github.com/noir-lang/noir/issues/8687 + let push_required_type_variables = self.current_trait.is_none(); + + let typ = self.type_check_variable_with_bindings( + ident, + id, + None, + bindings, + push_required_type_variables, + ); self.interner.push_expr_type(id, typ.clone()); (id, typ) } diff --git a/compiler/noirc_frontend/src/tests/traits.rs b/compiler/noirc_frontend/src/tests/traits.rs index 9813039c2af..4bc9b800ce2 100644 --- a/compiler/noirc_frontend/src/tests/traits.rs +++ b/compiler/noirc_frontend/src/tests/traits.rs @@ -1783,3 +1783,24 @@ fn ambiguous_associated_type() { "#; check_errors!(src); } + +#[named] +#[test] +fn as_trait_path_self_type() { + let src = r#" + pub trait BigCurve { + fn one() -> Self; + } + + struct Bn254 {} + + impl BigCurve for Bn254 { + fn one() -> Self { Bn254 {} } + } + + fn main() { + let _ = >::one(); + } + "#; + assert_no_errors!(src); +} diff --git a/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/Nargo.toml b/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/Nargo.toml new file mode 100644 index 00000000000..bd86ebadf0c --- /dev/null +++ b/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/Nargo.toml @@ -0,0 +1,7 @@ + + [package] + name = "noirc_frontend_tests_traits_as_trait_path_self_type" + type = "bin" + authors = [""] + + [dependencies] \ No newline at end of file diff --git a/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/src/main.nr b/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/src/main.nr new file mode 100644 index 00000000000..56726a8823e --- /dev/null +++ b/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/src/main.nr @@ -0,0 +1,15 @@ + + pub trait BigCurve { + fn one() -> Self; + } + + struct Bn254 {} + + impl BigCurve for Bn254 { + fn one() -> Self { Bn254 {} } + } + + fn main() { + let _ = >::one(); + } + \ No newline at end of file diff --git a/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/src_hash.txt b/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/src_hash.txt new file mode 100644 index 00000000000..5dfcdb992b6 --- /dev/null +++ b/test_programs/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/src_hash.txt @@ -0,0 +1 @@ +14346112081613033525 \ No newline at end of file diff --git a/tooling/nargo_cli/tests/snapshots/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/execute__tests__expanded.snap b/tooling/nargo_cli/tests/snapshots/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/execute__tests__expanded.snap new file mode 100644 index 00000000000..ac928492d82 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/compile_success_no_bug/noirc_frontend_tests_traits_as_trait_path_self_type/execute__tests__expanded.snap @@ -0,0 +1,19 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: expanded_code +--- +pub trait BigCurve { + fn one() -> Self; +} + +struct Bn254 {} + +impl BigCurve for Bn254 { + fn one() -> Self { + Self {} + } +} + +fn main() { + let _: Bn254 = >::one(); +}