Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 6 additions & 6 deletions compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use noirc_frontend::monomorphization::{
errors::MonomorphizationError, monomorphize, monomorphize_debug,
};
use noirc_frontend::node_interner::{FuncId, GlobalId, TypeId};
use noirc_frontend::token::SecondaryAttribute;
use noirc_frontend::token::SecondaryAttributeKind;
use std::collections::HashMap;
use std::path::Path;
use tracing::info;
Expand Down Expand Up @@ -507,7 +507,7 @@ fn read_contract(context: &Context, module_id: ModuleId, name: String) -> Contra

context.def_interner.get_all_globals().iter().for_each(|global_info| {
context.def_interner.global_attributes(&global_info.id).iter().for_each(|attr| {
if let SecondaryAttribute::Abi(tag) = attr {
if let SecondaryAttributeKind::Abi(tag) = &attr.kind {
if let Some(tagged) = outputs.globals.get_mut(tag) {
tagged.push(global_info.id);
} else {
Expand All @@ -520,7 +520,7 @@ fn read_contract(context: &Context, module_id: ModuleId, name: String) -> Contra
module.type_definitions().for_each(|id| {
if let ModuleDefId::TypeId(struct_id) = id {
context.def_interner.type_attributes(&struct_id).iter().for_each(|attr| {
if let SecondaryAttribute::Abi(tag) = attr {
if let SecondaryAttributeKind::Abi(tag) = &attr.kind {
if let Some(tagged) = outputs.structs.get_mut(tag) {
tagged.push(struct_id);
} else {
Expand Down Expand Up @@ -584,9 +584,9 @@ fn compile_contract_inner(
.attributes
.secondary
.iter()
.filter_map(|attr| match attr {
SecondaryAttribute::Tag(attribute) => Some(attribute.contents.clone()),
SecondaryAttribute::Meta(attribute) => Some(attribute.to_string()),
.filter_map(|attr| match &attr.kind {
SecondaryAttributeKind::Tag(contents) => Some(contents.clone()),
SecondaryAttributeKind::Meta(attribute) => Some(attribute.to_string()),
_ => None,
})
.collect();
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/ast/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct NoirEnumeration {

impl NoirEnumeration {
pub fn is_abi(&self) -> bool {
self.attributes.iter().any(|attr| attr.is_abi())
self.attributes.iter().any(|attr| attr.kind.is_abi())
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::ast::{
use crate::node_interner::{ExprId, InternedExpressionKind, InternedStatementKind, QuotedTypeId};
use crate::shared::Visibility;
use crate::signed_field::SignedField;
use crate::token::{Attributes, FmtStrFragment, FunctionAttribute, Token, Tokens};
use crate::token::{Attributes, FmtStrFragment, FunctionAttributeKind, Token, Tokens};
use crate::{Kind, Type};
use acvm::FieldElement;
use iter_extended::vecmap;
Expand Down Expand Up @@ -531,7 +531,7 @@ impl FunctionDefinition {

pub fn is_test(&self) -> bool {
if let Some(attribute) = self.attributes.function() {
matches!(attribute, FunctionAttribute::Test(..))
matches!(attribute.kind, FunctionAttributeKind::Test(..))
} else {
false
}
Expand Down
29 changes: 10 additions & 19 deletions compiler/noirc_frontend/src/ast/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use noirc_errors::{Location, Span};
use crate::{
ast::{FunctionReturnType, Ident, Param},
shared::Visibility,
token::{Attributes, FunctionAttribute, SecondaryAttribute},
token::{Attributes, FunctionAttribute, FunctionAttributeKind, SecondaryAttribute},
};

use super::{FunctionDefinition, UnresolvedType, UnresolvedTypeData};
Expand Down Expand Up @@ -105,29 +105,20 @@ impl NoirFunction {
pub fn span(&self) -> Span {
self.location().span
}

pub fn foreign(&self) -> Option<&FunctionDefinition> {
match &self.kind {
FunctionKind::LowLevel => {}
_ => return None,
}
assert!(self.function_attribute().unwrap().is_foreign());
Some(&self.def)
}
}

impl From<FunctionDefinition> for NoirFunction {
fn from(fd: FunctionDefinition) -> Self {
// The function type is determined by the existence of a function attribute
let kind = match fd.attributes.function() {
Some(FunctionAttribute::Builtin(_)) => FunctionKind::Builtin,
Some(FunctionAttribute::Foreign(_)) => FunctionKind::LowLevel,
Some(FunctionAttribute::Test { .. }) => FunctionKind::Normal,
Some(FunctionAttribute::FuzzingHarness { .. }) => FunctionKind::Normal,
Some(FunctionAttribute::Oracle(_)) => FunctionKind::Oracle,
Some(FunctionAttribute::Fold) => FunctionKind::Normal,
Some(FunctionAttribute::NoPredicates) => FunctionKind::Normal,
Some(FunctionAttribute::InlineAlways) => FunctionKind::Normal,
let kind = match fd.attributes.function().map(|attr| &attr.kind) {
Some(FunctionAttributeKind::Builtin(_)) => FunctionKind::Builtin,
Some(FunctionAttributeKind::Foreign(_)) => FunctionKind::LowLevel,
Some(FunctionAttributeKind::Test { .. }) => FunctionKind::Normal,
Some(FunctionAttributeKind::FuzzingHarness { .. }) => FunctionKind::Normal,
Some(FunctionAttributeKind::Oracle(_)) => FunctionKind::Oracle,
Some(FunctionAttributeKind::Fold) => FunctionKind::Normal,
Some(FunctionAttributeKind::NoPredicates) => FunctionKind::Normal,
Some(FunctionAttributeKind::InlineAlways) => FunctionKind::Normal,
None => FunctionKind::Normal,
};

Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/ast/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct NoirStruct {

impl NoirStruct {
pub fn is_abi(&self) -> bool {
self.attributes.iter().any(|attr| attr.is_abi())
self.attributes.iter().any(|attr| attr.kind.is_abi())
}
}

Expand Down
41 changes: 35 additions & 6 deletions compiler/noirc_frontend/src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
},
parser::{Item, ItemKind, ParsedSubModule},
signed_field::SignedField,
token::{FmtStrFragment, MetaAttribute, MetaAttributeName, SecondaryAttribute, Tokens},
token::{
FmtStrFragment, MetaAttribute, MetaAttributeName, SecondaryAttribute,
SecondaryAttributeKind, Tokens,
},
};

use super::{
Expand Down Expand Up @@ -526,7 +529,21 @@
true
}

fn visit_meta_attribute(&mut self, _: &MetaAttribute, _target: AttributeTarget) -> bool {
fn visit_secondary_attribute_kind(
&mut self,
_: &SecondaryAttributeKind,
_target: AttributeTarget,
_span: Span,
) -> bool {
true
}

fn visit_meta_attribute(
&mut self,
_: &MetaAttribute,
_target: AttributeTarget,
_span: Span,
) -> bool {
true
}
}
Expand Down Expand Up @@ -1465,8 +1482,8 @@
UnresolvedTypeData::FieldElement => {
visitor.visit_field_element_type(self.location.span);
}
UnresolvedTypeData::Integer(signdness, size) => {

Check warning on line 1485 in compiler/noirc_frontend/src/ast/visitor.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (signdness)
visitor.visit_integer_type(*signdness, *size, self.location.span);

Check warning on line 1486 in compiler/noirc_frontend/src/ast/visitor.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (signdness)
}
UnresolvedTypeData::Bool => visitor.visit_bool_type(self.location.span),
UnresolvedTypeData::Unit => visitor.visit_unit_type(self.location.span),
Expand Down Expand Up @@ -1644,15 +1661,27 @@
}

pub fn accept_children(&self, target: AttributeTarget, visitor: &mut impl Visitor) {
if let SecondaryAttribute::Meta(meta_attribute) = self {
meta_attribute.accept(target, visitor);
self.kind.accept(target, self.location.span, visitor);
}
}

impl SecondaryAttributeKind {
pub fn accept(&self, target: AttributeTarget, span: Span, visitor: &mut impl Visitor) {
if visitor.visit_secondary_attribute_kind(self, target, span) {
self.accept_children(target, span, visitor);
}
}

pub fn accept_children(&self, target: AttributeTarget, span: Span, visitor: &mut impl Visitor) {
if let SecondaryAttributeKind::Meta(meta_attribute) = self {
meta_attribute.accept(target, span, visitor);
}
}
}

impl MetaAttribute {
pub fn accept(&self, target: AttributeTarget, visitor: &mut impl Visitor) {
if visitor.visit_meta_attribute(self, target) {
pub fn accept(&self, target: AttributeTarget, span: Span, visitor: &mut impl Visitor) {
if visitor.visit_meta_attribute(self, target, span) {
self.accept_children(visitor);
}
}
Expand Down
9 changes: 5 additions & 4 deletions compiler/noirc_frontend/src/elaborator/comptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
hir_def::expr::{HirExpression, HirIdent},
node_interner::{DefinitionKind, DependencyId, FuncId, NodeInterner, TraitId, TypeId},
parser::{Item, ItemKind},
token::{MetaAttribute, MetaAttributeName, SecondaryAttribute},
token::{MetaAttribute, MetaAttributeName, SecondaryAttribute, SecondaryAttributeKind},
};

use super::{ElaborateReason, Elaborator, FunctionContext, ResolverMeta};
Expand Down Expand Up @@ -160,10 +160,11 @@ impl<'context> Elaborator<'context> {
attribute_context: AttributeContext,
attributes_to_run: &mut CollectedAttributes,
) {
if let SecondaryAttribute::Meta(attribute) = attribute {
if let SecondaryAttributeKind::Meta(meta) = &attribute.kind {
self.elaborate_in_comptime_context(|this| {
if let Err(error) = this.collect_comptime_attribute_name_on_item(
attribute,
meta,
attribute.location,
item.clone(),
attribute_context,
attributes_to_run,
Expand All @@ -178,12 +179,12 @@ impl<'context> Elaborator<'context> {
fn collect_comptime_attribute_name_on_item(
&mut self,
attribute: &MetaAttribute,
location: Location,
item: Value,
attribute_context: AttributeContext,
attributes_to_run: &mut CollectedAttributes,
) -> Result<(), CompilationError> {
self.local_module = attribute_context.attribute_module;
let location = attribute.location;

let kind = match &attribute.name {
MetaAttributeName::Path(path) => ExpressionKind::Variable(path.clone()),
Expand Down
54 changes: 35 additions & 19 deletions compiler/noirc_frontend/src/elaborator/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{
DefinitionId, DefinitionKind, ExprId, FuncId, FunctionModifiers, NodeInterner,
},
shared::{Signedness, Visibility},
token::FunctionAttributeKind,
};

use noirc_errors::Location;
Expand Down Expand Up @@ -46,32 +47,42 @@ pub(super) fn inlining_attributes(
func: &FuncMeta,
modifiers: &FunctionModifiers,
) -> Option<ResolverError> {
if modifiers.is_unconstrained {
if modifiers.attributes.is_no_predicates() {
if !modifiers.is_unconstrained {
return None;
}

let attribute = modifiers.attributes.function()?;
let location = attribute.location;
match &attribute.kind {
FunctionAttributeKind::NoPredicates => {
let ident = func_meta_name_ident(func, modifiers);
Some(ResolverError::NoPredicatesAttributeOnUnconstrained { ident })
} else if modifiers.attributes.is_foldable() {
Some(ResolverError::NoPredicatesAttributeOnUnconstrained { ident, location })
}
FunctionAttributeKind::Fold => {
let ident = func_meta_name_ident(func, modifiers);
Some(ResolverError::FoldAttributeOnUnconstrained { ident })
} else {
None
Some(ResolverError::FoldAttributeOnUnconstrained { ident, location })
}
} else {
None
FunctionAttributeKind::Foreign(_)
| FunctionAttributeKind::Builtin(_)
| FunctionAttributeKind::Oracle(_)
| FunctionAttributeKind::Test(_)
| FunctionAttributeKind::InlineAlways
| FunctionAttributeKind::FuzzingHarness(_) => None,
}
}

/// Attempting to define new low level (`#[builtin]` or `#[foreign]`) functions outside of the stdlib is disallowed.
pub(super) fn low_level_function_outside_stdlib(
func: &FuncMeta,
modifiers: &FunctionModifiers,
crate_id: CrateId,
) -> Option<ResolverError> {
let is_low_level_function =
modifiers.attributes.function().is_some_and(|func| func.is_low_level());
if !crate_id.is_stdlib() && is_low_level_function {
let ident = func_meta_name_ident(func, modifiers);
Some(ResolverError::LowLevelFunctionOutsideOfStdlib { ident })
if crate_id.is_stdlib() {
return None;
}

let attribute = modifiers.attributes.function()?;
if attribute.kind.is_low_level() {
Some(ResolverError::LowLevelFunctionOutsideOfStdlib { location: attribute.location })
} else {
None
}
Expand All @@ -82,10 +93,15 @@ pub(super) fn oracle_not_marked_unconstrained(
func: &FuncMeta,
modifiers: &FunctionModifiers,
) -> Option<ResolverError> {
let is_oracle_function = modifiers.attributes.function().is_some_and(|func| func.is_oracle());
if is_oracle_function && !modifiers.is_unconstrained {
if modifiers.is_unconstrained {
return None;
}

let attribute = modifiers.attributes.function()?;
if matches!(attribute.kind, FunctionAttributeKind::Oracle(_)) {
let ident = func_meta_name_ident(func, modifiers);
Some(ResolverError::OracleMarkedAsConstrained { ident })
let location = attribute.location;
Some(ResolverError::OracleMarkedAsConstrained { ident, location })
} else {
None
}
Expand All @@ -105,7 +121,7 @@ pub(super) fn oracle_called_from_constrained_function(
}

let function_attributes = interner.function_attributes(called_func);
let is_oracle_call = function_attributes.function().is_some_and(|func| func.is_oracle());
let is_oracle_call = function_attributes.function().is_some_and(|func| func.kind.is_oracle());
if is_oracle_call {
Some(ResolverError::UnconstrainedOracleReturnToConstrained { location })
} else {
Expand Down
17 changes: 10 additions & 7 deletions compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
hir_def::traits::ResolvedTraitBound,
node_interner::GlobalValue,
shared::Signedness,
token::SecondaryAttributeKind,
usage_tracker::UsageTracker,
};
use crate::{
Expand Down Expand Up @@ -47,7 +48,6 @@ use crate::{
ReferenceId, TraitId, TraitImplId, TypeAliasId, TypeId,
},
parser::{ParserError, ParserErrorReason},
token::SecondaryAttribute,
};

mod comptime;
Expand Down Expand Up @@ -1162,8 +1162,7 @@ impl<'context> Elaborator<'context> {
});
self.run_lint(|_| lints::oracle_not_marked_unconstrained(func, modifiers).map(Into::into));
self.run_lint(|elaborator| {
lints::low_level_function_outside_stdlib(func, modifiers, elaborator.crate_id)
.map(Into::into)
lints::low_level_function_outside_stdlib(modifiers, elaborator.crate_id).map(Into::into)
});
}

Expand Down Expand Up @@ -1995,10 +1994,14 @@ impl<'context> Elaborator<'context> {

let location = let_stmt.pattern.location();

if !self.in_contract()
&& let_stmt.attributes.iter().any(|attr| matches!(attr, SecondaryAttribute::Abi(_)))
{
self.push_err(ResolverError::AbiAttributeOutsideContract { location });
if !self.in_contract() {
for attr in &let_stmt.attributes {
if matches!(attr.kind, SecondaryAttributeKind::Abi(_)) {
self.push_err(ResolverError::AbiAttributeOutsideContract {
location: attr.location,
});
}
}
}

if !let_stmt.comptime && matches!(let_stmt.pattern, Pattern::Mutable(..)) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/elaborator/statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl Elaborator<'_> {
}

let warn_if_unused =
!let_stmt.attributes.iter().any(|attr| attr.is_allow_unused_variables());
!let_stmt.attributes.iter().any(|attr| attr.kind.is_allow_unused_variables());

let r#type = annotated_type;
let pattern = self.elaborate_pattern_and_store_ids(
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use crate::{
},
shared::Signedness,
signed_field::SignedField,
token::SecondaryAttribute,
token::SecondaryAttributeKind,
};

use super::{
Expand Down Expand Up @@ -318,7 +318,7 @@ impl Elaborator<'_> {
.interner
.type_attributes(&data_type.borrow().id)
.iter()
.any(|attr| matches!(attr, SecondaryAttribute::Abi(_)))
.any(|attr| matches!(attr.kind, SecondaryAttributeKind::Abi(_)))
{
self.push_err(ResolverError::AbiAttributeOutsideContract {
location: data_type.borrow().name.location(),
Expand Down
Loading
Loading