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
28 changes: 24 additions & 4 deletions compiler/noirc_frontend/src/elaborator/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use crate::{
expr::{HirExpression, HirIdent, HirMethodReference, ImplKind, TraitMethod},
stmt::HirPattern,
},
node_interner::{DefinitionId, DefinitionKind, ExprId, FuncId, GlobalId, TraitImplKind},
node_interner::{
DefinitionId, DefinitionInfo, DefinitionKind, ExprId, FuncId, GlobalId, TraitImplKind,
},
};

use super::{Elaborator, ResolverMeta, path_resolution::PathResolutionItem};
Expand Down Expand Up @@ -542,8 +544,10 @@ impl Elaborator<'_> {

let type_generics = item.map(|item| self.resolve_item_turbofish(item)).unwrap_or_default();

let definition_kind =
self.interner.try_definition(definition_id).map(|definition| definition.kind.clone());
let definition = self.interner.try_definition(definition_id);
let is_comptime_local = !self.in_comptime_context()
&& definition.is_some_and(DefinitionInfo::is_comptime_local);
let definition_kind = definition.as_ref().map(|definition| definition.kind.clone());

let mut bindings = TypeBindings::new();

Expand Down Expand Up @@ -574,7 +578,23 @@ impl Elaborator<'_> {
let typ = self.type_check_variable_with_bindings(expr, id, generics, bindings);
self.interner.push_expr_type(id, typ.clone());

(id, typ)
// If this variable it a comptime local variable, use its current value as the final expression
if is_comptime_local {
let mut interpreter = self.setup_interpreter();
let value = interpreter.evaluate(id);
// If the value is an error it means the variable already had an error, so don't report it here again
// (the error will make no sense, it will say that a non-comptime variable was referenced at runtime
// but that's not true)
if value.is_ok() {
let (id, typ) = self.inline_comptime_value(value, location);
self.debug_comptime(location, |interner| id.to_display_ast(interner).kind);
(id, typ)
} else {
(id, typ)
}
} else {
(id, typ)
}
}

/// Solve any generics that are part of the path before the function, for example:
Expand Down
4 changes: 4 additions & 0 deletions compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,12 @@
interned_statement_kinds: noirc_arena::Arena<StatementKind>,

// Interned `UnresolvedTypeData`s during comptime code.
interned_unresolved_type_datas: noirc_arena::Arena<UnresolvedTypeData>,

Check warning on line 219 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (datas)

// Interned `Pattern`s during comptime code.
interned_patterns: noirc_arena::Arena<Pattern>,

/// Determins whether to run in LSP mode. In LSP mode references are tracked.

Check warning on line 224 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (Determins)
pub(crate) lsp_mode: bool,

/// Store the location of the references in the graph.
Expand Down Expand Up @@ -573,6 +573,10 @@
pub fn is_global(&self) -> bool {
self.kind.is_global()
}

pub fn is_comptime_local(&self) -> bool {
self.comptime && matches!(self.kind, DefinitionKind::Local(..))
}
}

#[derive(Debug, Clone, Eq, PartialEq)]
Expand Down Expand Up @@ -697,7 +701,7 @@
quoted_types: Default::default(),
interned_expression_kinds: Default::default(),
interned_statement_kinds: Default::default(),
interned_unresolved_type_datas: Default::default(),

Check warning on line 704 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (datas)
interned_patterns: Default::default(),
lsp_mode: false,
location_indices: LocationIndices::default(),
Expand Down Expand Up @@ -2184,11 +2188,11 @@
&mut self,
typ: UnresolvedTypeData,
) -> InternedUnresolvedTypeData {
InternedUnresolvedTypeData(self.interned_unresolved_type_datas.insert(typ))

Check warning on line 2191 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (datas)
}

pub fn get_unresolved_type_data(&self, id: InternedUnresolvedTypeData) -> &UnresolvedTypeData {
&self.interned_unresolved_type_datas[id.0]

Check warning on line 2195 in compiler/noirc_frontend/src/node_interner.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (datas)
}

/// Returns the type of an operator (which is always a function), along with its return type.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "comptime_variable_at_runtime"
type = "bin"
authors = [""]

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn main() {
comptime let mut x = 1;

println(x); // prints 1

comptime {
x += 1;
}

println(x); // prints 2
}
Loading