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

feat: add unsafe blocks for calling unconstrained code from constrained functions #4429

Merged
merged 77 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
2413f4e
feat: add mvp of unsafe blocks
TomAFrench Feb 24, 2024
21b04cf
chore: fix tests
TomAFrench Feb 26, 2024
953b1e8
chore: fix some tests
TomAFrench Feb 26, 2024
ed0b681
chore: add unsafe blocks to tests
TomAFrench Feb 27, 2024
68364fd
chore: fix tests
TomAFrench Feb 27, 2024
32d50f8
chore: track `unsafe` status on `TypeChecker`
TomAFrench Feb 27, 2024
e7cdfeb
chore: small refactor
TomAFrench Feb 27, 2024
6325f92
chore: fix tests
TomAFrench Feb 27, 2024
ef441dd
Merge branch 'master' into tf/unsafe-blocks
TomAFrench Jun 6, 2024
3c89ab7
chore: update elaborator and fix tests
TomAFrench Jun 6, 2024
ff0d1b3
chore: fmt
TomAFrench Jun 6, 2024
94bb836
chore: fix formatter
TomAFrench Jun 7, 2024
6e04e2d
chore: add comment
TomAFrench Jun 7, 2024
c2eab6f
Merge branch 'master' into tf/unsafe-blocks
TomAFrench Jun 20, 2024
0a25b55
Merge branch 'master' into tf/unsafe-blocks
asterite Jul 15, 2024
d56e7d2
Missing is_unsafe
asterite Jul 15, 2024
e280c9e
Remove unused in_unconstrained_fn var
asterite Jul 15, 2024
d9618dc
Improve error message
asterite Jul 15, 2024
8a4c6d7
clippy
asterite Jul 15, 2024
9a034ff
Add a test for unconstrained called outside of unsafe
asterite Jul 15, 2024
feb8ed3
Fix debugger test case
asterite Jul 17, 2024
e6d9ac7
Merge branch 'master' into tf/unsafe-blocks
asterite Jul 17, 2024
83de376
Keep track of unconstrained status of function type, disallow calling…
asterite Jul 17, 2024
0c09df8
`unconstrained fn` and `fn` don't unify
asterite Jul 17, 2024
df13d6c
Can't check unconstrained match on traits and impls yet
asterite Jul 17, 2024
d2469da
Don't parse `unconstrained fn(...) -> ...` yet
asterite Jul 17, 2024
b9664e4
clippy
asterite Jul 17, 2024
995ccb3
Wrap `crate::field::bn254::decompose_hint` in unsafe
asterite Jul 17, 2024
d251fb1
Add a test to show that unconstrained and regular fn can't be put in var
asterite Jul 17, 2024
2910cc5
Parse `unconstrained fn` type and special rule for function call arg …
asterite Jul 17, 2024
35b3cfa
Fixes in test program
asterite Jul 17, 2024
7527020
Format `unconstrained fn` as type
asterite Jul 17, 2024
171288f
nargo fmt
asterite Jul 17, 2024
e8ae6e8
clippy
asterite Jul 17, 2024
d66228c
`fn` to `unconstrained fn` is now a type coercion, and fn calls coerc…
asterite Jul 18, 2024
1e4973f
Fix failing program
asterite Jul 18, 2024
1247917
Unify if branches
asterite Jul 18, 2024
211d120
Only coerce Array to Slice if `as_slice` builtin is defined
asterite Jul 18, 2024
b7c1d85
One more unsafe
asterite Jul 18, 2024
7bdf3bf
nargo fmt
asterite Jul 18, 2024
7081c85
Format
asterite Jul 18, 2024
c065b15
Mention `unsafe` in docs
asterite Jul 18, 2024
84c246c
Apply suggestions from code review
asterite Jul 18, 2024
7b334a5
Introduce an Unsafe block expression instead of a bool in BlockExpres…
asterite Jul 18, 2024
2eebd52
Merge branch 'master' into tf/unsafe-blocks
asterite Jul 22, 2024
1adc679
Fix after merge
asterite Jul 22, 2024
bda7e7c
Don't require semicolon after unsafe statement
asterite Jul 22, 2024
cf26442
Add a couple more unsafe
asterite Jul 22, 2024
e7e687b
Fix format
asterite Jul 22, 2024
b4e8f34
More unsafe
asterite Jul 22, 2024
293c710
nargo fmt
asterite Jul 22, 2024
de12673
More nargo fmt
asterite Jul 22, 2024
f9b6ae0
More formatting
asterite Jul 22, 2024
dfeec2a
Merge branch 'master' into tf/unsafe-blocks
asterite Jul 22, 2024
3432eeb
Merge branch 'master' into tf/unsafe-blocks
asterite Jul 24, 2024
0e07384
Merge branch 'master' into tf/unsafe-blocks
asterite Aug 9, 2024
df281dd
Use unsafe
asterite Aug 9, 2024
828f432
std::unsafe -> std::unsafe_func
asterite Aug 9, 2024
0d92ce1
Fix tests
asterite Aug 12, 2024
ea82c01
Move condition further down the line
asterite Aug 12, 2024
ca52a1a
Simpler `try_fn_to_unconstrained_fn_coercion`
asterite Aug 12, 2024
057438c
Use early returns to avoid too much nesting
asterite Aug 12, 2024
52e02d1
Add a required unsafe
asterite Aug 12, 2024
a0ec872
Incorrect unsafe usage is now a warning
asterite Aug 13, 2024
193b806
Merge branch 'master' into tf/unsafe-blocks
asterite Aug 13, 2024
b06f978
Fixes after merge
asterite Aug 13, 2024
5552d63
More fixes after merge
asterite Aug 13, 2024
adddc9d
cargo fmt
asterite Aug 13, 2024
2d01c5c
Put more unsafes
asterite Aug 13, 2024
7008143
And more
asterite Aug 13, 2024
f5e2a60
And more unsafe
asterite Aug 13, 2024
cf5e3c0
Simplify
asterite Aug 13, 2024
4ef02ff
unsafe_func -> mem
asterite Aug 13, 2024
5aea602
then_some -> then
asterite Aug 13, 2024
c615bb9
nargo fmt
asterite Aug 13, 2024
b88b7c0
Merge branch 'master' into tf/unsafe-blocks
asterite Aug 13, 2024
42d0560
Fix after merge
asterite Aug 14, 2024
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
5 changes: 4 additions & 1 deletion aztec_macros/src/utils/parse_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ fn empty_expression(expression: &mut Expression) {
ExpressionKind::Comptime(block_expression, _span) => {
empty_block_expression(block_expression);
}
ExpressionKind::Unsafe(block_expression, _span) => {
empty_block_expression(block_expression);
}
ExpressionKind::Quote(..) | ExpressionKind::Resolved(_) | ExpressionKind::Error => (),
ExpressionKind::AsTraitPath(path) => {
empty_unresolved_type(&mut path.typ);
Expand Down Expand Up @@ -325,7 +328,7 @@ fn empty_unresolved_type(unresolved_type: &mut UnresolvedType) {
empty_unresolved_type(unresolved_type)
}
UnresolvedTypeData::Tuple(unresolved_types) => empty_unresolved_types(unresolved_types),
UnresolvedTypeData::Function(args, ret, _env) => {
UnresolvedTypeData::Function(args, ret, _env, _) => {
empty_unresolved_types(args);
empty_unresolved_type(ret);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_driver/src/abi_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub(super) fn abi_type_from_hir_type(context: &Context, typ: &Type) -> AbiType {
| Type::Forall(..)
| Type::Quoted(_)
| Type::Slice(_)
| Type::Function(_, _, _) => unreachable!("{typ} cannot be used in the abi"),
| Type::Function(_, _, _, _) => unreachable!("{typ} cannot be used in the abi"),
Type::FmtString(_, _) => unreachable!("format strings cannot be used in the abi"),
Type::MutableReference(_) => unreachable!("&mut cannot be used in the abi"),
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_evaluator/src/ssa/ssa_gen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ impl<'a> FunctionContext<'a> {
}
ast::Type::Unit => panic!("convert_non_tuple_type called on a unit type"),
ast::Type::Tuple(_) => panic!("convert_non_tuple_type called on a tuple: {typ}"),
ast::Type::Function(_, _, _) => Type::Function,
ast::Type::Function(_, _, _, _) => Type::Function,
ast::Type::Slice(_) => panic!("convert_non_tuple_type called on a slice: {typ}"),
ast::Type::MutableReference(element) => {
// Recursive call to panic if element is a tuple
Expand Down
2 changes: 2 additions & 0 deletions compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub enum ExpressionKind {
Quote(Tokens),
Unquote(Box<Expression>),
Comptime(BlockExpression, Span),
Unsafe(BlockExpression, Span),
AsTraitPath(AsTraitPath),

// This variant is only emitted when inlining the result of comptime
Expand Down Expand Up @@ -587,6 +588,7 @@ impl Display for ExpressionKind {
Lambda(lambda) => lambda.fmt(f),
Parenthesized(sub_expr) => write!(f, "({sub_expr})"),
Comptime(block, _) => write!(f, "comptime {block}"),
Unsafe(block, _) => write!(f, "unsafe {block}"),
Error => write!(f, "Error"),
Resolved(_) => write!(f, "?Resolved"),
Unquote(expr) => write!(f, "$({expr})"),
Expand Down
7 changes: 6 additions & 1 deletion compiler/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub enum UnresolvedTypeData {
/*args:*/ Vec<UnresolvedType>,
/*ret:*/ Box<UnresolvedType>,
/*env:*/ Box<UnresolvedType>,
/*unconstrained:*/ bool,
),

/// The type of quoted code for metaprogramming
Expand Down Expand Up @@ -222,7 +223,11 @@ impl std::fmt::Display for UnresolvedTypeData {
Bool => write!(f, "bool"),
String(len) => write!(f, "str<{len}>"),
FormatString(len, elements) => write!(f, "fmt<{len}, {elements}"),
Function(args, ret, env) => {
Function(args, ret, env, unconstrained) => {
if *unconstrained {
write!(f, "unconstrained ")?;
}

let args = vecmap(args, ToString::to_string).join(", ");

match &env.as_ref().typ {
Expand Down
10 changes: 7 additions & 3 deletions compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ impl StatementKind {
StatementKind::Expression(expr) => {
match (&expr.kind, semi, last_statement_in_block) {
// Semicolons are optional for these expressions
(ExpressionKind::Block(_), semi, _) | (ExpressionKind::If(_), semi, _) => {
(ExpressionKind::Block(_), semi, _)
| (ExpressionKind::Unsafe(..), semi, _)
| (ExpressionKind::If(_), semi, _) => {
if semi.is_some() {
StatementKind::Semi(expr)
} else {
Expand Down Expand Up @@ -745,8 +747,10 @@ impl ForRange {
let block = ExpressionKind::Block(BlockExpression {
statements: vec![let_array, for_loop],
});
let kind = StatementKind::Expression(Expression::new(block, for_loop_span));
Statement { kind, span: for_loop_span }
Statement {
kind: StatementKind::Expression(Expression::new(block, for_loop_span)),
span: for_loop_span,
}
}
}
}
Expand Down
24 changes: 18 additions & 6 deletions compiler/noirc_frontend/src/debug/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,9 @@ pub fn build_debug_crate_file() -> String {
__debug_var_assign_oracle(var_id, value);
}
pub fn __debug_var_assign<T>(var_id: u32, value: T) {
__debug_var_assign_inner(var_id, value);
unsafe {{
__debug_var_assign_inner(var_id, value);
}}
}

#[oracle(__debug_var_drop)]
Expand All @@ -502,7 +504,9 @@ pub fn build_debug_crate_file() -> String {
__debug_var_drop_oracle(var_id);
}
pub fn __debug_var_drop(var_id: u32) {
__debug_var_drop_inner(var_id);
unsafe {{
__debug_var_drop_inner(var_id);
}}
}

#[oracle(__debug_fn_enter)]
Expand All @@ -511,7 +515,9 @@ pub fn build_debug_crate_file() -> String {
__debug_fn_enter_oracle(fn_id);
}
pub fn __debug_fn_enter(fn_id: u32) {
__debug_fn_enter_inner(fn_id);
unsafe {{
__debug_fn_enter_inner(fn_id);
}}
}

#[oracle(__debug_fn_exit)]
Expand All @@ -520,7 +526,9 @@ pub fn build_debug_crate_file() -> String {
__debug_fn_exit_oracle(fn_id);
}
pub fn __debug_fn_exit(fn_id: u32) {
__debug_fn_exit_inner(fn_id);
unsafe {{
__debug_fn_exit_inner(fn_id);
}}
}

#[oracle(__debug_dereference_assign)]
Expand All @@ -529,7 +537,9 @@ pub fn build_debug_crate_file() -> String {
__debug_dereference_assign_oracle(var_id, value);
}
pub fn __debug_dereference_assign<T>(var_id: u32, value: T) {
__debug_dereference_assign_inner(var_id, value);
unsafe {{
__debug_dereference_assign_inner(var_id, value);
}}
}
"#
.to_string(),
Expand All @@ -553,7 +563,9 @@ pub fn build_debug_crate_file() -> String {
__debug_oracle_member_assign_{n}(var_id, value, {vars});
}}
pub fn __debug_member_assign_{n}<T, Index>(var_id: u32, value: T, {var_sig}) {{
__debug_inner_member_assign_{n}(var_id, value, {vars});
unsafe {{
__debug_inner_member_assign_{n}(var_id, value, {vars});
}}
}}

"#
Expand Down
18 changes: 17 additions & 1 deletion compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ impl<'context> Elaborator<'context> {
ExpressionKind::Comptime(comptime, _) => {
return self.elaborate_comptime_block(comptime, expr.span)
}
ExpressionKind::Unsafe(block_expression, _) => {
self.elaborate_unsafe_block(block_expression)
}
ExpressionKind::Resolved(id) => return (id, self.interner.id_type(id)),
ExpressionKind::Error => (HirExpression::Error, Type::Error),
ExpressionKind::Unquote(_) => {
Expand Down Expand Up @@ -105,6 +108,19 @@ impl<'context> Elaborator<'context> {
(HirBlockExpression { statements }, block_type)
}

fn elaborate_unsafe_block(&mut self, block: BlockExpression) -> (HirExpression, Type) {
// Before entering the block we cache the old value of `in_unsafe_block` so it can be restored.
let old_in_unsafe_block = self.in_unsafe_block;
self.in_unsafe_block = true;

let (hir_block_expression, typ) = self.elaborate_block_expression(block);

// Finally, we restore the original value of `self.in_unsafe_block`.
self.in_unsafe_block = old_in_unsafe_block;

(HirExpression::Unsafe(hir_block_expression), typ)
}

fn elaborate_literal(&mut self, literal: Literal, span: Span) -> (HirExpression, Type) {
use HirExpression::Literal as Lit;
match literal {
Expand Down Expand Up @@ -710,7 +726,7 @@ impl<'context> Elaborator<'context> {

let captures = lambda_context.captures;
let expr = HirExpression::Lambda(HirLambda { parameters, return_type, body, captures });
(expr, Type::Function(arg_types, Box::new(body_type), Box::new(env_type)))
(expr, Type::Function(arg_types, Box::new(body_type), Box::new(env_type), false))
}

fn elaborate_quote(&mut self, mut tokens: Tokens) -> (HirExpression, Type) {
Expand Down
9 changes: 8 additions & 1 deletion compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ pub struct Elaborator<'context> {

file: FileId,

in_unsafe_block: bool,
nested_loops: usize,

/// Contains a mapping of the current struct or functions's generics to
Expand Down Expand Up @@ -194,6 +195,7 @@ impl<'context> Elaborator<'context> {
interner,
def_maps,
file: FileId::dummy(),
in_unsafe_block: false,
nested_loops: 0,
generics: Vec::new(),
lambda_stack: Vec::new(),
Expand Down Expand Up @@ -802,7 +804,12 @@ impl<'context> Elaborator<'context> {

let return_type = Box::new(self.resolve_type(func.return_type()));

let mut typ = Type::Function(parameter_types, return_type, Box::new(Type::Unit));
let mut typ = Type::Function(
parameter_types,
return_type,
Box::new(Type::Unit),
func.def.is_unconstrained,
);

if !generics.is_empty() {
typ = Type::Forall(generics, Box::new(typ));
Expand Down
13 changes: 10 additions & 3 deletions compiler/noirc_frontend/src/elaborator/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,9 @@ impl<'context> Elaborator<'context> {
};

let no_environment = Box::new(Type::Unit);
// TODO: unconstrained
let function_type =
Type::Function(arguments, Box::new(return_type), no_environment);
Type::Function(arguments, Box::new(return_type), no_environment, false);

functions.push(TraitFunction {
name: name.clone(),
Expand Down Expand Up @@ -345,9 +346,15 @@ fn check_function_type_matches_expected_type(
) {
let mut bindings = TypeBindings::new();
// Shouldn't need to unify envs, they should always be equal since they're both free functions
if let (Type::Function(params_a, ret_a, _env_a), Type::Function(params_b, ret_b, _env_b)) =
(expected, actual)
if let (
Type::Function(params_a, ret_a, _env_a, _unconstrained_a),
Type::Function(params_b, ret_b, _env_b, _unconstrained_b),
) = (expected, actual)
{
// TODO: we don't yet allow marking a trait function or a trait impl function as unconstrained,
// so both values will always be false here. Once we support that, we should check that both
// match (adding a test for it).

if params_a.len() == params_b.len() {
for (i, (a, b)) in params_a.iter().zip(params_b.iter()).enumerate() {
if a.try_unify(b, &mut bindings).is_err() {
Expand Down
36 changes: 25 additions & 11 deletions compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl<'context> Elaborator<'context> {
Tuple(fields) => {
Type::Tuple(vecmap(fields, |field| self.resolve_type_inner(field, kind)))
}
Function(args, ret, env) => {
Function(args, ret, env, unconstrained) => {
let args = vecmap(args, |arg| self.resolve_type_inner(arg, kind));
let ret = Box::new(self.resolve_type_inner(*ret, kind));

Expand All @@ -139,7 +139,7 @@ impl<'context> Elaborator<'context> {

match *env {
Type::Unit | Type::Tuple(_) | Type::NamedGeneric(_, _, _) => {
Type::Function(args, ret, env)
Type::Function(args, ret, env, unconstrained)
}
_ => {
self.push_err(ResolverError::InvalidClosureEnvironment {
Expand Down Expand Up @@ -735,8 +735,8 @@ impl<'context> Elaborator<'context> {
return Type::Error;
}

for (param, (arg, _, arg_span)) in fn_params.iter().zip(callsite_args) {
self.unify(arg, param, || TypeCheckError::TypeMismatch {
for (param, (arg, arg_expr_id, arg_span)) in fn_params.iter().zip(callsite_args) {
self.unify_with_coercions(arg, param, *arg_expr_id, || TypeCheckError::TypeMismatch {
expected_typ: param.to_string(),
expr_typ: arg.to_string(),
expr_span: *arg_span,
Expand All @@ -763,7 +763,8 @@ impl<'context> Elaborator<'context> {
let ret = self.interner.next_type_variable();
let args = vecmap(args, |(arg, _, _)| arg);
let env_type = self.interner.next_type_variable();
let expected = Type::Function(args, Box::new(ret.clone()), Box::new(env_type));
let expected =
Type::Function(args, Box::new(ret.clone()), Box::new(env_type), false);

if let Err(error) = binding.try_bind(expected, span) {
self.push_err(error);
Expand All @@ -772,7 +773,7 @@ impl<'context> Elaborator<'context> {
}
// The closure env is ignored on purpose: call arguments never place
// constraints on closure environments.
Type::Function(parameters, ret, _env) => {
Type::Function(parameters, ret, _env, _unconstrained) => {
self.bind_function_type_impl(&parameters, &ret, &args, span)
}
Type::Error => Type::Error,
Expand Down Expand Up @@ -1128,7 +1129,7 @@ impl<'context> Elaborator<'context> {
let (method_type, mut bindings) = method.typ.clone().instantiate(self.interner);

match method_type {
Type::Function(args, _, _) => {
Type::Function(args, _, _, _) => {
// We can cheat a bit and match against only the object type here since no operator
// overload uses other generic parameters or return types aside from the object type.
let expected_object_type = &args[0];
Expand Down Expand Up @@ -1314,9 +1315,22 @@ impl<'context> Elaborator<'context> {

let is_current_func_constrained = self.in_constrained_function();

let is_unconstrained_call = self.is_unconstrained_call(call.func);
let func_type_is_unconstrained =
if let Type::Function(_args, _ret, _env, unconstrained) = &func_type {
*unconstrained
} else {
false
};

let is_unconstrained_call =
func_type_is_unconstrained || self.is_unconstrained_call(call.func);
let crossing_runtime_boundary = is_current_func_constrained && is_unconstrained_call;
if crossing_runtime_boundary {
if !self.in_unsafe_block {
self.push_err(TypeCheckError::Unsafe { span });
return Type::Error;
}

let called_func_id = self
.interner
.lookup_function_from_expr(&call.func)
Expand Down Expand Up @@ -1373,9 +1387,9 @@ impl<'context> Elaborator<'context> {
object: &mut ExprId,
) {
let expected_object_type = match function_type {
Type::Function(args, _, _) => args.first(),
Type::Function(args, _, _, _) => args.first(),
Type::Forall(_, typ) => match typ.as_ref() {
Type::Function(args, _, _) => args.first(),
Type::Function(args, _, _, _) => args.first(),
typ => unreachable!("Unexpected type for function: {typ}"),
},
typ => unreachable!("Unexpected type for function: {typ}"),
Expand Down Expand Up @@ -1577,7 +1591,7 @@ impl<'context> Elaborator<'context> {
}
}

Type::Function(parameters, return_type, _env) => {
Type::Function(parameters, return_type, _env, _unconstrained) => {
for parameter in parameters {
Self::find_numeric_generics_in_type(parameter, found);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ impl HirExpression {
HirExpression::Comptime(block) => {
ExpressionKind::Comptime(block.to_display_ast(interner), span)
}
HirExpression::Unsafe(block) => {
ExpressionKind::Unsafe(block.to_display_ast(interner), span)
}
HirExpression::Quote(block) => ExpressionKind::Quote(block.clone()),

// A macro was evaluated here: return the quoted result
Expand Down Expand Up @@ -340,11 +343,11 @@ impl Type {
let name = Path::from_single(name.as_ref().clone(), Span::default());
UnresolvedTypeData::TraitAsType(name, Vec::new())
}
Type::Function(args, ret, env) => {
Type::Function(args, ret, env, unconstrained) => {
let args = vecmap(args, |arg| arg.to_display_ast());
let ret = Box::new(ret.to_display_ast());
let env = Box::new(env.to_display_ast());
UnresolvedTypeData::Function(args, ret, env)
UnresolvedTypeData::Function(args, ret, env, *unconstrained)
}
Type::MutableReference(element) => {
let element = Box::new(element.to_display_ast());
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
HirExpression::Lambda(lambda) => self.evaluate_lambda(lambda, id),
HirExpression::Quote(tokens) => self.evaluate_quote(tokens, id),
HirExpression::Comptime(block) => self.evaluate_block(block),
HirExpression::Unsafe(block) => self.evaluate_block(block),
HirExpression::Unquote(tokens) => {
// An Unquote expression being found is indicative of a macro being
// expanded within another comptime fn which we don't currently support.
Expand Down
Loading
Loading