From 5a8183ea62cc8214e3fbecf4f21581abe4e36606 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Wed, 17 Jul 2024 15:28:34 -0500 Subject: [PATCH 1/3] Trait to constraint --- .../src/hir/comptime/interpreter/builtin.rs | 39 ++++++++++++++++++- noir_stdlib/src/meta/mod.nr | 3 +- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index eea5e2747e..c7c7d50803 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -4,15 +4,16 @@ use std::{ }; use chumsky::Parser; +use iter_extended::vecmap; use noirc_errors::Location; use crate::{ ast::{IntegerBitSize, TraitBound}, hir::comptime::{errors::IResult, InterpreterError, Value}, - macros_api::{NodeInterner, Signedness}, + macros_api::{NodeInterner, Signedness, UnresolvedTypeData, Path}, parser, token::{SpannedToken, Token, Tokens}, - QuotedType, Type, + QuotedType, Type, node_interner::TraitId, }; pub(super) fn call_builtin( @@ -36,6 +37,9 @@ pub(super) fn call_builtin( "struct_def_generics" => struct_def_generics(interner, arguments, location), "trait_constraint_eq" => trait_constraint_eq(interner, arguments, location), "trait_constraint_hash" => trait_constraint_hash(interner, arguments, location), + "trait_def_as_trait_constraint" => { + trait_def_as_trait_constraint(interner, arguments, location) + } "quoted_as_trait_constraint" => quoted_as_trait_constraint(interner, arguments, location), _ => { let item = format!("Comptime evaluation for builtin function {name}"); @@ -97,6 +101,16 @@ fn get_trait_constraint(value: Value, location: Location) -> IResult } } +fn get_trait_def(value: Value, location: Location) -> IResult { + match value { + Value::TraitDefinition(id) => Ok(id), + value => { + let expected = Type::Quoted(QuotedType::TraitDefinition); + Err(InterpreterError::TypeMismatch { expected, value, location }) + } + } +} + fn get_quoted(value: Value, location: Location) -> IResult> { match value { Value::Code(tokens) => Ok(tokens), @@ -386,3 +400,24 @@ fn trait_constraint_eq( Ok(Value::Bool(constraint_a == constraint_b)) } + +fn trait_def_as_trait_constraint( + interner: &mut NodeInterner, + mut arguments: Vec<(Value, Location)>, + location: Location, +) -> Result { + check_argument_count(1, &arguments, location)?; + + let trait_id = get_trait_def(arguments.pop().unwrap().0, location)?; + let the_trait = interner.get_trait(trait_id); + + let trait_path = Path::from_ident(the_trait.name.clone()); + + let trait_generics = vecmap(&the_trait.generics, |generic| { + let name = Path::from_single(generic.name.as_ref().clone(), generic.span); + UnresolvedTypeData::Named(name, Vec::new(), false).with_span(generic.span) + }); + + let trait_id = Some(trait_id); + Ok(Value::TraitConstraint(TraitBound { trait_path, trait_id, trait_generics })) +} diff --git a/noir_stdlib/src/meta/mod.nr b/noir_stdlib/src/meta/mod.nr index ed3365d755..395f09a453 100644 --- a/noir_stdlib/src/meta/mod.nr +++ b/noir_stdlib/src/meta/mod.nr @@ -1,5 +1,6 @@ -mod type_def; mod trait_constraint; +mod trait_def; +mod type_def; mod quoted; /// Calling unquote as a macro (via `unquote!(arg)`) will unquote From 3f62df818cee8a43bee0e0f6d725e231dfb7facb Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Wed, 17 Jul 2024 15:33:38 -0500 Subject: [PATCH 2/3] Add missed stdlib file --- noir_stdlib/src/meta/trait_def.nr | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 noir_stdlib/src/meta/trait_def.nr diff --git a/noir_stdlib/src/meta/trait_def.nr b/noir_stdlib/src/meta/trait_def.nr new file mode 100644 index 0000000000..5de7631e34 --- /dev/null +++ b/noir_stdlib/src/meta/trait_def.nr @@ -0,0 +1,4 @@ +impl TraitDefinition { + #[builtin(trait_def_as_trait_constraint)] + fn as_trait_constraint(_self: Self) -> TraitConstraint {} +} From fcc65e6916df1b37fdc63cac25a7f12589fa7119 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Thu, 18 Jul 2024 15:53:16 -0500 Subject: [PATCH 3/3] Add test --- .../compile_success_empty/trait_as_constraint/Nargo.toml | 7 +++++++ .../trait_as_constraint/src/main.nr | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 test_programs/compile_success_empty/trait_as_constraint/Nargo.toml create mode 100644 test_programs/compile_success_empty/trait_as_constraint/src/main.nr diff --git a/test_programs/compile_success_empty/trait_as_constraint/Nargo.toml b/test_programs/compile_success_empty/trait_as_constraint/Nargo.toml new file mode 100644 index 0000000000..907b5ce09e --- /dev/null +++ b/test_programs/compile_success_empty/trait_as_constraint/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "trait_as_constraint" +type = "bin" +authors = [""] +compiler_version = ">=0.31.0" + +[dependencies] \ No newline at end of file diff --git a/test_programs/compile_success_empty/trait_as_constraint/src/main.nr b/test_programs/compile_success_empty/trait_as_constraint/src/main.nr new file mode 100644 index 0000000000..1911f045c2 --- /dev/null +++ b/test_programs/compile_success_empty/trait_as_constraint/src/main.nr @@ -0,0 +1,9 @@ +#[test_as_constraint] +trait Foo {} + +comptime fn test_as_constraint(t: TraitDefinition) { + let constraint = t.as_trait_constraint(); + assert(constraint == constraint); +} + +fn main() {}