anchor.diff:        BU.print1 "Expected type before unification: %s\n"
           (Print.term_to_string k);
   
  -    let g = Rel.teq env ty k in
  -    List.iter (Rel.force_trivial_guard env) [g_f; g_ret_t; g_pure_wp_uvar];
  -    let k = N.remove_uvar_solutions env k in  //AR: TODO: FIXME: do this for other combinators too
  +    let guard_eq = Rel.teq env ty k in
  +    List.iter (Rel.force_trivial_guard env) [guard_f; guard_ret_t; guard_wp; guard_eq];
  +    let k = N.remove_uvar_solutions env k in
       stronger_us, stronger_t, k |> N.normalize [Env.Beta; Env.Eager_unfolding] env |> SS.close_univ_vars stronger_us in
   
     log_combinator "stronger_repr" stronger_repr;
   
     //AR: TODO: FIXME: rest of the combinators
   
  +
  +  (*
  +   * Actions
  +   *
  +   * Actions must have type:
  +   *   <some binders> -> repr a i_1 ... i_n
  +   *   so that we can inject them into the effect
  +   *
  +   * Other than this, no polymorphism etc. restrictions
  +   *
  +   * TODO: this code has a lot in common with actions for non-layered effects, we should reuse
  +   *)
     let tc_action env (act:action) : action =
       let r = act.action_defn.pos in
       if List.length act.action_params <> 0
  -    then failwith "tc_layered_eff_decl: expected action_params to be empty";
  +    then raise_error (Errors.Fatal_MalformedActionDeclaration,
  +      BU.format3 "Action %s:%s has non-empty action params (%s)"
  +        ed.mname.str act.action_name.str (Print.binders_to_string "; " act.action_params)) r;
   
       let env, act =
         let usubst, us = SS.univ_var_opening act.action_univs in
  
positive.code:   // the rest of the job to [tc_decl].
    DMFF.cps_and_elaborate env ed
  
  let tc_layered_eff_decl env0 (ed:S.eff_decl) : S.eff_decl =
    if Env.debug env0 <| Options.Other "LayeredEffects" then
      BU.print1 "Typechecking layered effect: \n\t%s\n" (Print.eff_decl_to_string false ed);
  
    if List.length ed.univs <> 0 || List.length ed.binders <> 0 then
      raise_error
        (Errors.Fatal_UnexpectedEffect, "Binders are not supported for layered effects (" ^ ed.mname.str ^")")
        (range_of_lid ed.mname);
  
    let check_and_gen' (comb:string) (n:int) env_opt (us, t) : (univ_names * term * typ) =
      let env = if is_some env_opt then env_opt |> must else env0 in
      let us, t = SS.open_univ_vars us t in
      let t, ty =
        let t, lc, g = tc_tot_or_gtot_term (Env.push_univ_vars env us) t in
        Rel.force_trivial_guard env g;
        t, lc.res_typ in
      let g_us, t = TcUtil.generalize_universes env t in
      let ty = SS.close_univ_vars g_us ty in
      //check that n = List.length g_us and that if us is set, it is same as g_us
      begin
        if List.length g_us <> n then
          let error = BU.format4
            "Expected %s:%s to be universe-polymorphic in %s universes, found %s"
            ed.mname.str comb (string_of_int n) (g_us |> List.length |> string_of_int) in
          raise_error (Errors.Fatal_MismatchUniversePolymorphic, error) t.pos
      end;
      match us with
      | [] -> g_us, t, ty
      | _ ->
       if List.length us = List.length g_us &&
          List.forall2 (fun u1 u2 -> S.order_univ_name u1 u2 = 0) us g_us
       then g_us, t, ty
       else raise_error (Errors.Fatal_UnexpectedNumberOfUniverse,
              (BU.format4 "Expected and generalized universes in the declaration for %s:%s are different, expected: %s, but found %s"
                 ed.mname.str comb (BU.string_of_int (List.length us)) (BU.string_of_int (List.length g_us))))
              t.pos
    in
  
    let log_combinator s (us, t, ty) =
      if Env.debug env0 <| Options.Other "LayeredEffects" then
        BU.print4 "Typechecked %s:%s = %s:%s\n"
          ed.mname.str s
          (Print.tscheme_to_string (us, t)) (Print.tscheme_to_string (us, ty)) in
    
    let fresh_a_and_u_a (a:string) = U.type_u () |> (fun (t, u) -> S.gen_bv a None t |> S.mk_binder, u) in
    let fresh_x_a (x:string) (a:binder) = S.gen_bv x None (a |> fst |> S.bv_to_name) |> S.mk_binder in
  
    let signature =
      let r = (snd ed.signature).pos in
      let sig_us, sig_t, sig_ty = check_and_gen' "signature" 1 None ed.signature in
  
      let us, t = SS.open_univ_vars sig_us sig_t in
      let env = Env.push_univ_vars env0 us in
  
negative.code:       let signature_ts = let us, t, _ = signature in (us, t) in
        TcUtil.layered_effect_indices_as_binders signature_ts u (a |> fst |> S.bv_to_name) in
      let bs = a::rest_bs in
      let k = U.arrow bs (U.type_u () |> (fun (t, u) -> S.mk_Total' t (Some (new_u_univ ())))) in  //note the universe of Tot need not be u
      let g = Rel.teq env ty k in
      Rel.force_trivial_guard env g;
      repr_us, repr_t, SS.close_univ_vars us (k |> N.remove_uvar_solutions env) in
  
    log_combinator "repr" repr;
  
    //helper function that creates an application node (repr<u> a_tm ?u1 ... ?un)
    //returns the application term and the guard for the introduced uvars (see TcUtil.fresh_layered_effect_repr)
    let fresh_repr r env u a_tm =
      let signature_ts = let us, t, _ = signature in (us, t) in
      let repr_ts = let us, t, _ = repr in (us, t) in
      TcUtil.fresh_layered_effect_repr env r ed.mname signature_ts repr_ts u a_tm in
  
    let not_an_arrow_error comb n t r =
      raise_error (Errors.Fatal_UnexpectedEffect,
        BU.format4 "Type of %s:%s is not an arrow with >= %s binders (%s)" ed.mname.str comb (string_of_int n) (Print.term_to_string t)
      ) r in
  
    (*
     * return_repr
     *
     * return_repr must have type:
     *   a:Type -> <some binders> -> x:a -> repr a i_1 ... i_n  //polymorphic in one universe (that of a)
     *   where i_1 ... i_n are terms of effect indices types (as in the signature)
     *
     * The binders have arbitrary sorts
     *)
    let return_repr =
      let r = (snd ed.return_repr).pos in
      let ret_us, ret_t, ret_ty = check_and_gen "return_repr" 1 ed.return_repr in
  
      let us, ty = SS.open_univ_vars ret_us ret_ty in
      let env = Env.push_univ_vars env0 us in
  