Skip to content

Commit

Permalink
fix: Elaborate struct & trait annotations in the correct module (#5643)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

## Summary\*

Elaborates trait & struct annotations in the correct module.
We also save & restore type variables before elaborating items from the
interpreter. Otherwise this infers with checks that trait impls do not
overlap.

## Additional Context

This is necessary for `derive` to work in the stdlib. This will be
tested against regressions in the future as part of the PR adding
`derive` in the stdlib.

## 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 Aug 2, 2024
1 parent e00c370 commit d0a957b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
4 changes: 4 additions & 0 deletions compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1625,13 +1625,17 @@ 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);
}

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);
}

Expand Down
21 changes: 15 additions & 6 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
Some(body) => Ok(body),
None => {
if matches!(&meta.function_body, FunctionBody::Unresolved(..)) {
self.elaborator.elaborate_item_from_comptime(None, |elaborator| {
self.elaborate_item(None, |elaborator| {
elaborator.elaborate_function(function);
});

Expand All @@ -179,6 +179,17 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
}
}

fn elaborate_item<T>(
&mut self,
function: Option<FuncId>,
f: impl FnOnce(&mut Elaborator) -> T,
) -> T {
self.unbind_generics_from_previous_function();
let result = self.elaborator.elaborate_item_from_comptime(function, f);
self.rebind_generics_from_previous_function();
result
}

fn call_special(
&mut self,
function: FuncId,
Expand Down Expand Up @@ -1236,11 +1247,9 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
let mut result = self.call_function(function_id, arguments, bindings, location)?;
if call.is_macro_call {
let expr = result.into_expression(self.elaborator.interner, location)?;
let expr = self
.elaborator
.elaborate_item_from_comptime(self.current_function, |elab| {
elab.elaborate_expression(expr).0
});
let expr = self.elaborate_item(self.current_function, |elaborator| {
elaborator.elaborate_expression(expr).0
});
result = self.evaluate(expr)?;
}
Ok(result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,7 @@ fn quoted_as_trait_constraint(
})?;

let bound = interpreter
.elaborator
.elaborate_item_from_comptime(interpreter.current_function, |elaborator| {
.elaborate_item(interpreter.current_function, |elaborator| {
elaborator.resolve_trait_bound(&trait_bound, Type::Unit)
})
.ok_or(InterpreterError::FailedToResolveTraitBound { trait_bound, location })?;
Expand All @@ -429,9 +428,8 @@ fn quoted_as_type(
InterpreterError::FailedToParseMacro { error, tokens, rule, file: location.file }
})?;

let typ = interpreter
.elaborator
.elaborate_item_from_comptime(interpreter.current_function, |elab| elab.resolve_type(typ));
let typ =
interpreter.elaborate_item(interpreter.current_function, |elab| elab.resolve_type(typ));

Ok(Value::Type(typ))
}
Expand Down

0 comments on commit d0a957b

Please sign in to comment.