Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add conditional compilation of methods based on the underlying field being used #3045

Merged
merged 4 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions acvm-repo/acir_field/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ repository.workspace = true
hex.workspace = true
num-bigint.workspace = true
serde.workspace = true
num-traits.workspace = true

ark-bn254 = { version = "^0.4.0", optional = true, default-features = false, features = [
"curve",
Expand Down
26 changes: 25 additions & 1 deletion acvm-repo/acir_field/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#![warn(clippy::semicolon_if_nothing_returned)]
#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))]

use num_bigint::BigUint;
use num_traits::Num;

cfg_if::cfg_if! {
if #[cfg(feature = "bn254")] {
mod generic_ark;
Expand All @@ -18,12 +21,33 @@ cfg_if::cfg_if! {
}
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
pub enum FieldOptions {
BN254,
BLS12_381,
}

impl FieldOptions {
pub fn to_string(&self) -> &str {
match self {
FieldOptions::BN254 => "bn254",
FieldOptions::BLS12_381 => "bls12_381",
}
}

pub fn is_native_field(str: &str) -> bool {
let big_num = if let Some(hex) = str.strip_prefix("0x") {
BigUint::from_str_radix(hex, 16)
} else {
BigUint::from_str_radix(str, 10)
};
if let Ok(big_num) = big_num {
big_num == FieldElement::modulus()
} else {
CHOSEN_FIELD.to_string() == str
}
}
}
// This is needed because features are additive through the dependency graph; if a dependency turns on the bn254, then it
// will be turned on in all crates that depend on it
#[macro_export]
Expand Down
8 changes: 8 additions & 0 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::vec;

use acvm::acir::acir_field::FieldOptions;
use fm::FileId;
use noirc_errors::Location;

Expand Down Expand Up @@ -202,6 +203,13 @@
let module = ModuleId { krate, local_id: self.module_id };

for function in functions {
// check if optional field attribute is compatible with native field
if let Some(field) = function.attributes().get_field_attribute() {
if !FieldOptions::is_native_field(&field) {
continue;
}
}

let name = function.name_ident().clone();
let func_id = context.def_interner.push_empty_fn();

Expand Down Expand Up @@ -243,7 +251,7 @@
types: Vec<NoirStruct>,
krate: CrateId,
) -> Vec<(CompilationError, FileId)> {
let mut definiton_errors = vec![];

Check warning on line 254 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (definiton)
for struct_definition in types {
let name = struct_definition.name.clone();

Expand All @@ -257,7 +265,7 @@
let id = match self.push_child_module(&name, self.file_id, false, false) {
Ok(local_id) => context.def_interner.new_struct(&unresolved, krate, local_id),
Err(error) => {
definiton_errors.push((error.into(), self.file_id));

Check warning on line 268 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (definiton)
continue;
}
};
Expand All @@ -272,13 +280,13 @@
first_def,
second_def,
};
definiton_errors.push((error.into(), self.file_id));

Check warning on line 283 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (definiton)
}

// And store the TypeId -> StructType mapping somewhere it is reachable
self.def_collector.collected_types.insert(id, unresolved);
}
definiton_errors

Check warning on line 289 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (definiton)
}

/// Collect any type aliases definitions declared within the ast.
Expand Down Expand Up @@ -374,7 +382,7 @@
.declare_function(name.clone(), func_id)
{
Ok(()) => {
// TODO(Maddiaa): Investigate trait implementations with attributes see: https://github.com/noir-lang/noir/issues/2629

Check warning on line 385 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (Maddiaa)
if let Some(body) = body {
let impl_method =
NoirFunction::normal(FunctionDefinition::normal(
Expand Down Expand Up @@ -418,7 +426,7 @@
}
}
TraitItem::Type { name } => {
// TODO(nickysn or alexvitkov): implement context.def_interner.push_empty_type_alias and get an id, instead of using TypeAliasId::dummy_id()

Check warning on line 429 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (nickysn)

Check warning on line 429 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (alexvitkov)
if let Err((first_def, second_def)) = self.def_collector.def_map.modules
[id.0.local_id.0]
.declare_type_alias(name.clone(), TypeAliasId::dummy_id())
Expand Down Expand Up @@ -506,7 +514,7 @@
};
errors.push((error.into(), location.file));

let error2 = DefCollectorErrorKind::ModuleOrignallyDefined {

Check warning on line 517 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (Orignally)
mod_name: mod_name.clone(),
span: old_location.span,
};
Expand Down
17 changes: 16 additions & 1 deletion compiler/noirc_frontend/src/lexer/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@
match string.trim() {
"should_fail" => Some(TestScope::ShouldFailWith { reason: None }),
s if s.starts_with("should_fail_with") => {
let parts: Vec<&str> = s.splitn(2, '=').collect();

Check warning on line 335 in compiler/noirc_frontend/src/lexer/token.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (splitn)
if parts.len() == 2 {
let reason = parts[1].trim();
let reason = reason.trim_matches('"');
Expand Down Expand Up @@ -395,6 +395,15 @@
_ => None,
})
}

pub fn get_field_attribute(&self) -> Option<String> {
for secondary in &self.secondary {
if let SecondaryAttribute::Field(field) = secondary {
return Some(field.to_lowercase());
}
}
None
}
}

/// An Attribute can be either a Primary Attribute or a Secondary Attribute
Expand Down Expand Up @@ -466,6 +475,10 @@
None => return Err(malformed_scope),
}
}
["field", name] => {
validate(name)?;
Attribute::Secondary(SecondaryAttribute::Field(name.to_string()))
}
// Secondary attributes
["deprecated"] => Attribute::Secondary(SecondaryAttribute::Deprecated(None)),
["contract_library_method"] => {
Expand Down Expand Up @@ -550,6 +563,7 @@
// the entry point.
ContractLibraryMethod,
Event,
Field(String),
Custom(String),
}

Expand All @@ -563,6 +577,7 @@
SecondaryAttribute::Custom(ref k) => write!(f, "#[{k}]"),
SecondaryAttribute::ContractLibraryMethod => write!(f, "#[contract_library_method]"),
SecondaryAttribute::Event => write!(f, "#[event]"),
SecondaryAttribute::Field(ref k) => write!(f, "#[field({k})]"),
}
}
}
Expand All @@ -583,7 +598,7 @@
match self {
SecondaryAttribute::Deprecated(Some(string)) => string,
SecondaryAttribute::Deprecated(None) => "",
SecondaryAttribute::Custom(string) => string,
SecondaryAttribute::Custom(string) | SecondaryAttribute::Field(string) => string,
SecondaryAttribute::ContractLibraryMethod => "",
SecondaryAttribute::Event => "",
}
Expand Down Expand Up @@ -650,7 +665,7 @@
Keyword::Field => write!(f, "Field"),
Keyword::Fn => write!(f, "fn"),
Keyword::For => write!(f, "for"),
Keyword::FormatString => write!(f, "fmtstr"),

Check warning on line 668 in compiler/noirc_frontend/src/lexer/token.rs

View workflow job for this annotation

GitHub Actions / Spellcheck / Spellcheck

Unknown word (fmtstr)
Keyword::Global => write!(f, "global"),
Keyword::If => write!(f, "if"),
Keyword::Impl => write!(f, "impl"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "field_attribute"
type = "bin"
authors = [""]
compiler_version = "0.1"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = "3"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Test integer addition: 3 + 4 = 7
fn main(mut x: u32) {
assert(x> foo());
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
}

#[field(bn254)]
fn foo() -> u32 {
1
}

#[field(23)]
fn foo() -> u32 {
2
}

#[field(bls12_381)]
fn foo() -> u32 {
3
}