Skip to content

Commit

Permalink
Merge 0ebb4c1 into 70ebb90
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Sep 4, 2024
2 parents 70ebb90 + 0ebb4c1 commit 2d41f49
Show file tree
Hide file tree
Showing 25 changed files with 454 additions and 42 deletions.
1 change: 1 addition & 0 deletions aztec_macros/src/utils/parse_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ fn empty_item(item: &mut Item) {
ItemKind::Import(use_tree, _) => empty_use_tree(use_tree),
ItemKind::Struct(noir_struct) => empty_noir_struct(noir_struct),
ItemKind::TypeAlias(noir_type_alias) => empty_noir_type_alias(noir_type_alias),
ItemKind::InnerAttribute(_) => (),
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ pub trait Recoverable {
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ModuleDeclaration {
pub ident: Ident,
pub outer_attributes: Vec<SecondaryAttribute>,
}

impl std::fmt::Display for ModuleDeclaration {
Expand Down
13 changes: 12 additions & 1 deletion compiler/noirc_frontend/src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
QuotedTypeId,
},
parser::{Item, ItemKind, ParsedSubModule},
token::Tokens,
token::{SecondaryAttribute, Tokens},
ParsedModule, QuotedType,
};

Expand Down Expand Up @@ -432,6 +432,8 @@ pub trait Visitor {
fn visit_struct_pattern(&mut self, _: &Path, _: &[(Ident, Pattern)], _: Span) -> bool {
true
}

fn visit_secondary_attribute(&mut self, _: &SecondaryAttribute, _: Span) {}
}

impl ParsedModule {
Expand Down Expand Up @@ -481,6 +483,9 @@ impl Item {
ItemKind::ModuleDecl(module_declaration) => {
module_declaration.accept(self.span, visitor);
}
ItemKind::InnerAttribute(attribute) => {
attribute.accept(self.span, visitor);
}
}
}
}
Expand Down Expand Up @@ -1289,6 +1294,12 @@ impl Pattern {
}
}

impl SecondaryAttribute {
pub fn accept(&self, span: Span, visitor: &mut impl Visitor) {
visitor.visit_secondary_attribute(self, span);
}
}

fn visit_expressions(expressions: &[Expression], visitor: &mut impl Visitor) {
for expression in expressions {
expression.accept(visitor);
Expand Down
63 changes: 49 additions & 14 deletions compiler/noirc_frontend/src/elaborator/comptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ use crate::{
comptime::{Interpreter, InterpreterError, Value},
def_collector::{
dc_crate::{
CollectedItems, CompilationError, UnresolvedFunctions, UnresolvedStruct,
UnresolvedTrait, UnresolvedTraitImpl,
CollectedItems, CompilationError, ModuleAttribute, UnresolvedFunctions,
UnresolvedStruct, UnresolvedTrait, UnresolvedTraitImpl,
},
dc_mod,
},
def_map::ModuleId,
resolution::errors::ResolverError,
},
hir_def::expr::HirIdent,
Expand Down Expand Up @@ -96,21 +97,31 @@ impl<'context> Elaborator<'context> {
generated_items: &mut CollectedItems,
) {
for attribute in attributes {
if let SecondaryAttribute::Custom(attribute) = attribute {
if let Err(error) = self.run_comptime_attribute_on_item(
&attribute.contents,
item.clone(),
span,
attribute.contents_span,
generated_items,
) {
self.errors.push(error);
}
}
self.run_comptime_attribute_on_item(attribute, &item, span, generated_items);
}
}

fn run_comptime_attribute_on_item(
&mut self,
attribute: &SecondaryAttribute,
item: &Value,
span: Span,
generated_items: &mut CollectedItems,
) {
if let SecondaryAttribute::Custom(attribute) = attribute {
if let Err(error) = self.run_comptime_attribute_name_on_item(
&attribute.contents,
item.clone(),
span,
attribute.contents_span,
generated_items,
) {
self.errors.push(error);
}
}
}

fn run_comptime_attribute_name_on_item(
&mut self,
attribute: &str,
item: Value,
Expand Down Expand Up @@ -383,7 +394,8 @@ impl<'context> Elaborator<'context> {
| TopLevelStatement::Trait(_)
| TopLevelStatement::Impl(_)
| TopLevelStatement::TypeAlias(_)
| TopLevelStatement::SubModule(_) => {
| TopLevelStatement::SubModule(_)
| TopLevelStatement::InnerAttribute(_) => {
let item = item.to_string();
let error = InterpreterError::UnsupportedTopLevelItemUnquote { item, location };
self.errors.push(error.into_compilation_error_pair());
Expand Down Expand Up @@ -422,6 +434,7 @@ impl<'context> Elaborator<'context> {
traits: &BTreeMap<TraitId, UnresolvedTrait>,
types: &BTreeMap<StructId, UnresolvedStruct>,
functions: &[UnresolvedFunctions],
module_attributes: &[ModuleAttribute],
) -> CollectedItems {
let mut generated_items = CollectedItems::default();

Expand All @@ -444,9 +457,31 @@ impl<'context> Elaborator<'context> {
}

self.run_attributes_on_functions(functions, &mut generated_items);

self.run_attributes_on_modules(module_attributes, &mut generated_items);

generated_items
}

fn run_attributes_on_modules(
&mut self,
module_attributes: &[ModuleAttribute],
generated_items: &mut CollectedItems,
) {
for module_attribute in module_attributes {
let local_id = module_attribute.module_id;
let module_id = ModuleId { krate: self.crate_id, local_id };
let item = Value::ModuleDefinition(module_id);
let attribute = &module_attribute.attribute;
let span = Span::default();

self.local_module = module_attribute.attribute_module_id;
self.file = module_attribute.attribute_file_id;

self.run_comptime_attribute_on_item(attribute, &item, span, generated_items);
}
}

fn run_attributes_on_functions(
&mut self,
function_sets: &[UnresolvedFunctions],
Expand Down
7 changes: 6 additions & 1 deletion compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,12 @@ impl<'context> Elaborator<'context> {

// We have to run any comptime attributes on functions before the function is elaborated
// since the generated items are checked beforehand as well.
let generated_items = self.run_attributes(&items.traits, &items.types, &items.functions);
let generated_items = self.run_attributes(
&items.traits,
&items.types,
&items.functions,
&items.module_attributes,
);

// After everything is collected, we can elaborate our generated items.
// It may be better to inline these within `items` entirely since elaborating them
Expand Down
33 changes: 33 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ impl<'local, 'context> Interpreter<'local, 'context> {
function_def_set_return_type(self, arguments, location)
}
"module_functions" => module_functions(self, arguments, location),
"module_has_named_attribute" => module_has_named_attribute(self, arguments, location),
"module_is_contract" => module_is_contract(self, arguments, location),
"module_name" => module_name(interner, arguments, location),
"modulus_be_bits" => modulus_be_bits(interner, arguments, location),
Expand Down Expand Up @@ -1816,6 +1817,38 @@ fn module_functions(
Ok(Value::Slice(func_ids, slice_type))
}

// fn has_named_attribute(self, name: Quoted) -> bool
fn module_has_named_attribute(
interpreter: &Interpreter,
arguments: Vec<(Value, Location)>,
location: Location,
) -> IResult<Value> {
let (self_argument, name) = check_two_arguments(arguments, location)?;
let module_id = get_module(self_argument)?;
let module_data = interpreter.elaborator.get_module(module_id);
let name = get_quoted(name)?;

let name = name.iter().map(|token| token.to_string()).collect::<Vec<_>>().join("");

let attributes = module_data.outer_attributes.iter().chain(&module_data.inner_attributes);
for attribute in attributes {
let parse_result = Elaborator::parse_attribute(attribute, location);
let Ok(Some((function, _arguments))) = parse_result else {
continue;
};

let ExpressionKind::Variable(path) = function.kind else {
continue;
};

if path.last_name() == name {
return Ok(Value::Bool(true));
}
}

Ok(Value::Bool(false))
}

// fn is_contract(self) -> bool
fn module_is_contract(
interpreter: &Interpreter,
Expand Down
8 changes: 7 additions & 1 deletion compiler/noirc_frontend/src/hir/comptime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ fn interpret_helper(src: &str) -> Result<Value, InterpreterError> {
let module_id = LocalModuleId(Index::unsafe_zeroed());
let mut modules = noirc_arena::Arena::default();
let location = Location::new(Default::default(), file);
let root = LocalModuleId(modules.insert(ModuleData::new(None, location, false)));
let root = LocalModuleId(modules.insert(ModuleData::new(
None,
location,
Vec::new(),
Vec::new(),
false,
)));
assert_eq!(root, module_id);

let file_manager = FileManager::new(&PathBuf::new());
Expand Down
18 changes: 18 additions & 0 deletions compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleId};
use crate::hir::resolution::errors::ResolverError;
use crate::hir::resolution::path_resolver;
use crate::hir::type_check::TypeCheckError;
use crate::token::SecondaryAttribute;
use crate::{Generics, Type};

use crate::hir::resolution::import::{resolve_import, ImportDirective, PathResolution};
Expand Down Expand Up @@ -111,6 +112,21 @@ pub struct UnresolvedGlobal {
pub stmt_def: LetStatement,
}

pub struct ModuleAttribute {
// The file in which the module is defined
pub file_id: FileId,
// The module this attribute is attached to
pub module_id: LocalModuleId,
// The file where the attribute exists (it could be the same as `file_id`
// or a different one if it's an inner attribute in a different file)
pub attribute_file_id: FileId,
// The module where the attribute is defined (similar to `attribute_file_id`,
// it could be different than `module_id` for inner attributes)
pub attribute_module_id: LocalModuleId,
pub attribute: SecondaryAttribute,
pub is_inner: bool,
}

/// Given a Crate root, collect all definitions in that crate
pub struct DefCollector {
pub(crate) def_map: CrateDefMap,
Expand All @@ -127,6 +143,7 @@ pub struct CollectedItems {
pub globals: Vec<UnresolvedGlobal>,
pub(crate) impls: ImplMap,
pub(crate) trait_impls: Vec<UnresolvedTraitImpl>,
pub(crate) module_attributes: Vec<ModuleAttribute>,
}

impl CollectedItems {
Expand Down Expand Up @@ -238,6 +255,7 @@ impl DefCollector {
impls: HashMap::default(),
globals: vec![],
trait_impls: vec![],
module_attributes: vec![],
},
}
}
Expand Down
Loading

0 comments on commit 2d41f49

Please sign in to comment.