Skip to content

Commit e3313e9

Browse files
committed
Make comptime elaboration take an optional reason
1 parent 49a3fab commit e3313e9

File tree

3 files changed

+90
-87
lines changed

3 files changed

+90
-87
lines changed

compiler/noirc_frontend/src/elaborator/comptime.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ impl<'context> Elaborator<'context> {
4949
pub fn elaborate_item_from_comptime_in_function<'a, T>(
5050
&'a mut self,
5151
current_function: Option<FuncId>,
52+
reason: Option<ElaborateReason>,
5253
f: impl FnOnce(&mut Elaborator<'a>) -> T,
5354
) -> T {
54-
self.elaborate_item_from_comptime(f, |elaborator| {
55+
self.elaborate_item_from_comptime(reason, f, |elaborator| {
5556
if let Some(function) = current_function {
5657
let meta = elaborator.interner.function_meta(&function);
5758
elaborator.current_item = Some(DependencyId::Function(function));
@@ -65,9 +66,10 @@ impl<'context> Elaborator<'context> {
6566
pub fn elaborate_item_from_comptime_in_module<'a, T>(
6667
&'a mut self,
6768
module: ModuleId,
69+
reason: Option<ElaborateReason>,
6870
f: impl FnOnce(&mut Elaborator<'a>) -> T,
6971
) -> T {
70-
self.elaborate_item_from_comptime(f, |elaborator| {
72+
self.elaborate_item_from_comptime(reason, f, |elaborator| {
7173
elaborator.current_item = None;
7274
elaborator.crate_id = module.krate;
7375
elaborator.local_module = module.local_id;
@@ -76,6 +78,7 @@ impl<'context> Elaborator<'context> {
7678

7779
fn elaborate_item_from_comptime<'a, T>(
7880
&'a mut self,
81+
reason: Option<ElaborateReason>,
7982
f: impl FnOnce(&mut Elaborator<'a>) -> T,
8083
setup: impl FnOnce(&mut Elaborator<'a>),
8184
) -> T {
@@ -104,7 +107,14 @@ impl<'context> Elaborator<'context> {
104107
let result = f(&mut elaborator);
105108
elaborator.check_and_pop_function_context();
106109

107-
self.errors.append(&mut elaborator.errors);
110+
let mut errors = std::mem::take(&mut elaborator.errors);
111+
if let Some(reason) = reason {
112+
errors = vecmap(errors, |error| {
113+
CompilationError::ComptimeError(reason.to_macro_error(error))
114+
});
115+
};
116+
117+
self.errors.extend(errors);
108118
result
109119
}
110120

@@ -346,7 +356,7 @@ impl<'context> Elaborator<'context> {
346356
for item in items {
347357
elaborator.add_item(item, generated_items, location);
348358
}
349-
})
359+
});
350360
}
351361

352362
pub(crate) fn add_item(
@@ -557,7 +567,7 @@ impl<'context> Elaborator<'context> {
557567
if !generated_items.is_empty() {
558568
let reason = ElaborateReason::RunningAttribute(location);
559569
self.with_elaborate_reason(reason, |elaborator| {
560-
elaborator.elaborate_items(generated_items)
570+
elaborator.elaborate_items(generated_items);
561571
});
562572
}
563573
}

compiler/noirc_frontend/src/hir/comptime/interpreter.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_hash::FxHashMap as HashMap;
1010

1111
use crate::TypeVariable;
1212
use crate::ast::{BinaryOpKind, FunctionKind, IntegerBitSize, Signedness, UnaryOp};
13-
use crate::elaborator::Elaborator;
13+
use crate::elaborator::{ElaborateReason, Elaborator};
1414
use crate::graph::CrateId;
1515
use crate::hir::def_map::ModuleId;
1616
use crate::hir::type_check::TypeCheckError;
@@ -191,7 +191,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
191191
Some(body) => Ok(body),
192192
None => {
193193
if matches!(&meta.function_body, FunctionBody::Unresolved(..)) {
194-
self.elaborate_in_function(None, |elaborator| {
194+
self.elaborate_in_function(None, None, |elaborator| {
195195
elaborator.elaborate_function(function);
196196
});
197197

@@ -207,21 +207,23 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
207207
fn elaborate_in_function<T>(
208208
&mut self,
209209
function: Option<FuncId>,
210+
reason: Option<ElaborateReason>,
210211
f: impl FnOnce(&mut Elaborator) -> T,
211212
) -> T {
212213
self.unbind_generics_from_previous_function();
213-
let result = self.elaborator.elaborate_item_from_comptime_in_function(function, f);
214+
let result = self.elaborator.elaborate_item_from_comptime_in_function(function, reason, f);
214215
self.rebind_generics_from_previous_function();
215216
result
216217
}
217218

218219
fn elaborate_in_module<T>(
219220
&mut self,
220221
module: ModuleId,
222+
reason: Option<ElaborateReason>,
221223
f: impl FnOnce(&mut Elaborator) -> T,
222224
) -> T {
223225
self.unbind_generics_from_previous_function();
224-
let result = self.elaborator.elaborate_item_from_comptime_in_module(module, f);
226+
let result = self.elaborator.elaborate_item_from_comptime_in_module(module, reason, f);
225227
self.rebind_generics_from_previous_function();
226228
result
227229
}
@@ -1325,9 +1327,10 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
13251327
let mut result = self.call_function(function_id, arguments, bindings, location)?;
13261328
if call.is_macro_call {
13271329
let expr = result.into_expression(self.elaborator, location)?;
1328-
let expr = self.elaborate_in_function(self.current_function, |elaborator| {
1329-
elaborator.elaborate_expression(expr).0
1330-
});
1330+
let expr =
1331+
self.elaborate_in_function(self.current_function, None, |elaborator| {
1332+
elaborator.elaborate_expression(expr).0
1333+
});
13311334
result = self.evaluate(expr)?;
13321335

13331336
// Macro calls are typed as type variables during type checking.

compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs

+65-75
Original file line numberDiff line numberDiff line change
@@ -833,12 +833,10 @@ fn quoted_as_module(
833833
parse(interpreter.elaborator, argument, Parser::parse_path_no_turbofish_or_error, "a path")
834834
.ok();
835835
let option_value = path.and_then(|path| {
836+
let reason = Some(ElaborateReason::EvaluatingComptimeCall("Quoted::as_module", location));
836837
let module =
837-
interpreter.elaborate_in_function(interpreter.current_function, |elaborator| {
838-
let reason = ElaborateReason::EvaluatingComptimeCall("Quoted::as_module", location);
839-
elaborator.with_elaborate_reason(reason, |elaborator| {
840-
elaborator.resolve_module_by_path(path)
841-
})
838+
interpreter.elaborate_in_function(interpreter.current_function, reason, |elaborator| {
839+
elaborator.resolve_module_by_path(path)
842840
});
843841
module.map(Value::ModuleDefinition)
844842
});
@@ -859,13 +857,11 @@ fn quoted_as_trait_constraint(
859857
Parser::parse_trait_bound_or_error,
860858
"a trait constraint",
861859
)?;
860+
let reason =
861+
Some(ElaborateReason::EvaluatingComptimeCall("Quoted::as_trait_constraint", location));
862862
let bound = interpreter
863-
.elaborate_in_function(interpreter.current_function, |elaborator| {
864-
let reason =
865-
ElaborateReason::EvaluatingComptimeCall("Quoted::as_trait_constraint", location);
866-
elaborator.with_elaborate_reason(reason, |elaborator| {
867-
elaborator.resolve_trait_bound(&trait_bound)
868-
})
863+
.elaborate_in_function(interpreter.current_function, reason, |elaborator| {
864+
elaborator.resolve_trait_bound(&trait_bound)
869865
})
870866
.ok_or(InterpreterError::FailedToResolveTraitBound { trait_bound, location })?;
871867

@@ -880,10 +876,11 @@ fn quoted_as_type(
880876
) -> IResult<Value> {
881877
let argument = check_one_argument(arguments, location)?;
882878
let typ = parse(interpreter.elaborator, argument, Parser::parse_type_or_error, "a type")?;
883-
let typ = interpreter.elaborate_in_function(interpreter.current_function, |elaborator| {
884-
let reason = ElaborateReason::EvaluatingComptimeCall("Quoted::as_type", location);
885-
elaborator.with_elaborate_reason(reason, |elaborator| elaborator.resolve_type(typ))
886-
});
879+
let reason = Some(ElaborateReason::EvaluatingComptimeCall("Quoted::as_type", location));
880+
let typ =
881+
interpreter.elaborate_in_function(interpreter.current_function, reason, |elaborator| {
882+
elaborator.resolve_type(typ)
883+
});
887884
Ok(Value::Type(typ))
888885
}
889886

@@ -2301,37 +2298,34 @@ fn expr_resolve(
23012298
interpreter.current_function
23022299
};
23032300

2304-
interpreter.elaborate_in_function(function_to_resolve_in, |elaborator| {
2305-
let reason = ElaborateReason::EvaluatingComptimeCall("Expr::resolve", location);
2306-
elaborator.with_elaborate_reason(reason, |elaborator| match expr_value {
2307-
ExprValue::Expression(expression_kind) => {
2308-
let expr = Expression { kind: expression_kind, location: self_argument_location };
2309-
let (expr_id, _) = elaborator.elaborate_expression(expr);
2310-
Ok(Value::TypedExpr(TypedExpr::ExprId(expr_id)))
2311-
}
2312-
ExprValue::Statement(statement_kind) => {
2313-
let statement =
2314-
Statement { kind: statement_kind, location: self_argument_location };
2315-
let (stmt_id, _) = elaborator.elaborate_statement(statement);
2316-
Ok(Value::TypedExpr(TypedExpr::StmtId(stmt_id)))
2317-
}
2318-
ExprValue::LValue(lvalue) => {
2319-
let expr = lvalue.as_expression();
2320-
let (expr_id, _) = elaborator.elaborate_expression(expr);
2301+
let reason = Some(ElaborateReason::EvaluatingComptimeCall("Expr::resolve", location));
2302+
interpreter.elaborate_in_function(function_to_resolve_in, reason, |elaborator| match expr_value
2303+
{
2304+
ExprValue::Expression(expression_kind) => {
2305+
let expr = Expression { kind: expression_kind, location: self_argument_location };
2306+
let (expr_id, _) = elaborator.elaborate_expression(expr);
2307+
Ok(Value::TypedExpr(TypedExpr::ExprId(expr_id)))
2308+
}
2309+
ExprValue::Statement(statement_kind) => {
2310+
let statement = Statement { kind: statement_kind, location: self_argument_location };
2311+
let (stmt_id, _) = elaborator.elaborate_statement(statement);
2312+
Ok(Value::TypedExpr(TypedExpr::StmtId(stmt_id)))
2313+
}
2314+
ExprValue::LValue(lvalue) => {
2315+
let expr = lvalue.as_expression();
2316+
let (expr_id, _) = elaborator.elaborate_expression(expr);
2317+
Ok(Value::TypedExpr(TypedExpr::ExprId(expr_id)))
2318+
}
2319+
ExprValue::Pattern(pattern) => {
2320+
if let Some(expression) = pattern.try_as_expression(elaborator.interner) {
2321+
let (expr_id, _) = elaborator.elaborate_expression(expression);
23212322
Ok(Value::TypedExpr(TypedExpr::ExprId(expr_id)))
2323+
} else {
2324+
let expression = Value::pattern(pattern).display(elaborator.interner).to_string();
2325+
let location = self_argument_location;
2326+
Err(InterpreterError::CannotResolveExpression { location, expression })
23222327
}
2323-
ExprValue::Pattern(pattern) => {
2324-
if let Some(expression) = pattern.try_as_expression(elaborator.interner) {
2325-
let (expr_id, _) = elaborator.elaborate_expression(expression);
2326-
Ok(Value::TypedExpr(TypedExpr::ExprId(expr_id)))
2327-
} else {
2328-
let expression =
2329-
Value::pattern(pattern).display(elaborator.interner).to_string();
2330-
let location = self_argument_location;
2331-
Err(InterpreterError::CannotResolveExpression { location, expression })
2332-
}
2333-
}
2334-
})
2328+
}
23352329
})
23362330
}
23372331

@@ -2440,13 +2434,14 @@ fn function_def_as_typed_expr(
24402434
let hir_expr = HirExpression::Ident(hir_ident.clone(), generics.clone());
24412435
let expr_id = interpreter.elaborator.interner.push_expr(hir_expr);
24422436
interpreter.elaborator.interner.push_expr_location(expr_id, location);
2443-
let typ = interpreter.elaborate_in_function(interpreter.current_function, |elaborator| {
2444-
let reason =
2445-
ElaborateReason::EvaluatingComptimeCall("FunctionDefinition::as_typed_expr", location);
2446-
elaborator.with_elaborate_reason(reason, |elaborator| {
2437+
let reason = Some(ElaborateReason::EvaluatingComptimeCall(
2438+
"FunctionDefinition::as_typed_expr",
2439+
location,
2440+
));
2441+
let typ =
2442+
interpreter.elaborate_in_function(interpreter.current_function, reason, |elaborator| {
24472443
elaborator.type_check_variable(hir_ident, expr_id, generics)
2448-
})
2449-
});
2444+
});
24502445
interpreter.elaborator.interner.push_expr_type(expr_id, typ);
24512446
Ok(Value::TypedExpr(TypedExpr::ExprId(expr_id)))
24522447
}
@@ -2652,20 +2647,17 @@ fn function_def_set_parameters(
26522647
"a pattern",
26532648
)?;
26542649

2655-
let hir_pattern = interpreter.elaborate_in_function(Some(func_id), |elaborator| {
2656-
let reason = ElaborateReason::EvaluatingComptimeCall(
2657-
"FunctionDefinition::set_parameters",
2658-
location,
2659-
);
2660-
elaborator.with_elaborate_reason(reason, |elaborator| {
2661-
elaborator.elaborate_pattern_and_store_ids(
2662-
parameter_pattern,
2663-
parameter_type.clone(),
2664-
DefinitionKind::Local(None),
2665-
&mut parameter_idents,
2666-
true, // warn_if_unused
2667-
)
2668-
})
2650+
let reason =
2651+
ElaborateReason::EvaluatingComptimeCall("FunctionDefinition::set_parameters", location);
2652+
let reason = Some(reason);
2653+
let hir_pattern = interpreter.elaborate_in_function(Some(func_id), reason, |elaborator| {
2654+
elaborator.elaborate_pattern_and_store_ids(
2655+
parameter_pattern,
2656+
parameter_type.clone(),
2657+
DefinitionKind::Local(None),
2658+
&mut parameter_idents,
2659+
true, // warn_if_unused
2660+
)
26692661
});
26702662

26712663
parameters.push((hir_pattern, parameter_type.clone(), Visibility::Private));
@@ -2773,19 +2765,17 @@ fn module_add_item(
27732765
let parser = Parser::parse_top_level_items;
27742766
let top_level_statements = parse(interpreter.elaborator, item, parser, "a top-level item")?;
27752767

2776-
interpreter.elaborate_in_module(module_id, |elaborator| {
2777-
let reason = ElaborateReason::EvaluatingComptimeCall("Module::add_item", location);
2778-
elaborator.with_elaborate_reason(reason, |elaborator| {
2779-
let mut generated_items = CollectedItems::default();
2768+
let reason = Some(ElaborateReason::EvaluatingComptimeCall("Module::add_item", location));
2769+
interpreter.elaborate_in_module(module_id, reason, |elaborator| {
2770+
let mut generated_items = CollectedItems::default();
27802771

2781-
for top_level_statement in top_level_statements {
2782-
elaborator.add_item(top_level_statement, &mut generated_items, location);
2783-
}
2772+
for top_level_statement in top_level_statements {
2773+
elaborator.add_item(top_level_statement, &mut generated_items, location);
2774+
}
27842775

2785-
if !generated_items.is_empty() {
2786-
elaborator.elaborate_items(generated_items);
2787-
}
2788-
});
2776+
if !generated_items.is_empty() {
2777+
elaborator.elaborate_items(generated_items);
2778+
}
27892779
});
27902780

27912781
Ok(Value::Unit)

0 commit comments

Comments
 (0)