Skip to content

Commit d44f882

Browse files
author
jfecher
authored
fix: Change panic to error in interpreter (#5446)
# Description ## Problem\* Working towards #5428 ## Summary\* Changes the panic in #5428 to an error instead. The original error message was no longer appropriate either since this was occurring in the interpreter rather than the monomorphizer. ## Additional Context This doesn't fix the issue, I just thought it'd be slightly nicer UX going forward if we didn't panic here. ## 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.
1 parent 4020e77 commit d44f882

3 files changed

Lines changed: 28 additions & 10 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub enum InterpreterError {
5050
NonComptimeFnCallInSameCrate { function: String, location: Location },
5151
NoImpl { location: Location },
5252
NoMatchingImplFound { error: NoMatchingImplFoundError, file: FileId },
53+
ImplMethodTypeMismatch { expected: Type, actual: Type, location: Location },
5354

5455
Unimplemented { item: String, location: Location },
5556

@@ -114,6 +115,7 @@ impl InterpreterError {
114115
| InterpreterError::NonComptimeFnCallInSameCrate { location, .. }
115116
| InterpreterError::Unimplemented { location, .. }
116117
| InterpreterError::NoImpl { location, .. }
118+
| InterpreterError::ImplMethodTypeMismatch { location, .. }
117119
| InterpreterError::BreakNotInLoop { location, .. }
118120
| InterpreterError::ContinueNotInLoop { location, .. } => *location,
119121
InterpreterError::FailedToParseMacro { error, file, .. } => {
@@ -344,6 +346,12 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic {
344346
let msg = "No impl found due to prior type error".into();
345347
CustomDiagnostic::simple_error(msg, String::new(), location.span)
346348
}
349+
InterpreterError::ImplMethodTypeMismatch { expected, actual, location } => {
350+
let msg = format!(
351+
"Impl method type {actual} does not unify with trait method type {expected}"
352+
);
353+
CustomDiagnostic::simple_error(msg, String::new(), location.span)
354+
}
347355
InterpreterError::NoMatchingImplFound { error, .. } => error.into(),
348356
InterpreterError::Break => unreachable!("Uncaught InterpreterError::Break"),
349357
InterpreterError::Continue => unreachable!("Uncaught InterpreterError::Continue"),

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl<'a> Interpreter<'a> {
7474
let trait_method = self.interner.get_trait_method_id(function);
7575

7676
perform_instantiation_bindings(&instantiation_bindings);
77-
let impl_bindings = perform_impl_bindings(self.interner, trait_method, function);
77+
let impl_bindings = perform_impl_bindings(self.interner, trait_method, function, location)?;
7878
let result = self.call_function_inner(function, arguments, location);
7979
undo_instantiation_bindings(impl_bindings);
8080
undo_instantiation_bindings(instantiation_bindings);

compiler/noirc_frontend/src/monomorphization/mod.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ struct Monomorphizer<'interner> {
7272

7373
/// Queue of functions to monomorphize next each item in the queue is a tuple of:
7474
/// (old_id, new_monomorphized_id, any type bindings to apply, the trait method if old_id is from a trait impl)
75-
queue: VecDeque<(node_interner::FuncId, FuncId, TypeBindings, Option<TraitMethodId>)>,
75+
queue: VecDeque<(node_interner::FuncId, FuncId, TypeBindings, Option<TraitMethodId>, Location)>,
7676

7777
/// When a function finishes being monomorphized, the monomorphized ast::Function is
7878
/// stored here along with its FuncId.
@@ -124,11 +124,15 @@ pub fn monomorphize_debug(
124124
let function_sig = monomorphizer.compile_main(main)?;
125125

126126
while !monomorphizer.queue.is_empty() {
127-
let (next_fn_id, new_id, bindings, trait_method) = monomorphizer.queue.pop_front().unwrap();
127+
let (next_fn_id, new_id, bindings, trait_method, location) =
128+
monomorphizer.queue.pop_front().unwrap();
128129
monomorphizer.locals.clear();
129130

130131
perform_instantiation_bindings(&bindings);
131-
let impl_bindings = perform_impl_bindings(monomorphizer.interner, trait_method, next_fn_id);
132+
let interner = &monomorphizer.interner;
133+
let impl_bindings = perform_impl_bindings(interner, trait_method, next_fn_id, location)
134+
.map_err(MonomorphizationError::InterpreterError)?;
135+
132136
monomorphizer.function(next_fn_id, new_id)?;
133137
undo_instantiation_bindings(impl_bindings);
134138
undo_instantiation_bindings(bindings);
@@ -1275,9 +1279,10 @@ impl<'interner> Monomorphizer<'interner> {
12751279
let new_id = self.next_function_id();
12761280
self.define_function(id, function_type.clone(), turbofish_generics, new_id);
12771281

1282+
let location = self.interner.expr_location(&expr_id);
12781283
let bindings = self.interner.get_instantiation_bindings(expr_id);
12791284
let bindings = self.follow_bindings(bindings);
1280-
self.queue.push_back((id, new_id, bindings, trait_method));
1285+
self.queue.push_back((id, new_id, bindings, trait_method, location));
12811286
new_id
12821287
}
12831288

@@ -1747,7 +1752,8 @@ pub fn perform_impl_bindings(
17471752
interner: &NodeInterner,
17481753
trait_method: Option<TraitMethodId>,
17491754
impl_method: node_interner::FuncId,
1750-
) -> TypeBindings {
1755+
location: Location,
1756+
) -> Result<TypeBindings, InterpreterError> {
17511757
let mut bindings = TypeBindings::new();
17521758

17531759
if let Some(trait_method) = trait_method {
@@ -1767,14 +1773,18 @@ pub fn perform_impl_bindings(
17671773
let type_bindings = generics.iter().map(replace_type_variable).collect();
17681774
let impl_method_type = impl_method_type.force_substitute(&type_bindings);
17691775

1770-
trait_method_type.try_unify(&impl_method_type, &mut bindings).unwrap_or_else(|_| {
1771-
unreachable!("Impl method type {} does not unify with trait method type {} during monomorphization", impl_method_type, trait_method_type)
1772-
});
1776+
trait_method_type.try_unify(&impl_method_type, &mut bindings).map_err(|_| {
1777+
InterpreterError::ImplMethodTypeMismatch {
1778+
expected: trait_method_type.clone(),
1779+
actual: impl_method_type,
1780+
location,
1781+
}
1782+
})?;
17731783

17741784
perform_instantiation_bindings(&bindings);
17751785
}
17761786

1777-
bindings
1787+
Ok(bindings)
17781788
}
17791789

17801790
pub fn resolve_trait_method(

0 commit comments

Comments
 (0)