Oops I found lots of cases where the type checker fucks up~

I mean, I guess they were there anyway.
2 files changed, 37 insertions(+), 0 deletions(-)

M src/passes.rs
A => src/passes/double_typeck.rs
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
+    }
+}