Skip to content

Commit

Permalink
feat: Add TraitDefinition::as_trait_constraint() (#5541)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Part of work towards
#4594 (comment),
forgot an issue for this one.

## Summary\*



## Additional Context



## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
jfecher authored Jul 19, 2024
1 parent d5de83f commit 0943223
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 2 deletions.
38 changes: 37 additions & 1 deletion compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ use std::{

use acvm::{AcirField, FieldElement};
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, Path, Signedness, UnresolvedTypeData},
node_interner::TraitId,
parser,
token::{SpannedToken, Token, Tokens},
QuotedType, Type,
Expand Down Expand Up @@ -42,6 +44,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}");
Expand Down Expand Up @@ -103,6 +108,16 @@ fn get_trait_constraint(value: Value, location: Location) -> IResult<TraitBound>
}
}

fn get_trait_def(value: Value, location: Location) -> IResult<TraitId> {
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<Rc<Tokens>> {
match value {
Value::Code(tokens) => Ok(tokens),
Expand Down Expand Up @@ -456,3 +471,24 @@ fn modulus_num_bits(
let bits = FieldElement::max_num_bits().into();
Ok(Value::U64(bits))
}

fn trait_def_as_trait_constraint(
interner: &mut NodeInterner,
mut arguments: Vec<(Value, Location)>,
location: Location,
) -> Result<Value, InterpreterError> {
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 }))
}
3 changes: 2 additions & 1 deletion noir_stdlib/src/meta/mod.nr
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 4 additions & 0 deletions noir_stdlib/src/meta/trait_def.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
impl TraitDefinition {
#[builtin(trait_def_as_trait_constraint)]
fn as_trait_constraint(_self: Self) -> TraitConstraint {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "trait_as_constraint"
type = "bin"
authors = [""]
compiler_version = ">=0.31.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[test_as_constraint]
trait Foo<T> {}

comptime fn test_as_constraint(t: TraitDefinition) {
let constraint = t.as_trait_constraint();
assert(constraint == constraint);
}

fn main() {}

0 comments on commit 0943223

Please sign in to comment.