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

fix: always place module attribute generated items inside module #5943

Merged
merged 4 commits into from
Sep 5, 2024
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
81 changes: 67 additions & 14 deletions compiler/noirc_frontend/src/elaborator/comptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
},
dc_mod,
},
def_map::ModuleId,
def_map::{LocalModuleId, ModuleId},
resolution::errors::ResolverError,
},
hir_def::expr::HirIdent,
Expand All @@ -30,6 +30,24 @@ use crate::{

use super::{Elaborator, FunctionContext, ResolverMeta};

#[derive(Debug, Copy, Clone)]
pub(crate) struct AttributeContext {
jfecher marked this conversation as resolved.
Show resolved Hide resolved
// The file where generated items should be added
file: FileId,
// The module where generated items should be added
module: LocalModuleId,
// The file where the attribute is located
attribute_file: FileId,
// The module where the attribute is located
attribute_module: LocalModuleId,
}

impl AttributeContext {
fn new(file: FileId, module: LocalModuleId) -> Self {
Self { file, module, attribute_file: file, attribute_module: module }
}
}

impl<'context> Elaborator<'context> {
/// Elaborate an expression from the middle of a comptime scope.
/// When this happens we require additional information to know
Expand Down Expand Up @@ -94,10 +112,17 @@ impl<'context> Elaborator<'context> {
attributes: &[SecondaryAttribute],
item: Value,
span: Span,
attribute_context: AttributeContext,
generated_items: &mut CollectedItems,
) {
for attribute in attributes {
self.run_comptime_attribute_on_item(attribute, &item, span, generated_items);
self.run_comptime_attribute_on_item(
attribute,
&item,
span,
attribute_context,
generated_items,
);
}
}

Expand All @@ -106,6 +131,7 @@ impl<'context> Elaborator<'context> {
attribute: &SecondaryAttribute,
item: &Value,
span: Span,
attribute_context: AttributeContext,
generated_items: &mut CollectedItems,
) {
if let SecondaryAttribute::Custom(attribute) = attribute {
Expand All @@ -114,6 +140,7 @@ impl<'context> Elaborator<'context> {
item.clone(),
span,
attribute.contents_span,
attribute_context,
generated_items,
) {
self.errors.push(error);
Expand All @@ -127,8 +154,12 @@ impl<'context> Elaborator<'context> {
item: Value,
span: Span,
attribute_span: Span,
attribute_context: AttributeContext,
generated_items: &mut CollectedItems,
) -> Result<(), (CompilationError, FileId)> {
self.file = attribute_context.attribute_file;
self.local_module = attribute_context.attribute_module;

let location = Location::new(attribute_span, self.file);
let Some((function, arguments)) = Self::parse_attribute(attribute, location)? else {
// Do not issue an error if the attribute is unknown
Expand Down Expand Up @@ -156,6 +187,9 @@ impl<'context> Elaborator<'context> {
return Err((ResolverError::NonFunctionInAnnotation { span }.into(), self.file));
};

self.file = attribute_context.file;
self.local_module = attribute_context.module;

let mut interpreter = self.setup_interpreter();
let mut arguments = Self::handle_attribute_arguments(
&mut interpreter,
Expand Down Expand Up @@ -463,18 +497,28 @@ impl<'context> Elaborator<'context> {
let attributes = &trait_.trait_def.attributes;
let item = Value::TraitDefinition(*trait_id);
let span = trait_.trait_def.span;
self.local_module = trait_.module_id;
self.file = trait_.file_id;
self.run_comptime_attributes_on_item(attributes, item, span, &mut generated_items);
let context = AttributeContext::new(trait_.file_id, trait_.module_id);
self.run_comptime_attributes_on_item(
attributes,
item,
span,
context,
&mut generated_items,
);
}

for (struct_id, struct_def) in types {
let attributes = &struct_def.struct_def.attributes;
let item = Value::StructDefinition(*struct_id);
let span = struct_def.struct_def.span;
self.local_module = struct_def.module_id;
self.file = struct_def.file_id;
self.run_comptime_attributes_on_item(attributes, item, span, &mut generated_items);
let context = AttributeContext::new(struct_def.file_id, struct_def.module_id);
self.run_comptime_attributes_on_item(
attributes,
item,
span,
context,
&mut generated_items,
);
}

self.run_attributes_on_functions(functions, &mut generated_items);
Expand All @@ -496,10 +540,14 @@ impl<'context> Elaborator<'context> {
let attribute = &module_attribute.attribute;
let span = Span::default();

self.local_module = module_attribute.attribute_module_id;
self.file = module_attribute.attribute_file_id;
let context = AttributeContext {
file: module_attribute.file_id,
module: module_attribute.module_id,
attribute_file: module_attribute.attribute_file_id,
attribute_module: module_attribute.attribute_module_id,
};

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

Expand All @@ -509,15 +557,20 @@ impl<'context> Elaborator<'context> {
generated_items: &mut CollectedItems,
) {
for function_set in function_sets {
self.file = function_set.file_id;
self.self_type = function_set.self_type.clone();

for (local_module, function_id, function) in &function_set.functions {
self.local_module = *local_module;
let context = AttributeContext::new(function_set.file_id, *local_module);
let attributes = function.secondary_attributes();
let item = Value::FunctionDefinition(*function_id);
let span = function.span();
self.run_comptime_attributes_on_item(attributes, item, span, generated_items);
self.run_comptime_attributes_on_item(
attributes,
item,
span,
context,
generated_items,
);
}
}
}
Expand Down
15 changes: 10 additions & 5 deletions test_programs/compile_success_empty/comptime_module/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#[outer_attribute]
mod foo {
#![some_attribute]
fn x() {}
fn y() {}
pub fn x() {}
pub fn y() {}
}

contract bar {}
Expand All @@ -13,7 +13,7 @@ mod another_module {}
#[outer_attribute_func]
mod yet_another_module {
#![super::inner_attribute_func]
fn foo() {}
pub fn foo() {}
}

#[outer_attribute_separate_module]
Expand All @@ -25,14 +25,16 @@ fn increment_counter() {
counter += 1;
}

fn outer_attribute_func(m: Module) {
fn outer_attribute_func(m: Module) -> Quoted {
assert_eq(m.name(), quote { yet_another_module });
increment_counter();
quote { pub fn generated_outer_function() {} }
}

fn inner_attribute_func(m: Module) {
fn inner_attribute_func(m: Module) -> Quoted {
assert_eq(m.name(), quote { yet_another_module });
increment_counter();
quote { pub fn generated_inner_function() {} }
}

fn outer_attribute_separate_module(m: Module) {
Expand Down Expand Up @@ -68,6 +70,9 @@ fn main() {
}

assert_eq(counter, 4);

yet_another_module::generated_outer_function();
yet_another_module::generated_inner_function();
}

// docs:start:as_module_example
Expand Down
2 changes: 1 addition & 1 deletion tooling/lsp/src/requests/completion/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ pub(super) fn keyword_builtin_type(keyword: &Keyword) -> Option<&'static str> {
Keyword::Expr => Some("Expr"),
Keyword::Field => Some("Field"),
Keyword::FunctionDefinition => Some("FunctionDefinition"),
Keyword::Module => Some("Module"),
Keyword::Quoted => Some("Quoted"),
Keyword::StructDefinition => Some("StructDefinition"),
Keyword::TraitConstraint => Some("TraitConstraint"),
Expand Down Expand Up @@ -128,7 +129,6 @@ pub(super) fn keyword_builtin_type(keyword: &Keyword) -> Option<&'static str> {
| Keyword::In
| Keyword::Let
| Keyword::Mod
| Keyword::Module
| Keyword::Mut
| Keyword::Pub
| Keyword::Return
Expand Down
Loading