Ltac find_type_contradict_rec :=
  first [ simple eapply find_type_contradict_pred_data_at; reflexivity
        | simple eapply find_type_contradict_pred_data_at_; reflexivity
        | simple eapply find_type_contradict_pred_field_at; reflexivity
        | simple eapply find_type_contradict_pred_field_at_; reflexivity].Definition unknown_type := Tvoid.Ltac SEP_type_contradict_msg r e :=
 let t := constr:(typeof e) in
 let t := eval simpl in t in
 let t' := match r with data_at _ ?u _ _ => constr:(u)
                                | data_at_ _ ?u _ => constr:(u)
                                | field_at _ ?u _ _ _ => constr:(u)
                                | field_at_ _ ?u _ _ => constr:(u)
                                | _ => constr:(unknown_type)
             end in
 fail 1000 "Cannot load/store with SEP clause" r "because of type mismatch
Type of expression: " t "
Type in SEP conjunct: " t'.Ltac SEP_type_contradict LOCAL2PTREE Delta e R :=
  eapply (SEP_type_contradict_lemma Delta e R);
  [ exact LOCAL2PTREE
  | reflexivity
  | solve_msubst_eval_lvalue
  | solve_msubst_eval_LR
  | solve_msubst_efield_denote
  | econstructor
  | solve_field_address_gen
  | find_nth find_type_contradict_rec
  | first [left; split; [reflexivity | find_nth find_type_contradict_rec] | right; reflexivity]
  | ];
  match goal with
  | |- Some (_, ?r) = _ /\ False => SEP_type_contradict_msg r e
  | |- _ = Some (_, ?r) /\ False => SEP_type_contradict_msg r e
  | |- _ => idtac
  end;
  fail 0.

(* Specifications: *)
Lemma hint_msg_lemma: forall {cs: compspecs} Delta e goal Q T1 T2 GV e_root efs lr p_full_from_e p_root_from_e gfs_from_e t_root_from_e p_root_from_hint gfs_from_hint t_root_from_hint t gfs p, local2ptree Q = (T1, T2, nil, GV) -> compute_nested_efield e = (e_root, efs, lr) -> msubst_eval_lvalue Delta T1 T2 GV e = Some p_full_from_e -> msubst_eval_LR Delta T1 T2 GV e_root lr = Some p_root_from_e -> msubst_efield_denote Delta T1 T2 GV efs gfs_from_e -> compute_root_type (typeof e_root) lr t_root_from_e -> field_address_gen (t_root_from_e, gfs_from_e, p_root_from_e) (t_root_from_hint, gfs_from_hint, p_root_from_hint) -> p_full_from_e = field_address t gfs p /\ p_root_from_hint = field_address t gfs p /\ False -> goal.