Skip to content

Commit

Permalink
chore: move delayed_type_checks field from NodeInterner to `TypeC…
Browse files Browse the repository at this point in the history
…hecker` (#1679)

* chore: move `delayed_type_checks` field from `NodeInterner` to `TypeChecker`

* Update crates/noirc_frontend/src/hir/type_check/mod.rs

---------

Co-authored-by: jfecher <jfecher11@gmail.com>
  • Loading branch information
f01dab1e and jfecher authored Jun 15, 2023
1 parent f598cc6 commit 65b91f2
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 21 deletions.
2 changes: 1 addition & 1 deletion crates/noirc_frontend/src/hir/type_check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ impl<'interner> TypeChecker<'interner> {
// This will be an error if these types later resolve to a Field, or stay
// polymorphic as the bit size will be unknown. Delay this error until the function
// finishes resolving so we can still allow cases like `let x: u8 = 1 << 2;`.
self.interner.push_delayed_type_check(Box::new(move || {
self.push_delayed_type_check(Box::new(move || {
if other.is_field() {
Err(make_error("Bitwise operations are invalid on Field types. Try casting the operands to a sized integer type first".into()))
} else if other.is_bindable() {
Expand Down
33 changes: 27 additions & 6 deletions crates/noirc_frontend/src/hir/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ use crate::{
Type,
};

type TypeCheckFn = Box<dyn FnOnce() -> Result<(), TypeCheckError>>;

pub struct TypeChecker<'interner> {
delayed_type_checks: Vec<TypeCheckFn>,
current_function: Option<FuncId>,
interner: &'interner mut NodeInterner,
errors: Vec<TypeCheckError>,
Expand All @@ -47,10 +50,11 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec<Type
type_checker.bind_pattern(&param.0, param.1);
}

let (function_last_type, mut errors) = type_checker.check_function_body(function_body_id);
let (function_last_type, delayed_type_check_functions, mut errors) =
type_checker.check_function_body(function_body_id);

// Go through any delayed type checking errors to see if they are resolved, or error otherwise.
for type_check_fn in interner.take_delayed_type_check_functions() {
for type_check_fn in delayed_type_check_functions {
if let Err(error) = type_check_fn() {
errors.push(error);
}
Expand All @@ -73,16 +77,33 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec<Type

impl<'interner> TypeChecker<'interner> {
fn new(current_function: FuncId, interner: &'interner mut NodeInterner) -> Self {
Self { current_function: Some(current_function), interner, errors: vec![] }
Self {
delayed_type_checks: Vec::new(),
current_function: Some(current_function),
interner,
errors: vec![],
}
}

fn check_function_body(mut self, body: &ExprId) -> (Type, Vec<TypeCheckError>) {
pub fn push_delayed_type_check(&mut self, f: TypeCheckFn) {
self.delayed_type_checks.push(f);
}

fn check_function_body(
mut self,
body: &ExprId,
) -> (Type, Vec<TypeCheckFn>, Vec<TypeCheckError>) {
let body_type = self.check_expression(body);
(body_type, self.errors)
(body_type, self.delayed_type_checks, self.errors)
}

pub fn check_global(id: &StmtId, interner: &'interner mut NodeInterner) -> Vec<TypeCheckError> {
let mut this = Self { current_function: None, interner, errors: vec![] };
let mut this = Self {
delayed_type_checks: Vec::new(),
current_function: None,
interner,
errors: vec![],
};
this.check_statement(id);
this.errors
}
Expand Down
14 changes: 0 additions & 14 deletions crates/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::ast::Ident;
use crate::graph::CrateId;
use crate::hir::def_collector::dc_crate::UnresolvedStruct;
use crate::hir::def_map::{LocalModuleId, ModuleId};
use crate::hir::type_check::TypeCheckError;
use crate::hir::StorageSlot;
use crate::hir_def::stmt::HirLetStatement;
use crate::hir_def::types::{StructType, Type};
Expand Down Expand Up @@ -66,17 +65,13 @@ pub struct NodeInterner {

next_type_variable_id: usize,

delayed_type_checks: Vec<TypeCheckFn>,

/// A map from a struct type and method name to a function id for the method.
struct_methods: HashMap<(StructId, String), FuncId>,

/// Methods on primitive types defined in the stdlib.
primitive_methods: HashMap<(TypeMethodKey, String), FuncId>,
}

type TypeCheckFn = Box<dyn FnOnce() -> Result<(), TypeCheckError>>;

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct DefinitionId(usize);

Expand Down Expand Up @@ -252,7 +247,6 @@ impl Default for NodeInterner {
field_indices: HashMap::new(),
next_type_variable_id: 0,
globals: HashMap::new(),
delayed_type_checks: vec![],
struct_methods: HashMap::new(),
primitive_methods: HashMap::new(),
};
Expand Down Expand Up @@ -561,14 +555,6 @@ impl NodeInterner {
self.function_definition_ids[&function]
}

pub fn push_delayed_type_check(&mut self, f: TypeCheckFn) {
self.delayed_type_checks.push(f);
}

pub fn take_delayed_type_check_functions(&mut self) -> Vec<TypeCheckFn> {
std::mem::take(&mut self.delayed_type_checks)
}

/// Add a method to a type.
/// This will panic for non-struct types currently as we do not support methods
/// for primitives. We could allow this in the future however.
Expand Down

0 comments on commit 65b91f2

Please sign in to comment.