anchor.diff:   *  At that point, the cache is updated to either Valid or Invalid w.r.t. the tc data
    *)
   type tc_result_t =
  -  | Unknown of (list<(string * string)>) * tc_result  //deps as in the checked_file_entry, tc_result
  +  | Unknown
     | Invalid of string  //reason why this is invalid
  -  | Valid   of string * tc_result  //digest of the checked file, tc_result
  +  | Valid   of string  //digest of the checked file
   
   (*
    * The cache of checked files
  
positive.code:                   let msg = BU.format2 "checked file %s is stale (digest mismatch for %s)" checked_fn fn in
                    add_and_return (Invalid msg, Inl msg)
                  end
                  else add_and_return (Unknown (deps_dig, tc_result), Inr parsing_data)
  
  (*
   * Second step for loading checked files, validates the tc data
   *)
  let load_checked_file_with_tc_result (deps:Dep.deps) (fn:string) (checked_fn:string) :cache_t =
    let elt = load_checked_file fn checked_fn in
    match elt with  //first step, in case some client calls it directly
    | Invalid _, _
    | Valid _, _ -> elt  //already marked Valid or Invalid
    | Unknown (deps_dig, tc_result), parsing_data ->
      match hash_dependences deps fn with
      | Inl msg ->
        let elt = (Invalid msg, parsing_data) in
        BU.smap_add mcache checked_fn elt;
        elt
      | Inr deps_dig' ->
        if deps_dig = deps_dig'
        then begin
          //mark the tc data of the file as valid
          let elt = (Valid (BU.digest_of_file checked_fn, tc_result), parsing_data) in 
          BU.smap_add mcache checked_fn elt;
          (*
           * if there exists an interface for it, mark that too as valid
  
negative.code:         in
          let elt = (Invalid msg, Inl msg) in
          BU.smap_add mcache checked_fn elt;
          Inl msg
        end
  
  
  let load_parsing_data_from_cache file_name =
    (*
     * the code below suppresses the already_cached assertion failure
     * following is the reason for it:
     *
     * consider a scenario:
     * A.fst -> B.fsti -> prims.fst
     *            ^      ^
     *            |     /
     *             B.fst
     *
     * the dependence analysis marks B.fsti as a dependence of A.fst
     * so when we use the makefiles to build this,
     *   makefile could first build prims, then B.fsti, and then tried to build A.fst
     *   with: fstar.exe A.fst already_cached '* -A'
     * now F* starts to build the dependence graph for A
     * it sees that A depends on B, so it reads the parsing data
     *   of B.fsti from its existing checked file
     * however, the dependence analysis ALSO reads B.fst so as to detect cycles
     * and calls load_parsing_data_from_cache_file with B.fst
     * clearly until this point, B.fst has not been checked and so its checked file doesn't exist
     * so cache_file_name raises an exception since B is in the already_cached list
     *
     * suppressing the exception here is not too bad since this exception is raised at other places
     *   e.g. when loading the checked file for typechecking purposes
     *
     * another way to handle this kind of thing would be to NOT load B.fst for cycle detection,
     *   rather provide a separate F* command --detect_cycles --alredy_cached '*' that builds
     *   can invoke in the end for cycle detection
     *)
    let cache_file =
      try
       Parser.Dep.cache_file_name file_name |> Some
      with _ -> None
  