Skip to content

Commit

Permalink
fix: 'cannot eval non-comptime global' error (#5586)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves an issue where if we call into a non-comptime function in
another crate like the stdlib, the functions there could not reference
any globals.

## Summary\*



## Additional Context

This will be tested as part of the future larger `derive` test. It's a
bit awkward making a test for this individually.

## 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.

---------

Co-authored-by: Michael J Klein <[email protected]>
  • Loading branch information
jfecher and michaeljklein authored Jul 23, 2024
1 parent b85e764 commit 0a987c7
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 4 deletions.
1 change: 1 addition & 0 deletions aztec_macros/src/utils/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ pub fn inject_global(
let global_id = context.def_interner.push_empty_global(
name.clone(),
module_id,
*crate_id,
file_id,
global.attributes.clone(),
false,
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1608,6 +1608,7 @@ impl<'context> Elaborator<'context> {
global,
self.file,
self.local_module,
self.crate_id,
);

generated_items.globals.push(global);
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,6 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
Err(InterpreterError::VariableNotInScope { location })
} else {
let name = self.elaborator.interner.definition_name(id).to_string();
eprintln!("{name} not in scope");
Err(InterpreterError::NonComptimeVarReferenced { name, location })
}
}
Expand Down Expand Up @@ -408,6 +407,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
if let Ok(value) = self.lookup(&ident) {
Ok(value)
} else {
let crate_of_global = self.elaborator.interner.get_global(*global_id).crate_id;
let let_ =
self.elaborator.interner.get_global_let_statement(*global_id).ok_or_else(
|| {
Expand All @@ -416,7 +416,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
},
)?;

if let_.comptime {
if let_.comptime || crate_of_global != self.crate_id {
self.evaluate_let(let_.clone())?;
}
self.lookup(&ident)
Expand Down
7 changes: 6 additions & 1 deletion compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub fn collect_defs(
});
}

errors.extend(collector.collect_globals(context, ast.globals));
errors.extend(collector.collect_globals(context, ast.globals, crate_id));

errors.extend(collector.collect_traits(context, ast.traits, crate_id));

Expand All @@ -106,6 +106,7 @@ impl<'a> ModCollector<'a> {
&mut self,
context: &mut Context,
globals: Vec<LetStatement>,
crate_id: CrateId,
) -> Vec<(CompilationError, fm::FileId)> {
let mut errors = vec![];
for global in globals {
Expand All @@ -115,6 +116,7 @@ impl<'a> ModCollector<'a> {
global,
self.file_id,
self.module_id,
crate_id,
);

if let Some(error) = error {
Expand Down Expand Up @@ -492,6 +494,7 @@ impl<'a> ModCollector<'a> {
let global_id = context.def_interner.push_empty_global(
name.clone(),
trait_id.0.local_id,
krate,
self.file_id,
vec![],
false,
Expand Down Expand Up @@ -862,12 +865,14 @@ pub(crate) fn collect_global(
global: LetStatement,
file_id: FileId,
module_id: LocalModuleId,
crate_id: CrateId,
) -> (UnresolvedGlobal, Option<(CompilationError, FileId)>) {
let name = global.pattern.name_ident().clone();

let global_id = interner.push_empty_global(
name.clone(),
module_id,
crate_id,
file_id,
global.attributes.clone(),
matches!(global.pattern, Pattern::Mutable { .. }),
Expand Down
8 changes: 7 additions & 1 deletion compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ pub struct GlobalInfo {
pub definition_id: DefinitionId,
pub ident: Ident,
pub local_id: LocalModuleId,
pub crate_id: CrateId,
pub location: Location,
pub let_statement: StmtId,
pub value: Option<comptime::Value>,
Expand Down Expand Up @@ -756,6 +757,7 @@ impl NodeInterner {
&mut self,
ident: Ident,
local_id: LocalModuleId,
crate_id: CrateId,
let_statement: StmtId,
file: FileId,
attributes: Vec<SecondaryAttribute>,
Expand All @@ -773,6 +775,7 @@ impl NodeInterner {
definition_id,
ident,
local_id,
crate_id,
let_statement,
location,
value: None,
Expand All @@ -786,18 +789,21 @@ impl NodeInterner {
}

/// Intern an empty global. Used for collecting globals before they're defined
#[allow(clippy::too_many_arguments)]
pub fn push_empty_global(
&mut self,
name: Ident,
local_id: LocalModuleId,
crate_id: CrateId,
file: FileId,
attributes: Vec<SecondaryAttribute>,
mutable: bool,
comptime: bool,
) -> GlobalId {
let statement = self.push_stmt(HirStatement::Error);
let span = name.span();
let id = self.push_global(name, local_id, statement, file, attributes, mutable, comptime);
let id = self
.push_global(name, local_id, crate_id, statement, file, attributes, mutable, comptime);
self.push_stmt_location(statement, span, file);
id
}
Expand Down

0 comments on commit 0a987c7

Please sign in to comment.