diff --git a/examples/deref_assign.rs b/examples/deref_assign.rs
index aad858cc16bbd554ea620a225d1ea712129cd235..c915288c2867a519709259ad7dae7407561439f0 100644
--- a/examples/deref_assign.rs
+++ b/examples/deref_assign.rs
@@ -1,6 +1,6 @@
-fn main() -> i32 {
+fn main() {
     let mut a = 7;
     let b = &mut a;
     *b = 9;
-    a
+    let c = a;
 }
diff --git a/examples/deref_assign2.rs b/examples/deref_assign2.rs
index 2d6189d2c98e2837a3790d441d3119ba3e70743d..53a1872cdf55a3827ffd761a6fc681dc96afd13e 100644
--- a/examples/deref_assign2.rs
+++ b/examples/deref_assign2.rs
@@ -1,7 +1,7 @@
-fn main() -> i32 {
+fn main() {
     let mut a = 7;
-    let b = &a;
-    let c = &b;
-    **c = 9;
-    a
+    let mut b = &a;
+    let c = &mut b;
+    *(*c) = 9;
+    let d = a;
 }
diff --git a/examples/ref_err4.rs b/examples/ref_err4.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2c105f44cba6e9cfe4ad4406c2f45ab42a567555
--- /dev/null
+++ b/examples/ref_err4.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let mut a = 1;
+    let b = &a;
+    let mut c: &mut &i32 = &mut b;
+}
diff --git a/src/check.rs b/src/check.rs
index 18c42be5f4caca3f1749045cf1bb52fd551807a4..0fe868dabb40c4e5a5db5b9eb9b84d98cb17d836 100644
--- a/src/check.rs
+++ b/src/check.rs
@@ -183,149 +183,6 @@ fn strip_mut(t: Type) -> Type {
     }
 }
 
-// // walk the left hand expression in an assignment.
-// // Ok(Type), the type of the left hand
-// // Err(), illegal left hand
-// fn left_expr_type(e: &Expr, to_type: Type, var_env: &mut VarEnv) -> Result<(), Error> {
-//     match e {
-//         Expr::Id(id) => {
-//             match var_env.get(id.clone()) {
-//                 Some((true, Some(t))) => {
-//                     match *t == to_type {
-//                         true => Ok(()), // mutable, defined of same type
-//                         false => Err("types differ".to_string()),
-//                     }
-//                 }
-//                 Some((true, None)) => unimplemented!(),
-//                 Some((false, _)) => Err("variable declared immutable".to_string()),
-//                 None => Err("variable not in scope".to_string()),
-//             }
-//         }
-//         Expr::DeRef(ref_mut_e) => {
-//             let e: &Expr = &*ref_mut_e;
-//             trace!("DeRef({})", e);
-//             match e {
-//                 Expr::RefMut(e) => left_expr_type(&*e, to_type, var_env),
-//                 _ => Err("cannot deref left hand expression".to_string()),
-//             }
-//             // }
-//             // let ref_mut_id = left_expr_type(ref_mut_e, var_env)?;
-//             // trace!("left: RefMut({})", ref_mut_id);
-
-//             // match var_env.get(ref_mut_id) {
-//             //     Some(Val::Ref(id)) => {
-//             //         println!("Ref id {}", id);
-//             //         id.clone()
-//             //     }
-//             //     Some(Val::RefMut(id)) => {
-//             //         println!("RefMut id {}", id);
-//             //         id.clone()
-//             //     }
-//             //     _ => panic!("deref failed"),
-//             // }
-
-//             // Ok(ref_mut_id)
-//         }
-
-//         // let ev = eval_left_expr(e, m, fn_env);
-//         // println!("eval_left {:?}", ev);
-
-//         // match m.get(ev) {
-//         //     Some(Val::Ref(id)) => {
-//         //         println!("Ref id {}", id);
-//         //         id.clone()
-//         //     }
-//         //     Some(Val::RefMut(id)) => {
-//         //         println!("RefMut id {}", id);
-//         //         id.clone()
-//         //     }
-//         //     _ => panic!("deref failed"),
-//         // }
-//         _ => Err(format!("illegal left hand expression {}", e)),
-//     }
-// }
-
-// walk the left hand expression in an assignment.
-// Ok(Type), the type of the left hand
-// Err(), illegal left hand
-fn left_expr_type(e: &Expr, var_env: &mut VarEnv) -> Result<Id, Error> {
-    match e {
-        Expr::Id(id) => Ok(id.to_owned()),
-        //     match var_env.get(id.clone()) {
-        //         Some((true, Some(t))) => {
-        //             match *t == to_type {
-        //                 true => Ok(()), // mutable, defined of same type
-        //                 false => Err("types differ".to_string()),
-        //             }
-        //         }
-        //         Some((true, None)) => unimplemented!(),
-        //         Some((false, _)) => Err("variable declared immutable".to_string()),
-        //         None => Err("variable not in scope".to_string()),
-        //     }
-        // }
-        Expr::DeRef(ref_mut_e) => {
-            trace!("DeRef({})", ref_mut_e);
-            let lh = left_expr_type(ref_mut_e, var_env)?;
-            trace!("DeRef({})", lh);
-            match var_env.get(lh) {
-                Some(t) => {
-                    trace!("t {:?}", t);
-                    panic!();
-                }
-                //     match *t == to_type {
-                //         true => Ok(()), // mutable, defined of same type
-                //         false => Err("types differ".to_string()),
-                //     }
-                // }
-                // Some((true, None)) => unimplemented!(),
-                // Some((false, _)) => Err("variable declared immutable".to_string()),
-                None => Err("variable not in scope".to_string()),
-            }
-        }
-
-        //     match e {
-        //         Expr::RefMut(e) => left_expr_type(&*e, to_type, var_env),
-        //         _ => Err("cannot deref left hand expression".to_string()),
-        //     }
-        // }
-        //  println!("eval_left deref e {:?}", e);
-
-        //     let ev = eval_left_expr(e, m, fn_env);
-        //     println!("eval_left {:?}", ev);
-
-        //     match m.get(ev) {
-        //         Some(Val::Ref(id)) => {
-        //             println!("Ref id {}", id);
-        //             id.clone()
-        //         }
-        //         Some(Val::RefMut(id)) => {
-        //             println!("RefMut id {}", id);
-        //             id.clone()
-        //         }
-        //         _ => panic!("deref failed"),
-        //     }
-
-        // Ok(ref_mut_id)
-        // }
-
-        // let ev = eval_left_expr(e, m, fn_env);
-        // println!("eval_left {:?}", ev);
-
-        // match m.get(ev) {
-        //     Some(Val::Ref(id)) => {
-        //         println!("Ref id {}", id);
-        //         id.clone()
-        //     }
-        //     Some(Val::RefMut(id)) => {
-        //         println!("RefMut id {}", id);
-        //         id.clone()
-        //     }
-        //     _ => panic!("deref failed"),
-        // }
-        _ => Err(format!("illegal left hand expression {}", e)),
-    }
-}
-
 pub fn check_stmts(
     stmts: &Stmts,
     fn_env: &FnEnv,
@@ -369,13 +226,22 @@ pub fn check_stmts(
             }
 
             Assign(lh, e) => {
-                let expr_type = expr_type(&*e, fn_env, type_env, var_env)?;
-                trace!("expr_type = {}", expr_type);
-                trace!("v = {:?}", lh);
+                let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
+                trace!("e_type = {}", e_type);
+                trace!("lh = {:?}", lh);
 
-                let id = left_expr_type(&*lh, var_env)?;
-                //  var_env.update(id, expr_type)?;
-                Ok(Type::Unit)
+                let lh_type = expr_type(lh, fn_env, type_env, var_env)?;
+                trace!("lh_type {}", &lh_type);
+
+                if match &lh_type {
+                    Type::Mut(t) => **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) {
diff --git a/tests/test_check.rs b/tests/test_check.rs
index 659152a951d52b193d05de1937e63c86c242e7b6..844b0b1395d6d8b47a3b8abb5a52e84cb206b7a2 100644
--- a/tests/test_check.rs
+++ b/tests/test_check.rs
@@ -144,3 +144,8 @@ fn check_ref_err2() {
 fn check_ref_err3() {
     assert!(check(&read_file::parse("examples/ref_err3.rs")).is_err());
 }
+
+#[test]
+fn check_ref_err4() {
+    assert!(check(&read_file::parse("examples/ref_err4.rs")).is_err());
+}