M src/passes.rs +2 -0
@@ 27,6 27,7 @@
//mod enum_to_int;
mod constinfer;
+mod double_typeck;
mod generic_infer;
mod handle_imports;
mod lambda_lift;
@@ 61,6 62,7 @@ pub fn run_typechecked_passes(ir: Ir, tc
// let passes: &[TckPass] = &[nameify, enum_to_int];
//let passes: &[TckPass] = &[nameify, struct_to_tuple];
let passes: &[TckPass] = &[
+ double_typeck::double_typeck,
constinfer::constinfer,
struct_to_tuple::struct_to_tuple,
//monomorphization::monomorphize,
A => src/passes/double_typeck.rs +35 -0
@@ 0,0 1,35 @@
+//! Sanity checks the results of the type checker.
+//! Doesn't actually change anything, just walks through
+//! the entire IR tree and makes sure that every expression
+//! has a real type.
+
+use crate::hir::*;
+use crate::passes::*;
+use crate::*;
+
+fn check_expr(expr: ExprNode, tck: &mut typeck::Tck) -> ExprNode {
+ let expr_typeid = tck.get_expr_type(&expr);
+ let expr_type = tck
+ .reconstruct(expr_typeid)
+ .unwrap_or_else(|e| panic!("Typechecker couldn't reconstruct something: {}", e));
+ match &expr_type {
+ Type::Prim(PrimType::UnknownInt) => panic!("Unknown int in expr {:?}", expr.e),
+ Type::Prim(PrimType::AnyPtr) => panic!("should be unused"),
+ _ => (),
+ }
+
+ expr
+}
+
+pub(super) fn double_typeck(ir: Ir, tck: &mut typeck::Tck) -> Ir {
+ let type_map = &mut |t| t;
+ let new_decls = ir
+ .decls
+ .into_iter()
+ .map(|d| decl_map_pre(d, &mut |e| check_expr(e, tck), type_map))
+ .collect();
+ Ir {
+ decls: new_decls,
+ ..ir
+ }
+}