diff --git a/examples/wip.rs b/examples/wip.rs
index 80b5c89b4f376892b430a771bc22c3d6b5369f45..7756966ec21967c3b91b3fdfc6fda02d9fc62bfb 100644
--- a/examples/wip.rs
+++ b/examples/wip.rs
@@ -4,7 +4,7 @@ fn main() {
     let mut a = 5;
     a = 5;
     a = { 7 };
-    a = if true { 7 } else { 5 }
+    a = if true { 7 } else { 5 };
 }
 
 fn b(x: i32) -> i32 {
diff --git a/src/check.rs b/src/check.rs
index 8870a42cd9d6f52b68f12e56172c1ccf6e43a5ff..5baafbdc6566abadc1b23f16ea3603bcf3c359d3 100644
--- a/src/check.rs
+++ b/src/check.rs
@@ -190,7 +190,7 @@ fn expr_type(
 
         Block(b) => check_stmts(b, fn_env, type_env, var_env),
 
-        Stmt(s) => panic!(),
+        Stmt(s) => check_stmt(s, fn_env, type_env, var_env),
     }
 }
 
@@ -246,128 +246,139 @@ fn is_known(t: &Type) -> bool {
     }
 }
 
-pub fn check_stmts(
-    stmts: &Stmts,
+pub fn check_stmt(
+    s: &Stmt,
     fn_env: &FnEnv,
     type_env: &TypeEnv,
     var_env: &mut VarEnv,
 ) -> Result<Type, Error> {
     use Stmt::*;
-
-    var_env.push_empty_scope();
-
-    let t = stmts.stmts.iter().try_fold(Type::Unit, |_, s| {
-        trace!("stmt: {}", s);
-        match s {
-            Stmt::Block(b) => check_stmts(b, fn_env, type_env, var_env),
-
-            Expr(e) => expr_type(&*e, fn_env, type_env, var_env),
-
-            Let(var_id, is_mut, ot, oe) => {
-                let t: Type = match (ot, oe) {
-                    (Some(t), Some(e)) => {
-                        let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
-                        let e_type = strip_mut(e_type);
-                        match strip_mut(t.clone()) == e_type {
-                            true => t.clone(),
-                            false => {
-                                trace!("e {}", e);
-                                Err(format!("incompatible types, {} <> {}", t, e_type))?
-                            }
+    trace!("stmt: {}", s);
+    match s {
+        Stmt::Block(b) => check_stmts(b, fn_env, type_env, var_env),
+
+        Expr(e) => expr_type(&*e, fn_env, type_env, var_env),
+
+        Let(var_id, is_mut, ot, oe) => {
+            let t: Type = match (ot, oe) {
+                (Some(t), Some(e)) => {
+                    let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
+                    let e_type = strip_mut(e_type);
+                    match strip_mut(t.clone()) == e_type {
+                        true => t.clone(),
+                        false => {
+                            trace!("e {}", e);
+                            Err(format!("incompatible types, {} <> {}", t, e_type))?
                         }
                     }
-                    (None, Some(e)) => {
-                        let e_type = strip_mut(expr_type(&*e, fn_env, type_env, var_env)?);
-                        match is_known(&e_type) {
-                            true => e_type,
-                            _ => Err("reference to unknown type".to_string())?,
-                        }
+                }
+                (None, Some(e)) => {
+                    let e_type = strip_mut(expr_type(&*e, fn_env, type_env, var_env)?);
+                    match is_known(&e_type) {
+                        true => e_type,
+                        _ => Err("reference to unknown type".to_string())?,
                     }
-                    (Some(t), None) => t.clone(),
-                    _ => Type::Unknown,
-                };
-                let t = match is_mut {
-                    true => Type::Mut(Box::new(t)),
-                    false => t,
-                };
-                var_env.new_id(var_id.clone(), t);
-                trace!("var_env {:?}", var_env);
-                Ok(Type::Unit)
-            }
+                }
+                (Some(t), None) => t.clone(),
+                _ => Type::Unknown,
+            };
+            let t = match is_mut {
+                true => Type::Mut(Box::new(t)),
+                false => t,
+            };
+            var_env.new_id(var_id.clone(), t);
+            trace!("var_env {:?}", var_env);
+            Ok(Type::Unit)
+        }
 
-            Assign(lh, e) => {
-                trace!("assign");
+        Assign(lh, e) => {
+            trace!("assign");
 
-                let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
-                trace!("e_type = {}", &e_type);
-                let e_type = strip_mut(e_type);
-                trace!("e_type stripped = {}", &e_type);
+            let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
+            trace!("e_type = {}", &e_type);
+            let e_type = strip_mut(e_type);
+            trace!("e_type stripped = {}", &e_type);
 
-                trace!("lh expr = {:?}", lh);
+            trace!("lh expr = {:?}", lh);
 
-                let lh_type = lexpr_type(lh, fn_env, type_env, var_env)?;
-                trace!("lh_type {}", lh_type);
+            let lh_type = lexpr_type(lh, fn_env, type_env, var_env)?;
+            trace!("lh_type {}", lh_type);
 
-                if match lh_type {
+            if match lh_type {
+                Type::Unknown => {
+                    trace!("assign to unknown");
+                    *lh_type = e_type.clone();
+                    true
+                }
+                Type::Mut(t) => match **t {
                     Type::Unknown => {
-                        trace!("assign to unknown");
-                        *lh_type = e_type.clone();
+                        trace!("assign to `mut Unknown`");
+                        *t = Box::new(e_type.clone());
                         true
                     }
-                    Type::Mut(t) => match **t {
-                        Type::Unknown => {
-                            trace!("assign to `mut Unknown`");
-                            *t = Box::new(e_type.clone());
-                            true
-                        }
-                        _ => **t == e_type,
-                    },
-
-                    _ => Err(format!("assignment to immutable"))?,
-                } {
-                    Ok(Type::Unit)
-                } else {
-                    Err(format!("cannot assign {} = {}", &lh_type, e_type))
-                }
+                    _ => **t == e_type,
+                },
+
+                _ => Err(format!("assignment to immutable"))?,
+            } {
+                Ok(Type::Unit)
+            } else {
+                Err(format!("cannot assign {} = {}", &lh_type, e_type))
             }
+        }
 
-            While(e, block) => match expr_type(&*e, fn_env, type_env, var_env) {
-                Ok(Type::Bool) => {
-                    let _ = check_stmts(&block, fn_env, type_env, var_env)?;
-                    Ok(Type::Unit) // a while statement is of unit type;
-                }
-                _ => Err("Condition not Boolean".to_string()),
-            },
-
-            If(e, then, o_else) => match expr_type(&*e, fn_env, type_env, var_env)? {
-                Type::Bool => {
-                    // The condition is of Bool type
-                    let then_type = check_stmts(&then, fn_env, type_env, var_env)?;
-                    trace!("then type {}", then_type);
-                    match o_else {
-                        None => Ok(then_type), // type of the arm
-                        Some(else_stmts) => {
-                            let else_type = check_stmts(&else_stmts, fn_env, type_env, var_env)?;
-                            trace!("else type {}", else_type);
-
-                            match then_type == else_type {
-                                true => Ok(then_type), // same type of both arms
-                                false => {
-                                    trace!("error-----");
-                                    Err(format!(
-                                        "'then' arm :{} does not match 'else' arm :{}",
-                                        then_type, else_type
-                                    ))
-                                }
+        While(e, block) => match expr_type(&*e, fn_env, type_env, var_env) {
+            Ok(Type::Bool) => {
+                let _ = check_stmts(&block, fn_env, type_env, var_env)?;
+                Ok(Type::Unit) // a while statement is of unit type;
+            }
+            _ => Err("Condition not Boolean".to_string()),
+        },
+
+        If(e, then, o_else) => match expr_type(&*e, fn_env, type_env, var_env)? {
+            Type::Bool => {
+                // The condition is of Bool type
+                let then_type = check_stmts(&then, fn_env, type_env, var_env)?;
+                trace!("then type {}", then_type);
+                match o_else {
+                    None => Ok(then_type), // type of the arm
+                    Some(else_stmts) => {
+                        let else_type = check_stmts(&else_stmts, fn_env, type_env, var_env)?;
+                        trace!("else type {}", else_type);
+
+                        match then_type == else_type {
+                            true => Ok(then_type), // same type of both arms
+                            false => {
+                                trace!("error-----");
+                                Err(format!(
+                                    "'then' arm :{} does not match 'else' arm :{}",
+                                    then_type, else_type
+                                ))
                             }
                         }
                     }
                 }
-                _ => Err("Condition not Boolean".to_string()),
-            },
-            Semi => panic!("ICE"),
-        }
-    })?;
+            }
+            _ => Err("Condition not Boolean".to_string()),
+        },
+        Semi => panic!("ICE"),
+    }
+}
+
+pub fn check_stmts(
+    stmts: &Stmts,
+    fn_env: &FnEnv,
+    type_env: &TypeEnv,
+    var_env: &mut VarEnv,
+) -> Result<Type, Error> {
+    use Stmt::*;
+
+    var_env.push_empty_scope();
+
+    let t = stmts
+        .stmts
+        .iter()
+        .try_fold(Type::Unit, |_, s| check_stmt(s, fn_env, type_env, var_env))?;
 
     var_env.pop_scope();
     if !stmts.ret {