open Prims
type extension_tosyntax_decl_t =
  FStarC_Syntax_DsEnv.env ->
    FStarC_Dyn.dyn ->
      FStarC_Ident.lident Prims.list ->
        FStarC_Range_Type.t -> FStarC_Syntax_Syntax.sigelt' Prims.list
let extension_tosyntax_table : extension_tosyntax_decl_t FStarC_SMap.t=
  FStarC_SMap.create (Prims.of_int (20))
let register_extension_tosyntax (lang_name : Prims.string)
  (cb : extension_tosyntax_decl_t) : unit=
  FStarC_SMap.add extension_tosyntax_table lang_name cb
let lookup_extension_tosyntax (lang_name : Prims.string) :
  extension_tosyntax_decl_t FStar_Pervasives_Native.option=
  FStarC_SMap.try_find extension_tosyntax_table lang_name
let dbg_attrs : Prims.bool FStarC_Effect.ref= FStarC_Debug.get_toggle "attrs"
let dbg_ToSyntax : Prims.bool FStarC_Effect.ref=
  FStarC_Debug.get_toggle "ToSyntax"
type antiquotations_temp =
  (FStarC_Syntax_Syntax.bv * FStarC_Syntax_Syntax.term) Prims.list
let tun_r (r : FStarC_Range_Type.t) : FStarC_Syntax_Syntax.term=
  {
    FStarC_Syntax_Syntax.n =
      (FStarC_Syntax_Syntax.tun.FStarC_Syntax_Syntax.n);
    FStarC_Syntax_Syntax.pos = r;
    FStarC_Syntax_Syntax.vars =
      (FStarC_Syntax_Syntax.tun.FStarC_Syntax_Syntax.vars);
    FStarC_Syntax_Syntax.hash_code =
      (FStarC_Syntax_Syntax.tun.FStarC_Syntax_Syntax.hash_code)
  }
type annotated_pat =
  (FStarC_Syntax_Syntax.pat * (FStarC_Syntax_Syntax.bv *
    FStarC_Syntax_Syntax.typ * FStarC_Syntax_Syntax.term Prims.list)
    Prims.list)
let mk_thunk (e : FStarC_Syntax_Syntax.term) : FStarC_Syntax_Syntax.term=
  let b =
    let uu___ =
      FStarC_Syntax_Syntax.new_bv FStar_Pervasives_Native.None
        FStarC_Syntax_Syntax.tun in
    FStarC_Syntax_Syntax.mk_binder uu___ in
  FStarC_Syntax_Util.abs [b] e FStar_Pervasives_Native.None
let mk_binder_with_attrs (bv : FStarC_Syntax_Syntax.bv)
  (aq : FStarC_Syntax_Syntax.bqual)
  (attrs : FStarC_Syntax_Syntax.attribute Prims.list) :
  FStarC_Syntax_Syntax.binder=
  let uu___ = FStarC_Syntax_Util.parse_positivity_attributes attrs in
  match uu___ with
  | (pqual, attrs1) ->
      FStarC_Syntax_Syntax.mk_binder_with_attrs bv aq pqual attrs1
let qualify_field_names (record_or_dc_lid : FStarC_Ident.lident)
  (field_names : FStarC_Ident.lident Prims.list) :
  FStarC_Ident.lident Prims.list=
  let qualify_to_record l =
    let ns = FStarC_Ident.ns_of_lid record_or_dc_lid in
    let uu___ = FStarC_Ident.ident_of_lid l in
    FStarC_Ident.lid_of_ns_and_id ns uu___ in
  let uu___ =
    FStarC_List.fold_left
      (fun uu___1 l ->
         match uu___1 with
         | (ns_opt, out) ->
             let uu___2 = FStarC_Ident.nsstr l in
             (match uu___2 with
              | "" ->
                  if FStar_Pervasives_Native.uu___is_Some ns_opt
                  then
                    let uu___3 =
                      let uu___4 = qualify_to_record l in uu___4 :: out in
                    (ns_opt, uu___3)
                  else (ns_opt, (l :: out))
              | ns ->
                  (match ns_opt with
                   | FStar_Pervasives_Native.Some ns' ->
                       if ns <> ns'
                       then
                         let uu___3 =
                           let uu___4 =
                             FStarC_Class_Show.show
                               FStarC_Ident.showable_lident l in
                           FStarC_Format.fmt2
                             "Field %s of record type was expected to be scoped to namespace %s"
                             uu___4 ns' in
                         FStarC_Errors.raise_error
                           FStarC_Ident.hasrange_lident l
                           FStarC_Errors_Codes.Fatal_MissingFieldInRecord ()
                           (Obj.magic
                              FStarC_Errors_Msg.is_error_message_string)
                           (Obj.magic uu___3)
                       else
                         (let uu___4 =
                            let uu___5 = qualify_to_record l in uu___5 :: out in
                          (ns_opt, uu___4))
                   | FStar_Pervasives_Native.None ->
                       let uu___3 =
                         let uu___4 = qualify_to_record l in uu___4 :: out in
                       ((FStar_Pervasives_Native.Some ns), uu___3))))
      (FStar_Pervasives_Native.None, []) field_names in
  match uu___ with
  | (uu___1, field_names_rev) -> FStarC_List.rev field_names_rev
let desugar_disjunctive_pattern
  (annotated_pats :
    (FStarC_Syntax_Syntax.pat' FStarC_Syntax_Syntax.withinfo_t *
      (FStarC_Syntax_Syntax.bv * FStarC_Syntax_Syntax.term * 'uuuuu)
      Prims.list) Prims.list)
  (when_opt :
    FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax
      FStar_Pervasives_Native.option)
  (branch : FStarC_Syntax_Syntax.term) :
  FStarC_Syntax_Syntax.branch Prims.list=
  FStarC_List.map
    (fun uu___ ->
       match uu___ with
       | (pat, annots) ->
           let branch1 =
             FStarC_List.fold_left
               (fun br uu___1 ->
                  match uu___1 with
                  | (bv, ty, uu___2) ->
                      let lb =
                        let uu___3 = FStarC_Syntax_Syntax.bv_to_name bv in
                        FStarC_Syntax_Util.mk_letbinding
                          (FStar_Pervasives.Inl bv) [] ty
                          FStarC_Parser_Const.effect_Tot_lid uu___3 []
                          br.FStarC_Syntax_Syntax.pos in
                      let branch2 =
                        let uu___3 =
                          let uu___4 = FStarC_Syntax_Syntax.mk_binder bv in
                          [uu___4] in
                        FStarC_Syntax_Subst.close uu___3 branch in
                      FStarC_Syntax_Syntax.mk
                        (FStarC_Syntax_Syntax.Tm_let
                           {
                             FStarC_Syntax_Syntax.lbs = (false, [lb]);
                             FStarC_Syntax_Syntax.body1 = branch2
                           }) br.FStarC_Syntax_Syntax.pos) branch annots in
           FStarC_Syntax_Util.branch (pat, when_opt, branch1)) annotated_pats
let trans_qual (r : FStarC_Range_Type.t)
  (maybe_effect_id : FStarC_Ident.lident FStar_Pervasives_Native.option)
  (uu___ : FStarC_Parser_AST.qualifier) : FStarC_Syntax_Syntax.qualifier=
  match uu___ with
  | FStarC_Parser_AST.Private -> FStarC_Syntax_Syntax.Private
  | FStarC_Parser_AST.Assumption -> FStarC_Syntax_Syntax.Assumption
  | FStarC_Parser_AST.Unfold_for_unification_and_vcgen ->
      FStarC_Syntax_Syntax.Unfold_for_unification_and_vcgen
  | FStarC_Parser_AST.Inline_for_extraction ->
      FStarC_Syntax_Syntax.Inline_for_extraction
  | FStarC_Parser_AST.NoExtract -> FStarC_Syntax_Syntax.NoExtract
  | FStarC_Parser_AST.Irreducible -> FStarC_Syntax_Syntax.Irreducible
  | FStarC_Parser_AST.Logic -> FStarC_Syntax_Syntax.Logic
  | FStarC_Parser_AST.TotalEffect -> FStarC_Syntax_Syntax.TotalEffect
  | FStarC_Parser_AST.Effect_qual -> FStarC_Syntax_Syntax.Effect
  | FStarC_Parser_AST.New -> FStarC_Syntax_Syntax.New
  | FStarC_Parser_AST.Opaque ->
      ((let uu___2 =
          let uu___3 =
            FStarC_Errors_Msg.text
              "The 'opaque' qualifier is deprecated since its use was strangely schizophrenic." in
          let uu___4 =
            let uu___5 =
              FStarC_Errors_Msg.text
                "There were two overloaded uses: (1) Given 'opaque val f : t', the behavior was to exclude the definition of 'f' to the SMT solver. This corresponds roughly to the new 'irreducible' qualifier. (2) Given 'opaque type t = t'', the behavior was to provide the definition of 't' to the SMT solver, but not to inline it, unless absolutely required for unification. This corresponds roughly to the behavior of 'unfoldable' (which is currently the default)." in
            [uu___5] in
          uu___3 :: uu___4 in
        FStarC_Errors.log_issue FStarC_Class_HasRange.hasRange_range r
          FStarC_Errors_Codes.Warning_DeprecatedOpaqueQualifier ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
          (Obj.magic uu___2));
       FStarC_Syntax_Syntax.Visible_default)
  | FStarC_Parser_AST.Reflectable ->
      (match maybe_effect_id with
       | FStar_Pervasives_Native.None ->
           FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
             FStarC_Errors_Codes.Fatal_ReflectOnlySupportedOnEffects ()
             (Obj.magic FStarC_Errors_Msg.is_error_message_string)
             (Obj.magic "Qualifier reflect only supported on effects")
       | FStar_Pervasives_Native.Some effect_id ->
           FStarC_Syntax_Syntax.Reflectable effect_id)
  | FStarC_Parser_AST.Reifiable -> FStarC_Syntax_Syntax.Reifiable
  | FStarC_Parser_AST.Noeq -> FStarC_Syntax_Syntax.Noeq
  | FStarC_Parser_AST.Unopteq -> FStarC_Syntax_Syntax.Unopteq
  | FStarC_Parser_AST.Inline ->
      FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
        FStarC_Errors_Codes.Fatal_UnsupportedQualifier ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic "Unsupported qualifier")
  | FStarC_Parser_AST.Visible ->
      FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
        FStarC_Errors_Codes.Fatal_UnsupportedQualifier ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic "Unsupported qualifier")
let as_imp (uu___ : FStarC_Parser_AST.imp) :
  FStarC_Syntax_Syntax.arg_qualifier FStar_Pervasives_Native.option=
  match uu___ with
  | FStarC_Parser_AST.Hash -> FStarC_Syntax_Syntax.as_aqual_implicit true
  | uu___1 -> FStar_Pervasives_Native.None
let arg_withimp_t (imp : FStarC_Parser_AST.imp) (t : 'uuuuu) :
  ('uuuuu * FStarC_Syntax_Syntax.arg_qualifier
    FStar_Pervasives_Native.option)=
  let uu___ = as_imp imp in (t, uu___)
let contains_binder (binders : FStarC_Parser_AST.binder Prims.list) :
  Prims.bool=
  FStarC_Util.for_some
    (fun b ->
       match b.FStarC_Parser_AST.b with
       | FStarC_Parser_AST.Annotated uu___ -> true
       | uu___ -> false) binders
let rec unparen (t : FStarC_Parser_AST.term) : FStarC_Parser_AST.term=
  match t.FStarC_Parser_AST.tm with
  | FStarC_Parser_AST.Paren t1 -> unparen t1
  | uu___ -> t
let tm_type_z (r : FStarC_Range_Type.range) : FStarC_Parser_AST.term=
  let uu___ =
    let uu___1 = FStarC_Ident.lid_of_path ["Type0"] r in
    FStarC_Parser_AST.Name uu___1 in
  FStarC_Parser_AST.mk_term uu___ r FStarC_Parser_AST.Kind
let tm_type (r : FStarC_Range_Type.range) : FStarC_Parser_AST.term=
  let uu___ =
    let uu___1 = FStarC_Ident.lid_of_path ["Type"] r in
    FStarC_Parser_AST.Name uu___1 in
  FStarC_Parser_AST.mk_term uu___ r FStarC_Parser_AST.Kind
let rec is_comp_type (env : FStarC_Syntax_DsEnv.env)
  (t : FStarC_Parser_AST.term) : Prims.bool=
  let uu___ = let uu___1 = unparen t in uu___1.FStarC_Parser_AST.tm in
  match uu___ with
  | FStarC_Parser_AST.Name l when
      (let uu___1 = FStarC_Syntax_DsEnv.current_module env in
       FStarC_Ident.lid_equals uu___1 FStarC_Parser_Const.prims_lid) &&
        (let s =
           let uu___1 = FStarC_Ident.ident_of_lid l in
           FStarC_Ident.string_of_id uu___1 in
         (s = "Tot") || (s = "GTot"))
      -> true
  | FStarC_Parser_AST.Name l ->
      let uu___1 = FStarC_Syntax_DsEnv.try_lookup_effect_name env l in
      FStar_Pervasives_Native.uu___is_Some uu___1
  | FStarC_Parser_AST.Construct (l, uu___1) ->
      let uu___2 = FStarC_Syntax_DsEnv.try_lookup_effect_name env l in
      FStar_Pervasives_Native.uu___is_Some uu___2
  | FStarC_Parser_AST.App (head, uu___1, uu___2) -> is_comp_type env head
  | FStarC_Parser_AST.Paren t1 -> failwith "impossible"
  | FStarC_Parser_AST.Ascribed (t1, uu___1, uu___2, uu___3) ->
      is_comp_type env t1
  | FStarC_Parser_AST.LetOpen (uu___1, t1) -> is_comp_type env t1
  | uu___1 -> false
let unit_ty (rng : FStarC_Range_Type.range) : FStarC_Parser_AST.term=
  FStarC_Parser_AST.mk_term
    (FStarC_Parser_AST.Name FStarC_Parser_Const.unit_lid) rng
    FStarC_Parser_AST.Type_level
type env_t = FStarC_Syntax_DsEnv.env
type lenv_t = FStarC_Syntax_Syntax.bv Prims.list
let desugar_name'
  (setpos : FStarC_Syntax_Syntax.term -> FStarC_Syntax_Syntax.term)
  (env : env_t) (resolve : Prims.bool) (l : FStarC_Ident.lid) :
  FStarC_Syntax_Syntax.term FStar_Pervasives_Native.option=
  let tm_attrs_opt =
    if resolve
    then FStarC_Syntax_DsEnv.try_lookup_lid_with_attributes env l
    else FStarC_Syntax_DsEnv.try_lookup_lid_with_attributes_no_resolve env l in
  match tm_attrs_opt with
  | FStar_Pervasives_Native.None -> FStar_Pervasives_Native.None
  | FStar_Pervasives_Native.Some (tm, attrs) ->
      let tm1 = setpos tm in FStar_Pervasives_Native.Some tm1
let desugar_name (mk : 'uuuuu)
  (setpos : FStarC_Syntax_Syntax.term -> FStarC_Syntax_Syntax.term)
  (env : env_t) (resolve : Prims.bool) (l : FStarC_Ident.lident) :
  FStarC_Syntax_Syntax.term=
  FStarC_Syntax_DsEnv.fail_or env (desugar_name' setpos env resolve) l
let compile_op_lid (n : Prims.int) (s : Prims.string)
  (r : FStarC_Range_Type.range) : FStarC_Ident.lident=
  let uu___ =
    let uu___1 =
      let uu___2 =
        let uu___3 = FStarC_Parser_AST.compile_op n s r in (uu___3, r) in
      FStarC_Ident.mk_ident uu___2 in
    [uu___1] in
  FStarC_Ident.lid_of_ids uu___
let op_as_term (env : env_t) (arity : Prims.int) (op : FStarC_Ident.ident) :
  FStarC_Syntax_Syntax.term FStar_Pervasives_Native.option=
  let r l =
    let uu___ =
      let uu___1 =
        let uu___2 =
          let uu___3 = FStarC_Ident.range_of_id op in
          FStarC_Ident.set_lid_range l uu___3 in
        FStarC_Syntax_Syntax.lid_and_dd_as_fv uu___2
          FStar_Pervasives_Native.None in
      FStarC_Syntax_Syntax.fv_to_tm uu___1 in
    FStar_Pervasives_Native.Some uu___ in
  let fallback uu___ =
    let uu___1 = FStarC_Ident.string_of_id op in
    match uu___1 with
    | "=" -> r FStarC_Parser_Const.op_Eq
    | "<" -> r FStarC_Parser_Const.op_LT
    | "<=" -> r FStarC_Parser_Const.op_LTE
    | ">" -> r FStarC_Parser_Const.op_GT
    | ">=" -> r FStarC_Parser_Const.op_GTE
    | "&&" -> r FStarC_Parser_Const.op_And
    | "||" -> r FStarC_Parser_Const.op_Or
    | "+" -> r FStarC_Parser_Const.op_Addition
    | "-" when arity = Prims.int_one -> r FStarC_Parser_Const.op_Minus
    | "-" -> r FStarC_Parser_Const.op_Subtraction
    | "/" -> r FStarC_Parser_Const.op_Division
    | "%" -> r FStarC_Parser_Const.op_Modulus
    | "@" ->
        ((let uu___3 =
            let uu___4 =
              FStarC_Errors_Msg.text
                "The operator '@' has been resolved to FStar.List.Tot.append even though FStar.List.Tot is not in scope. Please add an 'open FStar.List.Tot' to stop relying on this deprecated, special treatment of '@'." in
            [uu___4] in
          FStarC_Errors.log_issue FStarC_Ident.hasrange_ident op
            FStarC_Errors_Codes.Warning_DeprecatedGeneric ()
            (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
            (Obj.magic uu___3));
         r FStarC_Parser_Const.list_tot_append_lid)
    | "<>" -> r FStarC_Parser_Const.op_notEq
    | "~" -> r FStarC_Parser_Const.not_lid
    | "==" -> r FStarC_Parser_Const.eq2_lid
    | "<<" -> r FStarC_Parser_Const.precedes_lid
    | "/\\" -> r FStarC_Parser_Const.and_lid
    | "\\/" -> r FStarC_Parser_Const.or_lid
    | "==>" -> r FStarC_Parser_Const.imp_lid
    | "<==>" -> r FStarC_Parser_Const.iff_lid
    | uu___2 -> FStar_Pervasives_Native.None in
  let uu___ =
    let uu___1 =
      let uu___2 = FStarC_Ident.string_of_id op in
      let uu___3 = FStarC_Ident.range_of_id op in
      compile_op_lid arity uu___2 uu___3 in
    desugar_name'
      (fun t ->
         let uu___2 = FStarC_Ident.range_of_id op in
         {
           FStarC_Syntax_Syntax.n = (t.FStarC_Syntax_Syntax.n);
           FStarC_Syntax_Syntax.pos = uu___2;
           FStarC_Syntax_Syntax.vars = (t.FStarC_Syntax_Syntax.vars);
           FStarC_Syntax_Syntax.hash_code =
             (t.FStarC_Syntax_Syntax.hash_code)
         }) env true uu___1 in
  match uu___ with
  | FStar_Pervasives_Native.Some t -> FStar_Pervasives_Native.Some t
  | uu___1 -> fallback ()
let head_and_args (t : FStarC_Parser_AST.term) :
  (FStarC_Parser_AST.term * (FStarC_Parser_AST.term * FStarC_Parser_AST.imp)
    Prims.list)=
  let rec aux args t1 =
    let uu___ = let uu___1 = unparen t1 in uu___1.FStarC_Parser_AST.tm in
    match uu___ with
    | FStarC_Parser_AST.App (t2, arg, imp) -> aux ((arg, imp) :: args) t2
    | FStarC_Parser_AST.Construct (l, args') ->
        ({
           FStarC_Parser_AST.tm = (FStarC_Parser_AST.Name l);
           FStarC_Parser_AST.range = (t1.FStarC_Parser_AST.range);
           FStarC_Parser_AST.level = (t1.FStarC_Parser_AST.level)
         }, (FStarC_List.op_At args' args))
    | uu___1 -> (t1, args) in
  aux [] t
let rec uncurry (bs : FStarC_Parser_AST.binder Prims.list)
  (t : FStarC_Parser_AST.term) :
  (FStarC_Parser_AST.binder Prims.list * FStarC_Parser_AST.term)=
  match t.FStarC_Parser_AST.tm with
  | FStarC_Parser_AST.Product (binders, t1) ->
      uncurry (FStarC_List.op_At bs binders) t1
  | uu___ -> (bs, t)
let rec is_var_pattern (p : FStarC_Parser_AST.pattern) : Prims.bool=
  match p.FStarC_Parser_AST.pat with
  | FStarC_Parser_AST.PatWild uu___ -> true
  | FStarC_Parser_AST.PatVar uu___ -> true
  | FStarC_Parser_AST.PatAscribed (p1, uu___) -> is_var_pattern p1
  | uu___ -> false
let rec is_app_pattern (p : FStarC_Parser_AST.pattern) : Prims.bool=
  match p.FStarC_Parser_AST.pat with
  | FStarC_Parser_AST.PatAscribed (p1, uu___) -> is_app_pattern p1
  | FStarC_Parser_AST.PatApp
      ({ FStarC_Parser_AST.pat = FStarC_Parser_AST.PatVar uu___;
         FStarC_Parser_AST.prange = uu___1;_},
       uu___2)
      -> true
  | uu___ -> false
let replace_unit_pattern (p : FStarC_Parser_AST.pattern) :
  FStarC_Parser_AST.pattern=
  match p.FStarC_Parser_AST.pat with
  | FStarC_Parser_AST.PatConst (FStarC_Const.Const_unit) ->
      let uu___ =
        let uu___1 =
          let uu___2 =
            FStarC_Parser_AST.mk_pattern
              (FStarC_Parser_AST.PatWild (FStar_Pervasives_Native.None, []))
              p.FStarC_Parser_AST.prange in
          let uu___3 =
            let uu___4 = unit_ty p.FStarC_Parser_AST.prange in
            (uu___4, FStar_Pervasives_Native.None) in
          (uu___2, uu___3) in
        FStarC_Parser_AST.PatAscribed uu___1 in
      FStarC_Parser_AST.mk_pattern uu___ p.FStarC_Parser_AST.prange
  | uu___ -> p
let rec destruct_app_pattern (env : env_t) (is_top_level : Prims.bool)
  (p : FStarC_Parser_AST.pattern) :
  ((FStarC_Ident.ident, FStarC_Ident.lid) FStar_Pervasives.either *
    FStarC_Parser_AST.pattern Prims.list * (FStarC_Parser_AST.term *
    FStarC_Parser_AST.term FStar_Pervasives_Native.option)
    FStar_Pervasives_Native.option)=
  match p.FStarC_Parser_AST.pat with
  | FStarC_Parser_AST.PatAscribed (p1, t) ->
      let uu___ = destruct_app_pattern env is_top_level p1 in
      (match uu___ with
       | (name, args, uu___1) ->
           (name, args, (FStar_Pervasives_Native.Some t)))
  | FStarC_Parser_AST.PatApp
      ({
         FStarC_Parser_AST.pat = FStarC_Parser_AST.PatVar (id, uu___, uu___1);
         FStarC_Parser_AST.prange = uu___2;_},
       args)
      when is_top_level ->
      let uu___3 =
        let uu___4 = FStarC_Syntax_DsEnv.qualify env id in
        FStar_Pervasives.Inr uu___4 in
      (uu___3, args, FStar_Pervasives_Native.None)
  | FStarC_Parser_AST.PatApp
      ({
         FStarC_Parser_AST.pat = FStarC_Parser_AST.PatVar (id, uu___, uu___1);
         FStarC_Parser_AST.prange = uu___2;_},
       args)
      -> ((FStar_Pervasives.Inl id), args, FStar_Pervasives_Native.None)
  | uu___ -> failwith "Not an app pattern"
let rec gather_pattern_bound_vars_maybe_top
  (uu___1 : FStarC_Ident.ident FStarC_FlatSet.t)
  (uu___ : FStarC_Parser_AST.pattern) : FStarC_Ident.ident FStarC_FlatSet.t=
  (fun acc p ->
     let gather_pattern_bound_vars_from_list =
       FStarC_List.fold_left gather_pattern_bound_vars_maybe_top acc in
     match p.FStarC_Parser_AST.pat with
     | FStarC_Parser_AST.PatWild uu___ -> Obj.magic (Obj.repr acc)
     | FStarC_Parser_AST.PatConst uu___ -> Obj.magic (Obj.repr acc)
     | FStarC_Parser_AST.PatVQuote uu___ -> Obj.magic (Obj.repr acc)
     | FStarC_Parser_AST.PatName uu___ -> Obj.magic (Obj.repr acc)
     | FStarC_Parser_AST.PatRest -> Obj.magic (Obj.repr acc)
     | FStarC_Parser_AST.PatOp uu___ -> Obj.magic (Obj.repr acc)
     | FStarC_Parser_AST.PatApp (phead, pats) ->
         Obj.magic
           (Obj.repr (gather_pattern_bound_vars_from_list (phead :: pats)))
     | FStarC_Parser_AST.PatVar (x, uu___, uu___1) ->
         Obj.magic
           (Obj.repr
              (FStarC_Class_Setlike.add ()
                 (Obj.magic
                    (FStarC_FlatSet.setlike_flat_set
                       FStarC_Syntax_Syntax.ord_ident)) x (Obj.magic acc)))
     | FStarC_Parser_AST.PatList pats ->
         Obj.magic (Obj.repr (gather_pattern_bound_vars_from_list pats))
     | FStarC_Parser_AST.PatTuple (pats, uu___) ->
         Obj.magic (Obj.repr (gather_pattern_bound_vars_from_list pats))
     | FStarC_Parser_AST.PatOr pats ->
         Obj.magic (Obj.repr (gather_pattern_bound_vars_from_list pats))
     | FStarC_Parser_AST.PatRecord guarded_pats ->
         Obj.magic
           (Obj.repr
              (let uu___ =
                 FStarC_List.map FStar_Pervasives_Native.snd guarded_pats in
               gather_pattern_bound_vars_from_list uu___))
     | FStarC_Parser_AST.PatAscribed (pat, uu___) ->
         Obj.magic (Obj.repr (gather_pattern_bound_vars_maybe_top acc pat)))
    uu___1 uu___
let gather_pattern_bound_vars :
  FStarC_Parser_AST.pattern -> FStarC_Ident.ident FStarC_FlatSet.t=
  let acc =
    Obj.magic
      (FStarC_Class_Setlike.empty ()
         (Obj.magic
            (FStarC_FlatSet.setlike_flat_set FStarC_Syntax_Syntax.ord_ident))
         ()) in
  fun p -> gather_pattern_bound_vars_maybe_top acc p
type bnd =
  | LocalBinder of (FStarC_Syntax_Syntax.bv * FStarC_Syntax_Syntax.bqual *
  FStarC_Syntax_Syntax.term Prims.list) 
  | LetBinder of (FStarC_Ident.lident * (FStarC_Syntax_Syntax.term *
  FStarC_Syntax_Syntax.term FStar_Pervasives_Native.option)) 
let uu___is_LocalBinder (projectee : bnd) : Prims.bool=
  match projectee with | LocalBinder _0 -> true | uu___ -> false
let __proj__LocalBinder__item___0 (projectee : bnd) :
  (FStarC_Syntax_Syntax.bv * FStarC_Syntax_Syntax.bqual *
    FStarC_Syntax_Syntax.term Prims.list)=
  match projectee with | LocalBinder _0 -> _0
let uu___is_LetBinder (projectee : bnd) : Prims.bool=
  match projectee with | LetBinder _0 -> true | uu___ -> false
let __proj__LetBinder__item___0 (projectee : bnd) :
  (FStarC_Ident.lident * (FStarC_Syntax_Syntax.term *
    FStarC_Syntax_Syntax.term FStar_Pervasives_Native.option))=
  match projectee with | LetBinder _0 -> _0
let is_implicit (b : bnd) : Prims.bool=
  match b with
  | LocalBinder
      (uu___, FStar_Pervasives_Native.Some (FStarC_Syntax_Syntax.Implicit
       uu___1), uu___2)
      -> true
  | uu___ -> false
let binder_of_bnd (uu___ : bnd) :
  (FStarC_Syntax_Syntax.bv * FStarC_Syntax_Syntax.bqual *
    FStarC_Syntax_Syntax.term Prims.list)=
  match uu___ with
  | LocalBinder (a, aq, attrs) -> (a, aq, attrs)
  | uu___1 -> failwith "Impossible"
let mk_lb
  (uu___ :
    (FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax Prims.list *
      (FStarC_Syntax_Syntax.bv, FStarC_Syntax_Syntax.fv)
      FStar_Pervasives.either * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax * FStarC_Range_Type.range))
  : FStarC_Syntax_Syntax.letbinding=
  match uu___ with
  | (attrs, n, t, e, pos) ->
      let uu___1 = FStarC_Parser_Const.effect_ALL_lid () in
      {
        FStarC_Syntax_Syntax.lbname = n;
        FStarC_Syntax_Syntax.lbunivs = [];
        FStarC_Syntax_Syntax.lbtyp = t;
        FStarC_Syntax_Syntax.lbeff = uu___1;
        FStarC_Syntax_Syntax.lbdef = e;
        FStarC_Syntax_Syntax.lbattrs = attrs;
        FStarC_Syntax_Syntax.lbpos = pos
      }
let no_annot_abs (bs : FStarC_Syntax_Syntax.binders)
  (t : FStarC_Syntax_Syntax.term) : FStarC_Syntax_Syntax.term=
  FStarC_Syntax_Util.abs bs t FStar_Pervasives_Native.None
let rec generalize_annotated_univs (s : FStarC_Syntax_Syntax.sigelt) :
  FStarC_Syntax_Syntax.sigelt=
  let vars = FStarC_Effect.mk_ref [] in
  let seen =
    let uu___ =
      Obj.magic
        (FStarC_Class_Setlike.empty ()
           (Obj.magic
              (FStarC_RBSet.setlike_rbset FStarC_Syntax_Syntax.ord_ident)) ()) in
    FStarC_Effect.mk_ref uu___ in
  let reg u =
    let uu___ =
      let uu___1 =
        let uu___2 = FStarC_Effect.op_Bang seen in
        FStarC_Class_Setlike.mem ()
          (Obj.magic
             (FStarC_RBSet.setlike_rbset FStarC_Syntax_Syntax.ord_ident)) u
          (Obj.magic uu___2) in
      Prims.op_Negation uu___1 in
    if uu___
    then
      ((let uu___2 =
          let uu___3 = FStarC_Effect.op_Bang seen in
          Obj.magic
            (FStarC_Class_Setlike.add ()
               (Obj.magic
                  (FStarC_RBSet.setlike_rbset FStarC_Syntax_Syntax.ord_ident))
               u (Obj.magic uu___3)) in
        FStarC_Effect.op_Colon_Equals seen uu___2);
       (let uu___2 = let uu___3 = FStarC_Effect.op_Bang vars in u :: uu___3 in
        FStarC_Effect.op_Colon_Equals vars uu___2))
    else () in
  let get uu___ =
    let uu___1 = FStarC_Effect.op_Bang vars in FStarC_List.rev uu___1 in
  let uu___ =
    FStarC_Syntax_Visit.visit_sigelt false (fun t -> t)
      (fun u ->
         (match u with
          | FStarC_Syntax_Syntax.U_name nm -> reg nm
          | uu___3 -> ());
         u) s in
  let unames = get () in
  match s.FStarC_Syntax_Syntax.sigel with
  | FStarC_Syntax_Syntax.Sig_inductive_typ uu___1 ->
      failwith
        "Impossible: collect_annotated_universes: bare data/type constructor"
  | FStarC_Syntax_Syntax.Sig_datacon uu___1 ->
      failwith
        "Impossible: collect_annotated_universes: bare data/type constructor"
  | FStarC_Syntax_Syntax.Sig_bundle
      { FStarC_Syntax_Syntax.ses = sigs; FStarC_Syntax_Syntax.lids = lids;_}
      ->
      let usubst = FStarC_Syntax_Subst.univ_var_closing unames in
      let uu___1 =
        let uu___2 =
          let uu___3 =
            FStarC_List.map
              (fun se ->
                 match se.FStarC_Syntax_Syntax.sigel with
                 | FStarC_Syntax_Syntax.Sig_inductive_typ
                     { FStarC_Syntax_Syntax.lid = lid;
                       FStarC_Syntax_Syntax.us = uu___4;
                       FStarC_Syntax_Syntax.params = bs;
                       FStarC_Syntax_Syntax.num_uniform_params = num_uniform;
                       FStarC_Syntax_Syntax.t = t;
                       FStarC_Syntax_Syntax.mutuals = lids1;
                       FStarC_Syntax_Syntax.ds = lids2;
                       FStarC_Syntax_Syntax.injective_type_params = uu___5;_}
                     ->
                     let uu___6 =
                       let uu___7 =
                         let uu___8 =
                           FStarC_Syntax_Subst.subst_binders usubst bs in
                         let uu___9 =
                           let uu___10 =
                             FStarC_Syntax_Subst.shift_subst
                               (FStarC_List.length bs) usubst in
                           FStarC_Syntax_Subst.subst uu___10 t in
                         {
                           FStarC_Syntax_Syntax.lid = lid;
                           FStarC_Syntax_Syntax.us = unames;
                           FStarC_Syntax_Syntax.params = uu___8;
                           FStarC_Syntax_Syntax.num_uniform_params =
                             num_uniform;
                           FStarC_Syntax_Syntax.t = uu___9;
                           FStarC_Syntax_Syntax.mutuals = lids1;
                           FStarC_Syntax_Syntax.ds = lids2;
                           FStarC_Syntax_Syntax.injective_type_params = false
                         } in
                       FStarC_Syntax_Syntax.Sig_inductive_typ uu___7 in
                     {
                       FStarC_Syntax_Syntax.sigel = uu___6;
                       FStarC_Syntax_Syntax.sigrng =
                         (se.FStarC_Syntax_Syntax.sigrng);
                       FStarC_Syntax_Syntax.sigquals =
                         (se.FStarC_Syntax_Syntax.sigquals);
                       FStarC_Syntax_Syntax.sigmeta =
                         (se.FStarC_Syntax_Syntax.sigmeta);
                       FStarC_Syntax_Syntax.sigattrs =
                         (se.FStarC_Syntax_Syntax.sigattrs);
                       FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                         (se.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
                       FStarC_Syntax_Syntax.sigopts =
                         (se.FStarC_Syntax_Syntax.sigopts)
                     }
                 | FStarC_Syntax_Syntax.Sig_datacon
                     { FStarC_Syntax_Syntax.lid1 = lid;
                       FStarC_Syntax_Syntax.us1 = uu___4;
                       FStarC_Syntax_Syntax.t1 = t;
                       FStarC_Syntax_Syntax.ty_lid = tlid;
                       FStarC_Syntax_Syntax.num_ty_params = n;
                       FStarC_Syntax_Syntax.mutuals1 = lids1;
                       FStarC_Syntax_Syntax.injective_type_params1 = uu___5;
                       FStarC_Syntax_Syntax.proj_disc_lids = proj_disc_lids;_}
                     ->
                     let uu___6 =
                       let uu___7 =
                         let uu___8 = FStarC_Syntax_Subst.subst usubst t in
                         {
                           FStarC_Syntax_Syntax.lid1 = lid;
                           FStarC_Syntax_Syntax.us1 = unames;
                           FStarC_Syntax_Syntax.t1 = uu___8;
                           FStarC_Syntax_Syntax.ty_lid = tlid;
                           FStarC_Syntax_Syntax.num_ty_params = n;
                           FStarC_Syntax_Syntax.mutuals1 = lids1;
                           FStarC_Syntax_Syntax.injective_type_params1 =
                             false;
                           FStarC_Syntax_Syntax.proj_disc_lids =
                             proj_disc_lids
                         } in
                       FStarC_Syntax_Syntax.Sig_datacon uu___7 in
                     {
                       FStarC_Syntax_Syntax.sigel = uu___6;
                       FStarC_Syntax_Syntax.sigrng =
                         (se.FStarC_Syntax_Syntax.sigrng);
                       FStarC_Syntax_Syntax.sigquals =
                         (se.FStarC_Syntax_Syntax.sigquals);
                       FStarC_Syntax_Syntax.sigmeta =
                         (se.FStarC_Syntax_Syntax.sigmeta);
                       FStarC_Syntax_Syntax.sigattrs =
                         (se.FStarC_Syntax_Syntax.sigattrs);
                       FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                         (se.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
                       FStarC_Syntax_Syntax.sigopts =
                         (se.FStarC_Syntax_Syntax.sigopts)
                     }
                 | uu___4 ->
                     failwith
                       "Impossible: collect_annotated_universes: Sig_bundle should not have a non data/type sigelt")
              sigs in
          {
            FStarC_Syntax_Syntax.ses = uu___3;
            FStarC_Syntax_Syntax.lids = lids
          } in
        FStarC_Syntax_Syntax.Sig_bundle uu___2 in
      {
        FStarC_Syntax_Syntax.sigel = uu___1;
        FStarC_Syntax_Syntax.sigrng = (s.FStarC_Syntax_Syntax.sigrng);
        FStarC_Syntax_Syntax.sigquals = (s.FStarC_Syntax_Syntax.sigquals);
        FStarC_Syntax_Syntax.sigmeta = (s.FStarC_Syntax_Syntax.sigmeta);
        FStarC_Syntax_Syntax.sigattrs = (s.FStarC_Syntax_Syntax.sigattrs);
        FStarC_Syntax_Syntax.sigopens_and_abbrevs =
          (s.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
        FStarC_Syntax_Syntax.sigopts = (s.FStarC_Syntax_Syntax.sigopts)
      }
  | FStarC_Syntax_Syntax.Sig_declare_typ
      { FStarC_Syntax_Syntax.lid2 = lid; FStarC_Syntax_Syntax.us2 = uu___1;
        FStarC_Syntax_Syntax.t2 = t;_}
      ->
      let uu___2 =
        let uu___3 =
          let uu___4 = FStarC_Syntax_Subst.close_univ_vars unames t in
          {
            FStarC_Syntax_Syntax.lid2 = lid;
            FStarC_Syntax_Syntax.us2 = unames;
            FStarC_Syntax_Syntax.t2 = uu___4
          } in
        FStarC_Syntax_Syntax.Sig_declare_typ uu___3 in
      {
        FStarC_Syntax_Syntax.sigel = uu___2;
        FStarC_Syntax_Syntax.sigrng = (s.FStarC_Syntax_Syntax.sigrng);
        FStarC_Syntax_Syntax.sigquals = (s.FStarC_Syntax_Syntax.sigquals);
        FStarC_Syntax_Syntax.sigmeta = (s.FStarC_Syntax_Syntax.sigmeta);
        FStarC_Syntax_Syntax.sigattrs = (s.FStarC_Syntax_Syntax.sigattrs);
        FStarC_Syntax_Syntax.sigopens_and_abbrevs =
          (s.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
        FStarC_Syntax_Syntax.sigopts = (s.FStarC_Syntax_Syntax.sigopts)
      }
  | FStarC_Syntax_Syntax.Sig_let
      { FStarC_Syntax_Syntax.lbs1 = (b, lbs);
        FStarC_Syntax_Syntax.lids1 = lids;_}
      ->
      let usubst = FStarC_Syntax_Subst.univ_var_closing unames in
      let uu___1 =
        let uu___2 =
          let uu___3 =
            let uu___4 =
              FStarC_List.map
                (fun lb ->
                   let uu___5 =
                     FStarC_Syntax_Subst.subst usubst
                       lb.FStarC_Syntax_Syntax.lbtyp in
                   let uu___6 =
                     FStarC_Syntax_Subst.subst usubst
                       lb.FStarC_Syntax_Syntax.lbdef in
                   {
                     FStarC_Syntax_Syntax.lbname =
                       (lb.FStarC_Syntax_Syntax.lbname);
                     FStarC_Syntax_Syntax.lbunivs = unames;
                     FStarC_Syntax_Syntax.lbtyp = uu___5;
                     FStarC_Syntax_Syntax.lbeff =
                       (lb.FStarC_Syntax_Syntax.lbeff);
                     FStarC_Syntax_Syntax.lbdef = uu___6;
                     FStarC_Syntax_Syntax.lbattrs =
                       (lb.FStarC_Syntax_Syntax.lbattrs);
                     FStarC_Syntax_Syntax.lbpos =
                       (lb.FStarC_Syntax_Syntax.lbpos)
                   }) lbs in
            (b, uu___4) in
          {
            FStarC_Syntax_Syntax.lbs1 = uu___3;
            FStarC_Syntax_Syntax.lids1 = lids
          } in
        FStarC_Syntax_Syntax.Sig_let uu___2 in
      {
        FStarC_Syntax_Syntax.sigel = uu___1;
        FStarC_Syntax_Syntax.sigrng = (s.FStarC_Syntax_Syntax.sigrng);
        FStarC_Syntax_Syntax.sigquals = (s.FStarC_Syntax_Syntax.sigquals);
        FStarC_Syntax_Syntax.sigmeta = (s.FStarC_Syntax_Syntax.sigmeta);
        FStarC_Syntax_Syntax.sigattrs = (s.FStarC_Syntax_Syntax.sigattrs);
        FStarC_Syntax_Syntax.sigopens_and_abbrevs =
          (s.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
        FStarC_Syntax_Syntax.sigopts = (s.FStarC_Syntax_Syntax.sigopts)
      }
  | FStarC_Syntax_Syntax.Sig_assume
      { FStarC_Syntax_Syntax.lid3 = lid; FStarC_Syntax_Syntax.us3 = uu___1;
        FStarC_Syntax_Syntax.phi1 = fml;_}
      ->
      let uu___2 =
        let uu___3 =
          let uu___4 = FStarC_Syntax_Subst.close_univ_vars unames fml in
          {
            FStarC_Syntax_Syntax.lid3 = lid;
            FStarC_Syntax_Syntax.us3 = unames;
            FStarC_Syntax_Syntax.phi1 = uu___4
          } in
        FStarC_Syntax_Syntax.Sig_assume uu___3 in
      {
        FStarC_Syntax_Syntax.sigel = uu___2;
        FStarC_Syntax_Syntax.sigrng = (s.FStarC_Syntax_Syntax.sigrng);
        FStarC_Syntax_Syntax.sigquals = (s.FStarC_Syntax_Syntax.sigquals);
        FStarC_Syntax_Syntax.sigmeta = (s.FStarC_Syntax_Syntax.sigmeta);
        FStarC_Syntax_Syntax.sigattrs = (s.FStarC_Syntax_Syntax.sigattrs);
        FStarC_Syntax_Syntax.sigopens_and_abbrevs =
          (s.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
        FStarC_Syntax_Syntax.sigopts = (s.FStarC_Syntax_Syntax.sigopts)
      }
  | FStarC_Syntax_Syntax.Sig_effect_abbrev
      { FStarC_Syntax_Syntax.lid4 = lid; FStarC_Syntax_Syntax.us4 = uu___1;
        FStarC_Syntax_Syntax.bs2 = bs; FStarC_Syntax_Syntax.comp1 = c;
        FStarC_Syntax_Syntax.cflags = flags;_}
      ->
      let usubst = FStarC_Syntax_Subst.univ_var_closing unames in
      let uu___2 =
        let uu___3 =
          let uu___4 = FStarC_Syntax_Subst.subst_binders usubst bs in
          let uu___5 = FStarC_Syntax_Subst.subst_comp usubst c in
          {
            FStarC_Syntax_Syntax.lid4 = lid;
            FStarC_Syntax_Syntax.us4 = unames;
            FStarC_Syntax_Syntax.bs2 = uu___4;
            FStarC_Syntax_Syntax.comp1 = uu___5;
            FStarC_Syntax_Syntax.cflags = flags
          } in
        FStarC_Syntax_Syntax.Sig_effect_abbrev uu___3 in
      {
        FStarC_Syntax_Syntax.sigel = uu___2;
        FStarC_Syntax_Syntax.sigrng = (s.FStarC_Syntax_Syntax.sigrng);
        FStarC_Syntax_Syntax.sigquals = (s.FStarC_Syntax_Syntax.sigquals);
        FStarC_Syntax_Syntax.sigmeta = (s.FStarC_Syntax_Syntax.sigmeta);
        FStarC_Syntax_Syntax.sigattrs = (s.FStarC_Syntax_Syntax.sigattrs);
        FStarC_Syntax_Syntax.sigopens_and_abbrevs =
          (s.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
        FStarC_Syntax_Syntax.sigopts = (s.FStarC_Syntax_Syntax.sigopts)
      }
  | FStarC_Syntax_Syntax.Sig_fail
      { FStarC_Syntax_Syntax.errs = errs; FStarC_Syntax_Syntax.rng1 = rng;
        FStarC_Syntax_Syntax.fail_in_lax = lax;
        FStarC_Syntax_Syntax.ses1 = ses;_}
      ->
      let uu___1 =
        let uu___2 =
          let uu___3 = FStarC_List.map generalize_annotated_univs ses in
          {
            FStarC_Syntax_Syntax.errs = errs;
            FStarC_Syntax_Syntax.rng1 = rng;
            FStarC_Syntax_Syntax.fail_in_lax = lax;
            FStarC_Syntax_Syntax.ses1 = uu___3
          } in
        FStarC_Syntax_Syntax.Sig_fail uu___2 in
      {
        FStarC_Syntax_Syntax.sigel = uu___1;
        FStarC_Syntax_Syntax.sigrng = (s.FStarC_Syntax_Syntax.sigrng);
        FStarC_Syntax_Syntax.sigquals = (s.FStarC_Syntax_Syntax.sigquals);
        FStarC_Syntax_Syntax.sigmeta = (s.FStarC_Syntax_Syntax.sigmeta);
        FStarC_Syntax_Syntax.sigattrs = (s.FStarC_Syntax_Syntax.sigattrs);
        FStarC_Syntax_Syntax.sigopens_and_abbrevs =
          (s.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
        FStarC_Syntax_Syntax.sigopts = (s.FStarC_Syntax_Syntax.sigopts)
      }
  | FStarC_Syntax_Syntax.Sig_new_effect ed ->
      let generalize_annotated_univs_signature s1 =
        match s1 with
        | FStarC_Syntax_Syntax.Layered_eff_sig (n, (uu___1, t)) ->
            let uvs =
              let uu___2 = FStarC_Syntax_Free.univnames t in
              FStarC_Class_Setlike.elems ()
                (Obj.magic
                   (FStarC_FlatSet.setlike_flat_set
                      FStarC_Syntax_Syntax.ord_ident)) (Obj.magic uu___2) in
            let usubst = FStarC_Syntax_Subst.univ_var_closing uvs in
            let uu___2 =
              let uu___3 =
                let uu___4 = FStarC_Syntax_Subst.subst usubst t in
                (uvs, uu___4) in
              (n, uu___3) in
            FStarC_Syntax_Syntax.Layered_eff_sig uu___2
        | FStarC_Syntax_Syntax.WP_eff_sig (uu___1, t) ->
            let uvs =
              let uu___2 = FStarC_Syntax_Free.univnames t in
              FStarC_Class_Setlike.elems ()
                (Obj.magic
                   (FStarC_FlatSet.setlike_flat_set
                      FStarC_Syntax_Syntax.ord_ident)) (Obj.magic uu___2) in
            let usubst = FStarC_Syntax_Subst.univ_var_closing uvs in
            let uu___2 =
              let uu___3 = FStarC_Syntax_Subst.subst usubst t in
              (uvs, uu___3) in
            FStarC_Syntax_Syntax.WP_eff_sig uu___2 in
      let uu___1 =
        let uu___2 =
          let uu___3 =
            generalize_annotated_univs_signature
              ed.FStarC_Syntax_Syntax.signature in
          {
            FStarC_Syntax_Syntax.mname = (ed.FStarC_Syntax_Syntax.mname);
            FStarC_Syntax_Syntax.cattributes =
              (ed.FStarC_Syntax_Syntax.cattributes);
            FStarC_Syntax_Syntax.univs = (ed.FStarC_Syntax_Syntax.univs);
            FStarC_Syntax_Syntax.binders = (ed.FStarC_Syntax_Syntax.binders);
            FStarC_Syntax_Syntax.signature = uu___3;
            FStarC_Syntax_Syntax.combinators =
              (ed.FStarC_Syntax_Syntax.combinators);
            FStarC_Syntax_Syntax.actions = (ed.FStarC_Syntax_Syntax.actions);
            FStarC_Syntax_Syntax.eff_attrs =
              (ed.FStarC_Syntax_Syntax.eff_attrs);
            FStarC_Syntax_Syntax.extraction_mode =
              (ed.FStarC_Syntax_Syntax.extraction_mode)
          } in
        FStarC_Syntax_Syntax.Sig_new_effect uu___2 in
      {
        FStarC_Syntax_Syntax.sigel = uu___1;
        FStarC_Syntax_Syntax.sigrng = (s.FStarC_Syntax_Syntax.sigrng);
        FStarC_Syntax_Syntax.sigquals = (s.FStarC_Syntax_Syntax.sigquals);
        FStarC_Syntax_Syntax.sigmeta = (s.FStarC_Syntax_Syntax.sigmeta);
        FStarC_Syntax_Syntax.sigattrs = (s.FStarC_Syntax_Syntax.sigattrs);
        FStarC_Syntax_Syntax.sigopens_and_abbrevs =
          (s.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
        FStarC_Syntax_Syntax.sigopts = (s.FStarC_Syntax_Syntax.sigopts)
      }
  | FStarC_Syntax_Syntax.Sig_sub_effect uu___1 -> s
  | FStarC_Syntax_Syntax.Sig_polymonadic_bind uu___1 -> s
  | FStarC_Syntax_Syntax.Sig_polymonadic_subcomp uu___1 -> s
  | FStarC_Syntax_Syntax.Sig_splice uu___1 -> s
  | FStarC_Syntax_Syntax.Sig_pragma uu___1 -> s
let is_special_effect_combinator (uu___ : Prims.string) : Prims.bool=
  match uu___ with
  | "lift1" -> true
  | "lift2" -> true
  | "pure" -> true
  | "app" -> true
  | "push" -> true
  | "wp_if_then_else" -> true
  | "wp_assert" -> true
  | "wp_assume" -> true
  | "wp_close" -> true
  | "stronger" -> true
  | "ite_wp" -> true
  | "wp_trivial" -> true
  | "ctx" -> true
  | "gctx" -> true
  | "lift_from_pure" -> true
  | "return_wp" -> true
  | "return_elab" -> true
  | "bind_wp" -> true
  | "bind_elab" -> true
  | "repr" -> true
  | "post" -> true
  | "pre" -> true
  | "wp" -> true
  | uu___1 -> false
let rec sum_to_universe (u : FStarC_Syntax_Syntax.universe) (n : Prims.int) :
  FStarC_Syntax_Syntax.universe=
  if n = Prims.int_zero
  then u
  else
    (let uu___1 = sum_to_universe u (n - Prims.int_one) in
     FStarC_Syntax_Syntax.U_succ uu___1)
let int_to_universe (n : Prims.int) : FStarC_Syntax_Syntax.universe=
  sum_to_universe FStarC_Syntax_Syntax.U_zero n
let rec desugar_maybe_non_constant_universe (t : FStarC_Parser_AST.term) :
  (Prims.int, FStarC_Syntax_Syntax.universe) FStar_Pervasives.either=
  let uu___ = let uu___1 = unparen t in uu___1.FStarC_Parser_AST.tm in
  match uu___ with
  | FStarC_Parser_AST.Wild ->
      FStar_Pervasives.Inr FStarC_Syntax_Syntax.U_unknown
  | FStarC_Parser_AST.Uvar u ->
      FStar_Pervasives.Inr (FStarC_Syntax_Syntax.U_name u)
  | FStarC_Parser_AST.Const (FStarC_Const.Const_int (repr, uu___1)) ->
      let n = FStarC_Util.int_of_string repr in
      (if n < Prims.int_zero
       then
         FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term t
           FStarC_Errors_Codes.Fatal_NegativeUniverseConstFatal_NotSupported
           () (Obj.magic FStarC_Errors_Msg.is_error_message_string)
           (Obj.magic
              (Prims.strcat
                 "Negative universe constant  are not supported : " repr))
       else ();
       FStar_Pervasives.Inl n)
  | FStarC_Parser_AST.Op (_op_plus, t1::t2::[]) ->
      let u1 = desugar_maybe_non_constant_universe t1 in
      let u2 = desugar_maybe_non_constant_universe t2 in
      (match (u1, u2) with
       | (FStar_Pervasives.Inl n1, FStar_Pervasives.Inl n2) ->
           FStar_Pervasives.Inl (n1 + n2)
       | (FStar_Pervasives.Inl n, FStar_Pervasives.Inr u) ->
           let uu___2 = sum_to_universe u n in FStar_Pervasives.Inr uu___2
       | (FStar_Pervasives.Inr u, FStar_Pervasives.Inl n) ->
           let uu___2 = sum_to_universe u n in FStar_Pervasives.Inr uu___2
       | (FStar_Pervasives.Inr u11, FStar_Pervasives.Inr u21) ->
           let uu___2 =
             let uu___3 =
               FStarC_Class_Show.show FStarC_Parser_AST.showable_term t in
             Prims.strcat
               "This universe might contain a sum of two universe variables "
               uu___3 in
           FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term t
             FStarC_Errors_Codes.Fatal_UniverseMightContainSumOfTwoUnivVars
             () (Obj.magic FStarC_Errors_Msg.is_error_message_string)
             (Obj.magic uu___2))
  | FStarC_Parser_AST.App uu___1 ->
      let rec aux t1 univargs =
        let uu___2 = let uu___3 = unparen t1 in uu___3.FStarC_Parser_AST.tm in
        match uu___2 with
        | FStarC_Parser_AST.App (t2, targ, uu___3) ->
            let uarg = desugar_maybe_non_constant_universe targ in
            aux t2 (uarg :: univargs)
        | FStarC_Parser_AST.Var _max_lid ->
            let uu___4 =
              FStarC_List.existsb
                (fun uu___5 ->
                   match uu___5 with
                   | FStar_Pervasives.Inr uu___6 -> true
                   | uu___6 -> false) univargs in
            if uu___4
            then
              let uu___5 =
                let uu___6 =
                  FStarC_List.map
                    (fun uu___7 ->
                       match uu___7 with
                       | FStar_Pervasives.Inl n -> int_to_universe n
                       | FStar_Pervasives.Inr u -> u) univargs in
                FStarC_Syntax_Syntax.U_max uu___6 in
              FStar_Pervasives.Inr uu___5
            else
              (let nargs =
                 FStarC_List.map
                   (fun uu___6 ->
                      match uu___6 with
                      | FStar_Pervasives.Inl n -> n
                      | FStar_Pervasives.Inr uu___7 -> failwith "impossible")
                   univargs in
               let uu___6 =
                 FStarC_List.fold_left (fun m n -> if m > n then m else n)
                   Prims.int_zero nargs in
               FStar_Pervasives.Inl uu___6)
        | uu___3 ->
            let uu___4 =
              let uu___5 =
                let uu___6 = FStarC_Parser_AST.term_to_string t1 in
                Prims.strcat uu___6 " in universe context" in
              Prims.strcat "Unexpected term " uu___5 in
            FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term t1
              FStarC_Errors_Codes.Fatal_UnexpectedTermInUniverse ()
              (Obj.magic FStarC_Errors_Msg.is_error_message_string)
              (Obj.magic uu___4) in
      aux t []
  | uu___1 ->
      let uu___2 =
        let uu___3 =
          let uu___4 = FStarC_Parser_AST.term_to_string t in
          Prims.strcat uu___4 " in universe context" in
        Prims.strcat "Unexpected term " uu___3 in
      FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term t
        FStarC_Errors_Codes.Fatal_UnexpectedTermInUniverse ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic uu___2)
let desugar_universe (t : FStarC_Parser_AST.term) :
  FStarC_Syntax_Syntax.universe=
  let u = desugar_maybe_non_constant_universe t in
  match u with
  | FStar_Pervasives.Inl n -> int_to_universe n
  | FStar_Pervasives.Inr u1 -> u1
let check_no_aq (aq : antiquotations_temp) : unit=
  match aq with
  | [] -> ()
  | (bv,
     {
       FStarC_Syntax_Syntax.n = FStarC_Syntax_Syntax.Tm_quoted
         (e,
          { FStarC_Syntax_Syntax.qkind = FStarC_Syntax_Syntax.Quote_dynamic;
            FStarC_Syntax_Syntax.antiquotations = uu___;_});
       FStarC_Syntax_Syntax.pos = uu___1; FStarC_Syntax_Syntax.vars = uu___2;
       FStarC_Syntax_Syntax.hash_code = uu___3;_})::uu___4
      ->
      let uu___5 =
        let uu___6 =
          FStarC_Class_Show.show FStarC_Syntax_Print.showable_term e in
        FStarC_Format.fmt1 "Unexpected antiquotation: `@(%s)" uu___6 in
      FStarC_Errors.raise_error (FStarC_Syntax_Syntax.has_range_syntax ()) e
        FStarC_Errors_Codes.Fatal_UnexpectedAntiquotation ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic uu___5)
  | (bv, e)::uu___ ->
      let uu___1 =
        let uu___2 =
          FStarC_Class_Show.show FStarC_Syntax_Print.showable_term e in
        FStarC_Format.fmt1 "Unexpected antiquotation: `#(%s)" uu___2 in
      FStarC_Errors.raise_error (FStarC_Syntax_Syntax.has_range_syntax ()) e
        FStarC_Errors_Codes.Fatal_UnexpectedAntiquotation ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic uu___1)
let check_linear_pattern_variables
  (pats :
    FStarC_Syntax_Syntax.pat' FStarC_Syntax_Syntax.withinfo_t Prims.list)
  (r : FStarC_Range_Type.t) : unit=
  let rec pat_vars uu___ =
    (fun p ->
       match p.FStarC_Syntax_Syntax.v with
       | FStarC_Syntax_Syntax.Pat_dot_term uu___ ->
           Obj.magic
             (Obj.repr
                (FStarC_Class_Setlike.empty ()
                   (Obj.magic
                      (FStarC_RBSet.setlike_rbset FStarC_Syntax_Syntax.ord_bv))
                   ()))
       | FStarC_Syntax_Syntax.Pat_constant uu___ ->
           Obj.magic
             (Obj.repr
                (FStarC_Class_Setlike.empty ()
                   (Obj.magic
                      (FStarC_RBSet.setlike_rbset FStarC_Syntax_Syntax.ord_bv))
                   ()))
       | FStarC_Syntax_Syntax.Pat_var x ->
           Obj.magic
             (Obj.repr
                (let uu___ =
                   let uu___1 =
                     FStarC_Ident.string_of_id x.FStarC_Syntax_Syntax.ppname in
                   uu___1 = FStarC_Ident.reserved_prefix in
                 if uu___
                 then
                   FStarC_Class_Setlike.empty ()
                     (Obj.magic
                        (FStarC_RBSet.setlike_rbset
                           FStarC_Syntax_Syntax.ord_bv)) ()
                 else
                   FStarC_Class_Setlike.singleton ()
                     (Obj.magic
                        (FStarC_RBSet.setlike_rbset
                           FStarC_Syntax_Syntax.ord_bv)) x))
       | FStarC_Syntax_Syntax.Pat_cons (uu___, uu___1, pats1) ->
           Obj.magic
             (Obj.repr
                (let aux uu___3 uu___2 =
                   (fun out uu___2 ->
                      match uu___2 with
                      | (p1, uu___3) ->
                          let p_vars = pat_vars p1 in
                          let intersection =
                            Obj.magic
                              (FStarC_Class_Setlike.inter ()
                                 (Obj.magic
                                    (FStarC_RBSet.setlike_rbset
                                       FStarC_Syntax_Syntax.ord_bv))
                                 (Obj.magic p_vars) (Obj.magic out)) in
                          let uu___4 =
                            FStarC_Class_Setlike.is_empty ()
                              (Obj.magic
                                 (FStarC_RBSet.setlike_rbset
                                    FStarC_Syntax_Syntax.ord_bv))
                              (Obj.magic intersection) in
                          if uu___4
                          then
                            Obj.magic
                              (Obj.repr
                                 (FStarC_Class_Setlike.union ()
                                    (Obj.magic
                                       (FStarC_RBSet.setlike_rbset
                                          FStarC_Syntax_Syntax.ord_bv))
                                    (Obj.magic out) (Obj.magic p_vars)))
                          else
                            Obj.magic
                              (Obj.repr
                                 (let duplicate_bv =
                                    let uu___6 =
                                      FStarC_Class_Setlike.elems ()
                                        (Obj.magic
                                           (FStarC_RBSet.setlike_rbset
                                              FStarC_Syntax_Syntax.ord_bv))
                                        (Obj.magic intersection) in
                                    FStarC_List.hd uu___6 in
                                  let uu___6 =
                                    let uu___7 =
                                      FStarC_Class_Show.show
                                        FStarC_Ident.showable_ident
                                        duplicate_bv.FStarC_Syntax_Syntax.ppname in
                                    FStarC_Format.fmt1
                                      "Non-linear patterns are not permitted: `%s` appears more than once in this pattern."
                                      uu___7 in
                                  FStarC_Errors.raise_error
                                    FStarC_Syntax_Syntax.hasRange_bv
                                    duplicate_bv
                                    FStarC_Errors_Codes.Fatal_NonLinearPatternNotPermitted
                                    ()
                                    (Obj.magic
                                       FStarC_Errors_Msg.is_error_message_string)
                                    (Obj.magic uu___6)))) uu___3 uu___2 in
                 let uu___2 =
                   Obj.magic
                     (FStarC_Class_Setlike.empty ()
                        (Obj.magic
                           (FStarC_RBSet.setlike_rbset
                              FStarC_Syntax_Syntax.ord_bv)) ()) in
                 FStarC_List.fold_left aux uu___2 pats1))) uu___ in
  match pats with
  | [] -> ()
  | p::[] -> let uu___ = pat_vars p in ()
  | p::ps ->
      let pvars = pat_vars p in
      let aux p1 =
        let uu___ =
          let uu___1 = pat_vars p1 in
          FStarC_Class_Setlike.equal ()
            (Obj.magic
               (FStarC_RBSet.setlike_rbset FStarC_Syntax_Syntax.ord_bv))
            (Obj.magic pvars) (Obj.magic uu___1) in
        if uu___
        then ()
        else
          (let symdiff uu___3 uu___2 =
             (fun s1 s2 ->
                let uu___2 =
                  Obj.magic
                    (FStarC_Class_Setlike.diff ()
                       (Obj.magic
                          (FStarC_RBSet.setlike_rbset
                             FStarC_Syntax_Syntax.ord_bv)) (Obj.magic s1)
                       (Obj.magic s2)) in
                let uu___3 =
                  Obj.magic
                    (FStarC_Class_Setlike.diff ()
                       (Obj.magic
                          (FStarC_RBSet.setlike_rbset
                             FStarC_Syntax_Syntax.ord_bv)) (Obj.magic s2)
                       (Obj.magic s1)) in
                Obj.magic
                  (FStarC_Class_Setlike.union ()
                     (Obj.magic
                        (FStarC_RBSet.setlike_rbset
                           FStarC_Syntax_Syntax.ord_bv)) (Obj.magic uu___2)
                     (Obj.magic uu___3))) uu___3 uu___2 in
           let nonlinear_vars =
             let uu___2 = pat_vars p1 in symdiff pvars uu___2 in
           let first_nonlinear_var =
             let uu___2 =
               FStarC_Class_Setlike.elems ()
                 (Obj.magic
                    (FStarC_RBSet.setlike_rbset FStarC_Syntax_Syntax.ord_bv))
                 (Obj.magic nonlinear_vars) in
             FStarC_List.hd uu___2 in
           let uu___2 =
             let uu___3 =
               FStarC_Errors_Msg.text
                 "Patterns in this match are incoherent." in
             let uu___4 =
               let uu___5 =
                 let uu___6 =
                   let uu___7 =
                     FStarC_Class_Show.show FStarC_Ident.showable_ident
                       first_nonlinear_var.FStarC_Syntax_Syntax.ppname in
                   FStarC_Format.fmt1
                     "Variable %s is bound in some but not all patterns."
                     uu___7 in
                 FStarC_Errors_Msg.text uu___6 in
               [uu___5] in
             uu___3 :: uu___4 in
           FStarC_Errors.raise_error FStarC_Syntax_Syntax.hasRange_bv
             first_nonlinear_var FStarC_Errors_Codes.Fatal_IncoherentPatterns
             () (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
             (Obj.magic uu___2)) in
      FStarC_List.iter aux ps
let smt_pat_lid (r : FStarC_Range_Type.t) : FStarC_Ident.lident=
  FStarC_Ident.set_lid_range FStarC_Parser_Const.smtpat_lid r
let smt_pat_or_lid (r : FStarC_Range_Type.t) : FStarC_Ident.lident=
  FStarC_Ident.set_lid_range FStarC_Parser_Const.smtpatOr_lid r
let rec hoist_pat_ascription' (pat : FStarC_Parser_AST.pattern) :
  (FStarC_Parser_AST.pattern * FStarC_Parser_AST.term
    FStar_Pervasives_Native.option)=
  let mk tm =
    FStarC_Parser_AST.mk_term tm pat.FStarC_Parser_AST.prange
      FStarC_Parser_AST.Type_level in
  let handle_list type_lid pat_cons pats =
    let uu___ =
      let uu___1 = FStarC_List.map hoist_pat_ascription' pats in
      FStarC_List.unzip uu___1 in
    match uu___ with
    | (pats1, terms) ->
        let uu___1 =
          FStarC_List.for_all FStar_Pervasives_Native.uu___is_None terms in
        if uu___1
        then (pat, FStar_Pervasives_Native.None)
        else
          (let terms1 =
             FStarC_List.map
               (fun uu___3 ->
                  match uu___3 with
                  | FStar_Pervasives_Native.Some t -> t
                  | FStar_Pervasives_Native.None -> mk FStarC_Parser_AST.Wild)
               terms in
           let uu___3 =
             let uu___4 = pat_cons pats1 in
             {
               FStarC_Parser_AST.pat = uu___4;
               FStarC_Parser_AST.prange = (pat.FStarC_Parser_AST.prange)
             } in
           let uu___4 =
             let uu___5 =
               let uu___6 = mk type_lid in
               let uu___7 =
                 FStarC_List.map (fun t -> (t, FStarC_Parser_AST.Nothing))
                   terms1 in
               FStarC_Parser_AST.mkApp uu___6 uu___7
                 pat.FStarC_Parser_AST.prange in
             FStar_Pervasives_Native.Some uu___5 in
           (uu___3, uu___4)) in
  match pat.FStarC_Parser_AST.pat with
  | FStarC_Parser_AST.PatList pats ->
      handle_list (FStarC_Parser_AST.Var FStarC_Parser_Const.list_lid)
        (fun uu___ -> FStarC_Parser_AST.PatList uu___) pats
  | FStarC_Parser_AST.PatTuple (pats, dep) ->
      let uu___ =
        let uu___1 =
          (if dep
           then FStarC_Parser_Const_Tuples.mk_dtuple_lid
           else FStarC_Parser_Const_Tuples.mk_tuple_lid)
            (FStarC_List.length pats) pat.FStarC_Parser_AST.prange in
        FStarC_Parser_AST.Var uu___1 in
      handle_list uu___
        (fun pats1 -> FStarC_Parser_AST.PatTuple (pats1, dep)) pats
  | FStarC_Parser_AST.PatAscribed (pat1, (typ, FStar_Pervasives_Native.None))
      -> (pat1, (FStar_Pervasives_Native.Some typ))
  | uu___ -> (pat, FStar_Pervasives_Native.None)
let rest_pat_for_lid (env : env_t) (l : FStarC_Ident.lid) :
  FStarC_Parser_AST.pattern Prims.list=
  let uu___ =
    FStarC_Syntax_DsEnv.fail_or env
      (FStarC_Syntax_DsEnv.try_lookup_datacon env) l in
  match uu___ with
  | (l1, se) ->
      (match se.FStarC_Syntax_Syntax.sigel with
       | FStarC_Syntax_Syntax.Sig_datacon
           { FStarC_Syntax_Syntax.lid1 = uu___1;
             FStarC_Syntax_Syntax.us1 = uu___2; FStarC_Syntax_Syntax.t1 = t;
             FStarC_Syntax_Syntax.ty_lid = uu___3;
             FStarC_Syntax_Syntax.num_ty_params = num_ty_params;
             FStarC_Syntax_Syntax.mutuals1 = uu___4;
             FStarC_Syntax_Syntax.injective_type_params1 = uu___5;
             FStarC_Syntax_Syntax.proj_disc_lids = uu___6;_}
           ->
           let uu___7 = FStarC_Syntax_Util.arrow_formals t in
           (match uu___7 with
            | (bs, uu___8) ->
                let uu___9 = FStarC_List.splitAt num_ty_params bs in
                (match uu___9 with
                 | (uu___10, bs1) ->
                     FStarC_List.map
                       (fun b ->
                          let q =
                            match b.FStarC_Syntax_Syntax.binder_qual with
                            | FStar_Pervasives_Native.Some
                                (FStarC_Syntax_Syntax.Implicit uu___11) ->
                                FStar_Pervasives_Native.Some
                                  FStarC_Parser_AST.Implicit
                            | uu___11 -> FStar_Pervasives_Native.None in
                          let uu___11 =
                            FStarC_Class_HasRange.pos
                              FStarC_Syntax_Syntax.hasRange_fv l1 in
                          FStarC_Parser_AST.mk_pattern
                            (FStarC_Parser_AST.PatWild (q, [])) uu___11) bs1))
       | uu___1 ->
           failwith "unexpected: try_lookup_datacon returned odd sigelt")
let hoist_pat_ascription (pat : FStarC_Parser_AST.pattern) :
  FStarC_Parser_AST.pattern=
  let uu___ = hoist_pat_ascription' pat in
  match uu___ with
  | (pat1, typ) ->
      (match typ with
       | FStar_Pervasives_Native.Some typ1 ->
           {
             FStarC_Parser_AST.pat =
               (FStarC_Parser_AST.PatAscribed
                  (pat1, (typ1, FStar_Pervasives_Native.None)));
             FStarC_Parser_AST.prange = (pat1.FStarC_Parser_AST.prange)
           }
       | FStar_Pervasives_Native.None -> pat1)
let rec desugar_data_pat (top_level_ascr_allowed : Prims.bool) (env : env_t)
  (p : FStarC_Parser_AST.pattern) :
  ((env_t * bnd * annotated_pat Prims.list) * antiquotations_temp)=
  let resolvex l e x =
    let uu___ =
      FStarC_Option.find
        (fun y ->
           let uu___1 =
             FStarC_Ident.string_of_id y.FStarC_Syntax_Syntax.ppname in
           let uu___2 = FStarC_Ident.string_of_id x in uu___1 = uu___2) l in
    match uu___ with
    | FStar_Pervasives_Native.Some y -> (l, e, y)
    | uu___1 ->
        let uu___2 = FStarC_Syntax_DsEnv.push_bv e x in
        (match uu___2 with | (e1, xbv) -> ((xbv :: l), e1, xbv)) in
  let rec aux' top loc aqs env1 p1 =
    let pos q = FStarC_Syntax_Syntax.withinfo q p1.FStarC_Parser_AST.prange in
    let pos_r r q = FStarC_Syntax_Syntax.withinfo q r in
    let orig = p1 in
    match p1.FStarC_Parser_AST.pat with
    | FStarC_Parser_AST.PatOr uu___ ->
        failwith "impossible: PatOr handled below"
    | FStarC_Parser_AST.PatOp op ->
        let id_op =
          let uu___ =
            let uu___1 =
              let uu___2 = FStarC_Ident.string_of_id op in
              let uu___3 = FStarC_Ident.range_of_id op in
              FStarC_Parser_AST.compile_op Prims.int_zero uu___2 uu___3 in
            let uu___2 = FStarC_Ident.range_of_id op in (uu___1, uu___2) in
          FStarC_Ident.mk_ident uu___ in
        let p2 =
          {
            FStarC_Parser_AST.pat =
              (FStarC_Parser_AST.PatVar
                 (id_op, FStar_Pervasives_Native.None, []));
            FStarC_Parser_AST.prange = (p1.FStarC_Parser_AST.prange)
          } in
        aux loc aqs env1 p2
    | FStarC_Parser_AST.PatAscribed (p2, (t, tacopt)) ->
        ((match tacopt with
          | FStar_Pervasives_Native.None -> ()
          | FStar_Pervasives_Native.Some uu___1 ->
              FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_pattern
                orig
                FStarC_Errors_Codes.Fatal_TypeWithinPatternsAllowedOnVariablesOnly
                () (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                (Obj.magic
                   "Type ascriptions within patterns cannot be associated with a tactic"));
         (let uu___1 = aux loc aqs env1 p2 in
          match uu___1 with
          | (loc1, aqs1, env', binder, p3, annots) ->
              let uu___2 =
                match binder with
                | LetBinder uu___3 -> failwith "impossible"
                | LocalBinder (x, aq, attrs) ->
                    let uu___3 =
                      let uu___4 =
                        FStarC_ToSyntax_TickedVars.close_fun env1 t in
                      desugar_term_aq env1 uu___4 in
                    (match uu___3 with
                     | (t1, aqs') ->
                         let x1 =
                           {
                             FStarC_Syntax_Syntax.ppname =
                               (x.FStarC_Syntax_Syntax.ppname);
                             FStarC_Syntax_Syntax.index =
                               (x.FStarC_Syntax_Syntax.index);
                             FStarC_Syntax_Syntax.sort = t1
                           } in
                         ([(x1, t1, attrs)], (LocalBinder (x1, aq, attrs)),
                           (FStarC_List.op_At aqs' aqs1))) in
              (match uu___2 with
               | (annots', binder1, aqs2) ->
                   ((match p3.FStarC_Syntax_Syntax.v with
                     | FStarC_Syntax_Syntax.Pat_var uu___4 -> ()
                     | uu___4 when top && top_level_ascr_allowed -> ()
                     | uu___4 ->
                         FStarC_Errors.raise_error
                           FStarC_Parser_AST.hasRange_pattern orig
                           FStarC_Errors_Codes.Fatal_TypeWithinPatternsAllowedOnVariablesOnly
                           ()
                           (Obj.magic
                              FStarC_Errors_Msg.is_error_message_string)
                           (Obj.magic
                              "Type ascriptions within patterns are only allowed on variables"));
                    (loc1, aqs2, env', binder1, p3,
                      (FStarC_List.op_At annots' annots))))))
    | FStarC_Parser_AST.PatWild (aq, attrs) ->
        let aq1 = trans_bqual env1 aq in
        let attrs1 = FStarC_List.map (desugar_term env1) attrs in
        let x =
          let uu___ = tun_r p1.FStarC_Parser_AST.prange in
          FStarC_Syntax_Syntax.new_bv
            (FStar_Pervasives_Native.Some (p1.FStarC_Parser_AST.prange))
            uu___ in
        let uu___ = pos (FStarC_Syntax_Syntax.Pat_var x) in
        (loc, aqs, env1, (LocalBinder (x, aq1, attrs1)), uu___, [])
    | FStarC_Parser_AST.PatConst c ->
        let x =
          let uu___ = tun_r p1.FStarC_Parser_AST.prange in
          FStarC_Syntax_Syntax.new_bv
            (FStar_Pervasives_Native.Some (p1.FStarC_Parser_AST.prange))
            uu___ in
        let uu___ = pos (FStarC_Syntax_Syntax.Pat_constant c) in
        (loc, aqs, env1, (LocalBinder (x, FStar_Pervasives_Native.None, [])),
          uu___, [])
    | FStarC_Parser_AST.PatVQuote e ->
        let pat =
          let uu___ =
            let uu___1 =
              let uu___2 = desugar_vquote env1 e p1.FStarC_Parser_AST.prange in
              (uu___2, (p1.FStarC_Parser_AST.prange)) in
            FStarC_Const.Const_string uu___1 in
          FStarC_Parser_AST.PatConst uu___ in
        aux' top loc aqs env1
          {
            FStarC_Parser_AST.pat = pat;
            FStarC_Parser_AST.prange = (p1.FStarC_Parser_AST.prange)
          }
    | FStarC_Parser_AST.PatVar (x, aq, attrs) ->
        let aq1 = trans_bqual env1 aq in
        let attrs1 = FStarC_List.map (desugar_term env1) attrs in
        let uu___ = resolvex loc env1 x in
        (match uu___ with
         | (loc1, env2, xbv) ->
             let uu___1 = pos (FStarC_Syntax_Syntax.Pat_var xbv) in
             (loc1, aqs, env2, (LocalBinder (xbv, aq1, attrs1)), uu___1, []))
    | FStarC_Parser_AST.PatName l ->
        let uu___ =
          FStarC_Syntax_DsEnv.fail_or env1
            (FStarC_Syntax_DsEnv.try_lookup_datacon env1) l in
        (match uu___ with
         | (l1, uu___1) ->
             let x =
               let uu___2 = tun_r p1.FStarC_Parser_AST.prange in
               FStarC_Syntax_Syntax.new_bv
                 (FStar_Pervasives_Native.Some (p1.FStarC_Parser_AST.prange))
                 uu___2 in
             let uu___2 =
               pos
                 (FStarC_Syntax_Syntax.Pat_cons
                    (l1, FStar_Pervasives_Native.None, [])) in
             (loc, aqs, env1,
               (LocalBinder (x, FStar_Pervasives_Native.None, [])), uu___2,
               []))
    | FStarC_Parser_AST.PatApp
        ({ FStarC_Parser_AST.pat = FStarC_Parser_AST.PatName l;
           FStarC_Parser_AST.prange = uu___;_},
         { FStarC_Parser_AST.pat = FStarC_Parser_AST.PatRest;
           FStarC_Parser_AST.prange = uu___1;_}::[])
        ->
        let uu___2 = p1.FStarC_Parser_AST.pat in
        (match uu___2 with
         | FStarC_Parser_AST.PatApp (hd, uu___3) ->
             let argpats = rest_pat_for_lid env1 l in
             let newpat =
               FStarC_Parser_AST.mk_pattern
                 (FStarC_Parser_AST.PatApp (hd, argpats))
                 p1.FStarC_Parser_AST.prange in
             aux' top loc aqs env1 newpat)
    | FStarC_Parser_AST.PatRest ->
        let uu___ =
          let uu___1 = FStarC_Errors_Msg.text "Unexpected pattern." in
          let uu___2 =
            let uu___3 =
              FStarC_Errors_Msg.text
                "Using `..` is only allowed as argument to a data constructor, e.g. `C ..`." in
            [uu___3] in
          uu___1 :: uu___2 in
        FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_pattern p1
          FStarC_Errors_Codes.Fatal_UnexpectedPattern ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
          (Obj.magic uu___)
    | FStarC_Parser_AST.PatApp
        ({ FStarC_Parser_AST.pat = FStarC_Parser_AST.PatName l;
           FStarC_Parser_AST.prange = uu___;_},
         args)
        ->
        let uu___1 =
          FStarC_List.fold_right
            (fun arg uu___2 ->
               match uu___2 with
               | (loc1, aqs1, env2, annots, args1) ->
                   let uu___3 = aux loc1 aqs1 env2 arg in
                   (match uu___3 with
                    | (loc2, aqs2, env3, b, arg1, ans) ->
                        let imp = is_implicit b in
                        (loc2, aqs2, env3, (FStarC_List.op_At ans annots),
                          ((arg1, imp) :: args1)))) args
            (loc, aqs, env1, [], []) in
        (match uu___1 with
         | (loc1, aqs1, env2, annots, args1) ->
             let uu___2 =
               FStarC_Syntax_DsEnv.fail_or env2
                 (FStarC_Syntax_DsEnv.try_lookup_datacon env2) l in
             (match uu___2 with
              | (l1, uu___3) ->
                  let x =
                    let uu___4 = tun_r p1.FStarC_Parser_AST.prange in
                    FStarC_Syntax_Syntax.new_bv
                      (FStar_Pervasives_Native.Some
                         (p1.FStarC_Parser_AST.prange)) uu___4 in
                  let uu___4 =
                    pos
                      (FStarC_Syntax_Syntax.Pat_cons
                         (l1, FStar_Pervasives_Native.None, args1)) in
                  (loc1, aqs1, env2,
                    (LocalBinder (x, FStar_Pervasives_Native.None, [])),
                    uu___4, annots)))
    | FStarC_Parser_AST.PatApp uu___ ->
        FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_pattern p1
          FStarC_Errors_Codes.Fatal_UnexpectedPattern ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_string)
          (Obj.magic "Unexpected pattern")
    | FStarC_Parser_AST.PatList pats ->
        let uu___ =
          FStarC_List.fold_right
            (fun pat uu___1 ->
               match uu___1 with
               | (loc1, aqs1, env2, annots, pats1) ->
                   let uu___2 = aux loc1 aqs1 env2 pat in
                   (match uu___2 with
                    | (loc2, aqs2, env3, uu___3, pat1, ans) ->
                        (loc2, aqs2, env3, (FStarC_List.op_At ans annots),
                          (pat1 :: pats1)))) pats (loc, aqs, env1, [], []) in
        (match uu___ with
         | (loc1, aqs1, env2, annots, pats1) ->
             let pat =
               let uu___1 =
                 let uu___2 =
                   FStarC_Range_Ops.end_range p1.FStarC_Parser_AST.prange in
                 let uu___3 =
                   let uu___4 =
                     let uu___5 =
                       FStarC_Syntax_Syntax.lid_and_dd_as_fv
                         FStarC_Parser_Const.nil_lid
                         (FStar_Pervasives_Native.Some
                            FStarC_Syntax_Syntax.Data_ctor) in
                     (uu___5, FStar_Pervasives_Native.None, []) in
                   FStarC_Syntax_Syntax.Pat_cons uu___4 in
                 pos_r uu___2 uu___3 in
               FStarC_List.fold_right
                 (fun hd tl ->
                    let r =
                      FStarC_Range_Ops.union_ranges hd.FStarC_Syntax_Syntax.p
                        tl.FStarC_Syntax_Syntax.p in
                    let uu___2 =
                      let uu___3 =
                        let uu___4 =
                          FStarC_Syntax_Syntax.lid_and_dd_as_fv
                            FStarC_Parser_Const.cons_lid
                            (FStar_Pervasives_Native.Some
                               FStarC_Syntax_Syntax.Data_ctor) in
                        (uu___4, FStar_Pervasives_Native.None,
                          [(hd, false); (tl, false)]) in
                      FStarC_Syntax_Syntax.Pat_cons uu___3 in
                    pos_r r uu___2) pats1 uu___1 in
             let x =
               let uu___1 = tun_r p1.FStarC_Parser_AST.prange in
               FStarC_Syntax_Syntax.new_bv
                 (FStar_Pervasives_Native.Some (p1.FStarC_Parser_AST.prange))
                 uu___1 in
             (loc1, aqs1, env2,
               (LocalBinder (x, FStar_Pervasives_Native.None, [])), pat,
               annots))
    | FStarC_Parser_AST.PatTuple (args, dep) ->
        let uu___ =
          FStarC_List.fold_left
            (fun uu___1 p2 ->
               match uu___1 with
               | (loc1, aqs1, env2, annots, pats) ->
                   let uu___2 = aux loc1 aqs1 env2 p2 in
                   (match uu___2 with
                    | (loc2, aqs2, env3, uu___3, pat, ans) ->
                        (loc2, aqs2, env3, (FStarC_List.op_At ans annots),
                          ((pat, false) :: pats)))) (loc, aqs, env1, [], [])
            args in
        (match uu___ with
         | (loc1, aqs1, env2, annots, args1) ->
             let args2 = FStarC_List.rev args1 in
             let l =
               if dep
               then
                 FStarC_Parser_Const_Tuples.mk_dtuple_data_lid
                   (FStarC_List.length args2) p1.FStarC_Parser_AST.prange
               else
                 FStarC_Parser_Const_Tuples.mk_tuple_data_lid
                   (FStarC_List.length args2) p1.FStarC_Parser_AST.prange in
             let constr =
               FStarC_Syntax_DsEnv.fail_or env2
                 (FStarC_Syntax_DsEnv.try_lookup_lid env2) l in
             let l1 =
               match constr.FStarC_Syntax_Syntax.n with
               | FStarC_Syntax_Syntax.Tm_fvar fv -> fv
               | uu___1 -> failwith "impossible" in
             let x =
               let uu___1 = tun_r p1.FStarC_Parser_AST.prange in
               FStarC_Syntax_Syntax.new_bv
                 (FStar_Pervasives_Native.Some (p1.FStarC_Parser_AST.prange))
                 uu___1 in
             let uu___1 =
               pos
                 (FStarC_Syntax_Syntax.Pat_cons
                    (l1, FStar_Pervasives_Native.None, args2)) in
             (loc1, aqs1, env2,
               (LocalBinder (x, FStar_Pervasives_Native.None, [])), uu___1,
               annots))
    | FStarC_Parser_AST.PatRecord fields ->
        let uu___ = FStarC_List.unzip fields in
        (match uu___ with
         | (field_names, pats) ->
             let uu___1 =
               match fields with
               | [] -> (FStar_Pervasives_Native.None, field_names)
               | (f, uu___2)::uu___3 ->
                   let uu___4 =
                     FStarC_Syntax_DsEnv.try_lookup_record_by_field_name_many
                       env1 field_names in
                   (match uu___4 with
                    | FStar_Pervasives_Native.None ->
                        (FStar_Pervasives_Native.None, field_names)
                    | FStar_Pervasives_Native.Some r ->
                        let uu___5 =
                          qualify_field_names r.FStarC_Syntax_DsEnv.typename
                            field_names in
                        ((FStar_Pervasives_Native.Some
                            (r.FStarC_Syntax_DsEnv.typename)), uu___5)) in
             (match uu___1 with
              | (typename, field_names1) ->
                  let candidate_constructor =
                    let lid =
                      FStarC_Ident.lid_of_path ["__dummy__"]
                        p1.FStarC_Parser_AST.prange in
                    FStarC_Syntax_Syntax.lid_and_dd_as_fv lid
                      (FStar_Pervasives_Native.Some
                         (FStarC_Syntax_Syntax.Unresolved_constructor
                            {
                              FStarC_Syntax_Syntax.uc_base_term = false;
                              FStarC_Syntax_Syntax.uc_typename = typename;
                              FStarC_Syntax_Syntax.uc_fields = field_names1
                            })) in
                  let uu___2 =
                    FStarC_List.fold_left
                      (fun uu___3 p2 ->
                         match uu___3 with
                         | (loc1, aqs1, env2, annots, pats1) ->
                             let uu___4 = aux loc1 aqs1 env2 p2 in
                             (match uu___4 with
                              | (loc2, aqs2, env3, uu___5, pat, ann) ->
                                  (loc2, aqs2, env3,
                                    (FStarC_List.op_At ann annots),
                                    ((pat, false) :: pats1))))
                      (loc, aqs, env1, [], []) pats in
                  (match uu___2 with
                   | (loc1, aqs1, env2, annots, pats1) ->
                       let pats2 = FStarC_List.rev pats1 in
                       let pat =
                         pos
                           (FStarC_Syntax_Syntax.Pat_cons
                              (candidate_constructor,
                                FStar_Pervasives_Native.None, pats2)) in
                       let x =
                         let uu___3 = tun_r p1.FStarC_Parser_AST.prange in
                         FStarC_Syntax_Syntax.new_bv
                           (FStar_Pervasives_Native.Some
                              (p1.FStarC_Parser_AST.prange)) uu___3 in
                       (loc1, aqs1, env2,
                         (LocalBinder (x, FStar_Pervasives_Native.None, [])),
                         pat, annots))))
  and aux loc aqs env1 p1 = aux' false loc aqs env1 p1 in
  let aux_maybe_or env1 p1 =
    let loc = [] in
    match p1.FStarC_Parser_AST.pat with
    | FStarC_Parser_AST.PatOr [] -> failwith "impossible"
    | FStarC_Parser_AST.PatOr (p2::ps) ->
        let uu___ = aux' true loc [] env1 p2 in
        (match uu___ with
         | (loc1, aqs, env2, var, p3, ans) ->
             let uu___1 =
               FStarC_List.fold_left
                 (fun uu___2 p4 ->
                    match uu___2 with
                    | (loc2, aqs1, env3, ps1) ->
                        let uu___3 = aux' true loc2 aqs1 env3 p4 in
                        (match uu___3 with
                         | (loc3, aqs2, env4, uu___4, p5, ans1) ->
                             (loc3, aqs2, env4, ((p5, ans1) :: ps1))))
                 (loc1, aqs, env2, []) ps in
             (match uu___1 with
              | (loc2, aqs1, env3, ps1) ->
                  let pats = (p3, ans) :: (FStarC_List.rev ps1) in
                  ((env3, var, pats), aqs1)))
    | uu___ ->
        let uu___1 = aux' true loc [] env1 p1 in
        (match uu___1 with
         | (loc1, aqs, env2, var, pat, ans) ->
             ((env2, var, [(pat, ans)]), aqs)) in
  let uu___ = aux_maybe_or env p in
  match uu___ with
  | ((env1, b, pats), aqs) ->
      ((let uu___2 = FStarC_List.map FStar_Pervasives_Native.fst pats in
        check_linear_pattern_variables uu___2 p.FStarC_Parser_AST.prange);
       ((env1, b, pats), aqs))
and desugar_binding_pat_maybe_top (top : Prims.bool)
  (env : FStarC_Syntax_DsEnv.env) (p : FStarC_Parser_AST.pattern) :
  ((env_t * bnd * annotated_pat Prims.list) * antiquotations_temp)=
  if top
  then
    let mklet x ty tacopt =
      let uu___ =
        let uu___1 =
          let uu___2 = FStarC_Syntax_DsEnv.qualify env x in
          (uu___2, (ty, tacopt)) in
        LetBinder uu___1 in
      (env, uu___, []) in
    let op_to_ident x =
      let uu___ =
        let uu___1 =
          let uu___2 = FStarC_Ident.string_of_id x in
          let uu___3 = FStarC_Ident.range_of_id x in
          FStarC_Parser_AST.compile_op Prims.int_zero uu___2 uu___3 in
        let uu___2 = FStarC_Ident.range_of_id x in (uu___1, uu___2) in
      FStarC_Ident.mk_ident uu___ in
    match p.FStarC_Parser_AST.pat with
    | FStarC_Parser_AST.PatOp x ->
        let uu___ =
          let uu___1 = op_to_ident x in
          let uu___2 =
            let uu___3 = FStarC_Ident.range_of_id x in tun_r uu___3 in
          mklet uu___1 uu___2 FStar_Pervasives_Native.None in
        (uu___, [])
    | FStarC_Parser_AST.PatVar (x, uu___, uu___1) ->
        let uu___2 =
          let uu___3 =
            let uu___4 = FStarC_Ident.range_of_id x in tun_r uu___4 in
          mklet x uu___3 FStar_Pervasives_Native.None in
        (uu___2, [])
    | FStarC_Parser_AST.PatAscribed
        ({ FStarC_Parser_AST.pat = FStarC_Parser_AST.PatOp x;
           FStarC_Parser_AST.prange = uu___;_},
         (t, tacopt))
        ->
        let tacopt1 = FStarC_Option.map (desugar_term env) tacopt in
        let uu___1 = desugar_term_aq env t in
        (match uu___1 with
         | (t1, aq) ->
             let uu___2 =
               let uu___3 = op_to_ident x in mklet uu___3 t1 tacopt1 in
             (uu___2, aq))
    | FStarC_Parser_AST.PatAscribed
        ({
           FStarC_Parser_AST.pat = FStarC_Parser_AST.PatVar
             (x, uu___, uu___1);
           FStarC_Parser_AST.prange = uu___2;_},
         (t, tacopt))
        ->
        let tacopt1 = FStarC_Option.map (desugar_term env) tacopt in
        let uu___3 = desugar_term_aq env t in
        (match uu___3 with
         | (t1, aq) -> let uu___4 = mklet x t1 tacopt1 in (uu___4, aq))
    | uu___ ->
        FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_pattern p
          FStarC_Errors_Codes.Fatal_UnexpectedPattern ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_string)
          (Obj.magic "Unexpected pattern at the top-level")
  else
    (let uu___1 = desugar_data_pat true env p in
     match uu___1 with
     | ((env1, binder, p1), aq) ->
         let p2 =
           match p1 with
           | ({ FStarC_Syntax_Syntax.v = FStarC_Syntax_Syntax.Pat_var uu___2;
                FStarC_Syntax_Syntax.p = uu___3;_},
              uu___4)::[] -> []
           | uu___2 -> p1 in
         ((env1, binder, p2), aq))
and desugar_binding_pat_aq (env : FStarC_Syntax_DsEnv.env)
  (p : FStarC_Parser_AST.pattern) :
  ((env_t * bnd * annotated_pat Prims.list) * antiquotations_temp)=
  desugar_binding_pat_maybe_top false env p
and desugar_match_pat_maybe_top (uu___ : Prims.bool) (env : env_t)
  (pat : FStarC_Parser_AST.pattern) :
  ((env_t * annotated_pat Prims.list) * antiquotations_temp)=
  let uu___1 = desugar_data_pat false env pat in
  match uu___1 with | ((env1, uu___2, pat1), aqs) -> ((env1, pat1), aqs)
and desugar_match_pat (env : env_t) (p : FStarC_Parser_AST.pattern) :
  ((env_t * annotated_pat Prims.list) * antiquotations_temp)=
  desugar_match_pat_maybe_top false env p
and desugar_term_aq (env : env_t) (e : FStarC_Parser_AST.term) :
  (FStarC_Syntax_Syntax.term * antiquotations_temp)=
  let env1 = FStarC_Syntax_DsEnv.set_expect_typ env false in
  desugar_term_maybe_top false env1 e
and desugar_term (env : FStarC_Syntax_DsEnv.env) (e : FStarC_Parser_AST.term)
  : FStarC_Syntax_Syntax.term=
  let uu___ = desugar_term_aq env e in
  match uu___ with | (t, aq) -> (check_no_aq aq; t)
and desugar_typ_aq (env : FStarC_Syntax_DsEnv.env)
  (e : FStarC_Parser_AST.term) :
  (FStarC_Syntax_Syntax.term * antiquotations_temp)=
  let env1 = FStarC_Syntax_DsEnv.set_expect_typ env true in
  desugar_term_maybe_top false env1 e
and desugar_typ (env : FStarC_Syntax_DsEnv.env) (e : FStarC_Parser_AST.term)
  : FStarC_Syntax_Syntax.term=
  let uu___ = desugar_typ_aq env e in
  match uu___ with | (t, aq) -> (check_no_aq aq; t)
and desugar_machine_integer (env : FStarC_Syntax_DsEnv.env)
  (repr : Prims.string)
  (uu___ : (FStarC_Const.signedness * FStarC_Const.width))
  (range : FStarC_Range_Type.t) : FStarC_Syntax_Syntax.term=
  match uu___ with
  | (signedness, width) ->
      let tnm =
        if width = FStarC_Const.Sizet
        then "FStar.SizeT"
        else
          Prims.strcat "FStar."
            (Prims.strcat
               (match signedness with
                | FStarC_Const.Unsigned -> "U"
                | FStarC_Const.Signed -> "")
               (Prims.strcat "Int"
                  (match width with
                   | FStarC_Const.Int8 -> "8"
                   | FStarC_Const.Int16 -> "16"
                   | FStarC_Const.Int32 -> "32"
                   | FStarC_Const.Int64 -> "64"))) in
      ((let uu___2 =
          let uu___3 = FStarC_Const.within_bounds repr signedness width in
          Prims.op_Negation uu___3 in
        if uu___2
        then
          let uu___3 =
            FStarC_Format.fmt2 "%s is not in the expected range for %s" repr
              tnm in
          FStarC_Errors.log_issue FStarC_Class_HasRange.hasRange_range range
            FStarC_Errors_Codes.Error_OutOfRange ()
            (Obj.magic FStarC_Errors_Msg.is_error_message_string)
            (Obj.magic uu___3)
        else ());
       (let private_intro_nm =
          Prims.strcat tnm
            (Prims.strcat ".__"
               (Prims.strcat
                  (match signedness with
                   | FStarC_Const.Unsigned -> "u"
                   | FStarC_Const.Signed -> "") "int_to_t")) in
        let intro_nm =
          Prims.strcat tnm
            (Prims.strcat "."
               (Prims.strcat
                  (match signedness with
                   | FStarC_Const.Unsigned -> "u"
                   | FStarC_Const.Signed -> "") "int_to_t")) in
        let lid =
          let uu___2 = FStarC_Ident.path_of_text intro_nm in
          FStarC_Ident.lid_of_path uu___2 range in
        let lid1 =
          let uu___2 = FStarC_Syntax_DsEnv.try_lookup_lid env lid in
          match uu___2 with
          | FStar_Pervasives_Native.Some intro_term ->
              (match intro_term.FStarC_Syntax_Syntax.n with
               | FStarC_Syntax_Syntax.Tm_fvar fv ->
                   let private_lid =
                     let uu___3 = FStarC_Ident.path_of_text private_intro_nm in
                     FStarC_Ident.lid_of_path uu___3 range in
                   let private_fv =
                     FStarC_Syntax_Syntax.lid_and_dd_as_fv private_lid
                       fv.FStarC_Syntax_Syntax.fv_qual in
                   {
                     FStarC_Syntax_Syntax.n =
                       (FStarC_Syntax_Syntax.Tm_fvar private_fv);
                     FStarC_Syntax_Syntax.pos =
                       (intro_term.FStarC_Syntax_Syntax.pos);
                     FStarC_Syntax_Syntax.vars =
                       (intro_term.FStarC_Syntax_Syntax.vars);
                     FStarC_Syntax_Syntax.hash_code =
                       (intro_term.FStarC_Syntax_Syntax.hash_code)
                   }
               | uu___3 ->
                   failwith
                     (Prims.strcat "Unexpected non-fvar for " intro_nm))
          | FStar_Pervasives_Native.None ->
              let uu___3 =
                FStarC_Format.fmt1
                  "Unexpected numeric literal.  Restart F* to load %s." tnm in
              FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range
                range FStarC_Errors_Codes.Fatal_UnexpectedNumericLiteral ()
                (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                (Obj.magic uu___3) in
        let repr' =
          FStarC_Syntax_Syntax.mk
            (FStarC_Syntax_Syntax.Tm_constant
               (FStarC_Const.Const_int (repr, FStar_Pervasives_Native.None)))
            range in
        let app =
          let uu___2 =
            let uu___3 =
              let uu___4 =
                let uu___5 =
                  let uu___6 = FStarC_Syntax_Syntax.as_aqual_implicit false in
                  (repr', uu___6) in
                [uu___5] in
              {
                FStarC_Syntax_Syntax.hd = lid1;
                FStarC_Syntax_Syntax.args = uu___4
              } in
            FStarC_Syntax_Syntax.Tm_app uu___3 in
          FStarC_Syntax_Syntax.mk uu___2 range in
        FStarC_Syntax_Syntax.mk
          (FStarC_Syntax_Syntax.Tm_meta
             {
               FStarC_Syntax_Syntax.tm2 = app;
               FStarC_Syntax_Syntax.meta =
                 (FStarC_Syntax_Syntax.Meta_desugared
                    (FStarC_Syntax_Syntax.Machine_integer (signedness, width)))
             }) range))
and desugar_term_maybe_top (top_level : Prims.bool) (env : env_t)
  (top : FStarC_Parser_AST.term) :
  (FStarC_Syntax_Syntax.term * antiquotations_temp)=
  let mk e = FStarC_Syntax_Syntax.mk e top.FStarC_Parser_AST.range in
  let noaqs = [] in
  let join_aqs aqs = FStarC_List.flatten aqs in
  let setpos e =
    {
      FStarC_Syntax_Syntax.n = (e.FStarC_Syntax_Syntax.n);
      FStarC_Syntax_Syntax.pos = (top.FStarC_Parser_AST.range);
      FStarC_Syntax_Syntax.vars = (e.FStarC_Syntax_Syntax.vars);
      FStarC_Syntax_Syntax.hash_code = (e.FStarC_Syntax_Syntax.hash_code)
    } in
  let desugar_binders env1 binders =
    let uu___ =
      FStarC_List.fold_left
        (fun uu___1 b ->
           match uu___1 with
           | (env2, bs) ->
               let bb = desugar_binder env2 b in
               let uu___2 = as_binder env2 b.FStarC_Parser_AST.aqual bb in
               (match uu___2 with | (b1, env3) -> (env3, (b1 :: bs))))
        (env1, []) binders in
    match uu___ with | (env2, bs_rev) -> (env2, (FStarC_List.rev bs_rev)) in
  let unqual_bv_of_binder b =
    match b with
    | { FStarC_Syntax_Syntax.binder_bv = x;
        FStarC_Syntax_Syntax.binder_qual = FStar_Pervasives_Native.None;
        FStarC_Syntax_Syntax.binder_positivity = uu___;
        FStarC_Syntax_Syntax.binder_attrs = [];_} -> x
    | uu___ ->
        FStarC_Errors.raise_error FStarC_Syntax_Syntax.hasRange_binder b
          FStarC_Errors_Codes.Fatal_UnexpectedTerm ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_string)
          (Obj.magic "Unexpected qualified binder in ELIM_EXISTS") in
  (let uu___1 = FStarC_Effect.op_Bang dbg_ToSyntax in
   if uu___1
   then
     let uu___2 = FStarC_Class_Show.show FStarC_Parser_AST.showable_term top in
     FStarC_Format.print1 "desugaring (%s)\n\n" uu___2
   else ());
  (let uu___1 = let uu___2 = unparen top in uu___2.FStarC_Parser_AST.tm in
   match uu___1 with
   | FStarC_Parser_AST.Wild -> ((setpos FStarC_Syntax_Syntax.tun), noaqs)
   | FStarC_Parser_AST.Labeled uu___2 ->
       let uu___3 = desugar_formula env top in (uu___3, noaqs)
   | FStarC_Parser_AST.Requires t ->
       let uu___2 = desugar_formula env t in (uu___2, noaqs)
   | FStarC_Parser_AST.Ensures t ->
       let uu___2 = desugar_formula env t in (uu___2, noaqs)
   | FStarC_Parser_AST.Attributes ts ->
       failwith
         "Attributes should not be desugared by desugar_term_maybe_top"
   | FStarC_Parser_AST.Const (FStarC_Const.Const_int
       (i, FStar_Pervasives_Native.Some size)) ->
       let uu___2 =
         desugar_machine_integer env i size top.FStarC_Parser_AST.range in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Const c ->
       let uu___2 = mk (FStarC_Syntax_Syntax.Tm_constant c) in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Op (id, args) when
       let uu___2 = FStarC_Ident.string_of_id id in uu___2 = "=!=" ->
       let r = FStarC_Ident.range_of_id id in
       let e =
         let uu___2 =
           let uu___3 =
             let uu___4 = FStarC_Ident.mk_ident ("==", r) in (uu___4, args) in
           FStarC_Parser_AST.Op uu___3 in
         FStarC_Parser_AST.mk_term uu___2 top.FStarC_Parser_AST.range
           top.FStarC_Parser_AST.level in
       let uu___2 =
         let uu___3 =
           let uu___4 =
             let uu___5 = FStarC_Ident.mk_ident ("~", r) in (uu___5, [e]) in
           FStarC_Parser_AST.Op uu___4 in
         FStarC_Parser_AST.mk_term uu___3 top.FStarC_Parser_AST.range
           top.FStarC_Parser_AST.level in
       desugar_term_aq env uu___2
   | FStarC_Parser_AST.Op (op_star, lhs::rhs::[]) when
       (let uu___2 = FStarC_Ident.string_of_id op_star in uu___2 = "*") &&
         (let uu___2 = op_as_term env (Prims.of_int (2)) op_star in
          FStar_Pervasives_Native.uu___is_None uu___2)
       ->
       let rec flatten t =
         match t.FStarC_Parser_AST.tm with
         | FStarC_Parser_AST.Op (id, t1::t2::[]) when
             (let uu___2 = FStarC_Ident.string_of_id id in uu___2 = "*") &&
               (let uu___2 = op_as_term env (Prims.of_int (2)) op_star in
                FStar_Pervasives_Native.uu___is_None uu___2)
             -> let uu___2 = flatten t1 in FStarC_List.op_At uu___2 [t2]
         | uu___2 -> [t] in
       let terms = flatten lhs in
       let t =
         let uu___2 =
           let uu___3 =
             let uu___4 =
               FStarC_List.map (fun uu___5 -> FStar_Pervasives.Inr uu___5)
                 terms in
             (uu___4, rhs) in
           FStarC_Parser_AST.Sum uu___3 in
         {
           FStarC_Parser_AST.tm = uu___2;
           FStarC_Parser_AST.range = (top.FStarC_Parser_AST.range);
           FStarC_Parser_AST.level = (top.FStarC_Parser_AST.level)
         } in
       desugar_term_maybe_top top_level env t
   | FStarC_Parser_AST.Uvar u ->
       let uu___2 =
         let uu___3 =
           let uu___4 = FStarC_Ident.string_of_id u in
           Prims.strcat uu___4 " in non-universe context" in
         Prims.strcat "Unexpected universe variable " uu___3 in
       FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term top
         FStarC_Errors_Codes.Fatal_UnexpectedUniverseVariable ()
         (Obj.magic FStarC_Errors_Msg.is_error_message_string)
         (Obj.magic uu___2)
   | FStarC_Parser_AST.Op (s, f::e::[]) when
       let uu___2 = FStarC_Ident.string_of_id s in uu___2 = "<|" ->
       let uu___2 =
         FStarC_Parser_AST.mkApp f [(e, FStarC_Parser_AST.Nothing)]
           top.FStarC_Parser_AST.range in
       desugar_term_maybe_top top_level env uu___2
   | FStarC_Parser_AST.Op (s, e::f::[]) when
       let uu___2 = FStarC_Ident.string_of_id s in uu___2 = "|>" ->
       let uu___2 =
         FStarC_Parser_AST.mkApp f [(e, FStarC_Parser_AST.Nothing)]
           top.FStarC_Parser_AST.range in
       desugar_term_maybe_top top_level env uu___2
   | FStarC_Parser_AST.Op (s, args) ->
       let uu___2 = op_as_term env (FStarC_List.length args) s in
       (match uu___2 with
        | FStar_Pervasives_Native.None ->
            let uu___3 =
              let uu___4 = FStarC_Ident.string_of_id s in
              Prims.strcat "Unexpected or unbound operator: " uu___4 in
            FStarC_Errors.raise_error FStarC_Ident.hasrange_ident s
              FStarC_Errors_Codes.Fatal_UnepxectedOrUnboundOperator ()
              (Obj.magic FStarC_Errors_Msg.is_error_message_string)
              (Obj.magic uu___3)
        | FStar_Pervasives_Native.Some op ->
            if (FStarC_List.length args) > Prims.int_zero
            then
              let uu___3 =
                let uu___4 =
                  FStarC_List.map
                    (fun t ->
                       let uu___5 = desugar_term_aq env t in
                       match uu___5 with
                       | (t', s1) -> ((t', FStar_Pervasives_Native.None), s1))
                    args in
                FStarC_List.unzip uu___4 in
              (match uu___3 with
               | (args1, aqs) ->
                   let uu___4 =
                     mk
                       (FStarC_Syntax_Syntax.Tm_app
                          {
                            FStarC_Syntax_Syntax.hd = op;
                            FStarC_Syntax_Syntax.args = args1
                          }) in
                   (uu___4, (join_aqs aqs)))
            else (op, noaqs))
   | FStarC_Parser_AST.Construct (n, (a, uu___2)::[]) when
       let uu___3 = FStarC_Ident.string_of_lid n in uu___3 = "SMTPat" ->
       let uu___3 =
         let uu___4 =
           let uu___5 =
             let uu___6 =
               let uu___7 =
                 let uu___8 = smt_pat_lid top.FStarC_Parser_AST.range in
                 FStarC_Parser_AST.Var uu___8 in
               {
                 FStarC_Parser_AST.tm = uu___7;
                 FStarC_Parser_AST.range = (top.FStarC_Parser_AST.range);
                 FStarC_Parser_AST.level = (top.FStarC_Parser_AST.level)
               } in
             (uu___6, a, FStarC_Parser_AST.Nothing) in
           FStarC_Parser_AST.App uu___5 in
         {
           FStarC_Parser_AST.tm = uu___4;
           FStarC_Parser_AST.range = (top.FStarC_Parser_AST.range);
           FStarC_Parser_AST.level = (top.FStarC_Parser_AST.level)
         } in
       desugar_term_maybe_top top_level env uu___3
   | FStarC_Parser_AST.Construct (n, (a, uu___2)::[]) when
       let uu___3 = FStarC_Ident.string_of_lid n in uu___3 = "SMTPatT" ->
       (FStarC_Errors.log_issue FStarC_Parser_AST.hasRange_term top
          FStarC_Errors_Codes.Warning_SMTPatTDeprecated ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_string)
          (Obj.magic "SMTPatT is deprecated; please just use SMTPat");
        (let uu___4 =
           let uu___5 =
             let uu___6 =
               let uu___7 =
                 let uu___8 =
                   let uu___9 = smt_pat_lid top.FStarC_Parser_AST.range in
                   FStarC_Parser_AST.Var uu___9 in
                 {
                   FStarC_Parser_AST.tm = uu___8;
                   FStarC_Parser_AST.range = (top.FStarC_Parser_AST.range);
                   FStarC_Parser_AST.level = (top.FStarC_Parser_AST.level)
                 } in
               (uu___7, a, FStarC_Parser_AST.Nothing) in
             FStarC_Parser_AST.App uu___6 in
           {
             FStarC_Parser_AST.tm = uu___5;
             FStarC_Parser_AST.range = (top.FStarC_Parser_AST.range);
             FStarC_Parser_AST.level = (top.FStarC_Parser_AST.level)
           } in
         desugar_term_maybe_top top_level env uu___4))
   | FStarC_Parser_AST.Construct (n, (a, uu___2)::[]) when
       let uu___3 = FStarC_Ident.string_of_lid n in uu___3 = "SMTPatOr" ->
       let uu___3 =
         let uu___4 =
           let uu___5 =
             let uu___6 =
               let uu___7 =
                 let uu___8 = smt_pat_or_lid top.FStarC_Parser_AST.range in
                 FStarC_Parser_AST.Var uu___8 in
               {
                 FStarC_Parser_AST.tm = uu___7;
                 FStarC_Parser_AST.range = (top.FStarC_Parser_AST.range);
                 FStarC_Parser_AST.level = (top.FStarC_Parser_AST.level)
               } in
             (uu___6, a, FStarC_Parser_AST.Nothing) in
           FStarC_Parser_AST.App uu___5 in
         {
           FStarC_Parser_AST.tm = uu___4;
           FStarC_Parser_AST.range = (top.FStarC_Parser_AST.range);
           FStarC_Parser_AST.level = (top.FStarC_Parser_AST.level)
         } in
       desugar_term_maybe_top top_level env uu___3
   | FStarC_Parser_AST.Name lid when
       let uu___2 = FStarC_Ident.string_of_lid lid in uu___2 = "Type0" ->
       let uu___2 =
         mk (FStarC_Syntax_Syntax.Tm_type FStarC_Syntax_Syntax.U_zero) in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Name lid when
       let uu___2 = FStarC_Ident.string_of_lid lid in uu___2 = "Type" ->
       let uu___2 =
         mk (FStarC_Syntax_Syntax.Tm_type FStarC_Syntax_Syntax.U_unknown) in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Construct (lid, (t, FStarC_Parser_AST.UnivApp)::[])
       when let uu___2 = FStarC_Ident.string_of_lid lid in uu___2 = "Type" ->
       let uu___2 =
         let uu___3 =
           let uu___4 = desugar_universe t in
           FStarC_Syntax_Syntax.Tm_type uu___4 in
         mk uu___3 in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Name lid when
       let uu___2 = FStarC_Ident.string_of_lid lid in uu___2 = "Effect" ->
       let uu___2 =
         mk (FStarC_Syntax_Syntax.Tm_constant FStarC_Const.Const_effect) in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Name lid when
       let uu___2 = FStarC_Ident.string_of_lid lid in uu___2 = "True" ->
       let uu___2 =
         let uu___3 =
           FStarC_Ident.set_lid_range FStarC_Parser_Const.true_lid
             top.FStarC_Parser_AST.range in
         FStarC_Syntax_Syntax.fvar_with_dd uu___3
           FStar_Pervasives_Native.None in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Name lid when
       let uu___2 = FStarC_Ident.string_of_lid lid in uu___2 = "False" ->
       let uu___2 =
         let uu___3 =
           FStarC_Ident.set_lid_range FStarC_Parser_Const.false_lid
             top.FStarC_Parser_AST.range in
         FStarC_Syntax_Syntax.fvar_with_dd uu___3
           FStar_Pervasives_Native.None in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Projector (eff_name, id) when
       (let uu___2 = FStarC_Ident.string_of_id id in
        is_special_effect_combinator uu___2) &&
         (FStarC_Syntax_DsEnv.is_effect_name env eff_name)
       ->
       let txt = FStarC_Ident.string_of_id id in
       let uu___2 = FStarC_Syntax_DsEnv.try_lookup_effect_defn env eff_name in
       (match uu___2 with
        | FStar_Pervasives_Native.Some ed ->
            let lid = FStarC_Syntax_Util.dm4f_lid ed txt in
            let uu___3 =
              FStarC_Syntax_Syntax.fvar_with_dd lid
                FStar_Pervasives_Native.None in
            (uu___3, noaqs)
        | FStar_Pervasives_Native.None ->
            let uu___3 =
              let uu___4 = FStarC_Ident.string_of_lid eff_name in
              FStarC_Format.fmt2
                "Member %s of effect %s is not accessible (using an effect abbreviation instead of the original effect ?)"
                uu___4 txt in
            failwith uu___3)
   | FStarC_Parser_AST.Var l ->
       let uu___2 = desugar_name mk setpos env true l in (uu___2, noaqs)
   | FStarC_Parser_AST.Name l ->
       let uu___2 = desugar_name mk setpos env true l in (uu___2, noaqs)
   | FStarC_Parser_AST.Projector (l, i) ->
       let name =
         let uu___2 = FStarC_Syntax_DsEnv.try_lookup_datacon env l in
         match uu___2 with
         | FStar_Pervasives_Native.Some uu___3 ->
             FStar_Pervasives_Native.Some (true, l)
         | FStar_Pervasives_Native.None ->
             let uu___3 =
               FStarC_Syntax_DsEnv.try_lookup_root_effect_name env l in
             (match uu___3 with
              | FStar_Pervasives_Native.Some new_name ->
                  FStar_Pervasives_Native.Some (false, new_name)
              | uu___4 -> FStar_Pervasives_Native.None) in
       (match name with
        | FStar_Pervasives_Native.Some (resolve, new_name) ->
            let uu___2 =
              let uu___3 =
                FStarC_Syntax_Util.mk_field_projector_name_from_ident
                  new_name i in
              desugar_name mk setpos env resolve uu___3 in
            (uu___2, noaqs)
        | uu___2 ->
            let uu___3 =
              let uu___4 = FStarC_Ident.string_of_lid l in
              FStarC_Format.fmt1 "Data constructor or effect %s not found"
                uu___4 in
            FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term top
              FStarC_Errors_Codes.Fatal_EffectNotFound ()
              (Obj.magic FStarC_Errors_Msg.is_error_message_string)
              (Obj.magic uu___3))
   | FStarC_Parser_AST.Discrim lid ->
       let uu___2 = FStarC_Syntax_DsEnv.try_lookup_datacon env lid in
       (match uu___2 with
        | FStar_Pervasives_Native.None ->
            let uu___3 =
              let uu___4 = FStarC_Ident.string_of_lid lid in
              FStarC_Format.fmt1 "Data constructor %s not found" uu___4 in
            FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term top
              FStarC_Errors_Codes.Fatal_DataContructorNotFound ()
              (Obj.magic FStarC_Errors_Msg.is_error_message_string)
              (Obj.magic uu___3)
        | uu___3 ->
            let lid' = FStarC_Syntax_Util.mk_discriminator lid in
            let uu___4 = desugar_name mk setpos env true lid' in
            (uu___4, noaqs))
   | FStarC_Parser_AST.Construct (l, args) ->
       let uu___2 = FStarC_Syntax_DsEnv.try_lookup_datacon env l in
       (match uu___2 with
        | FStar_Pervasives_Native.Some (head, uu___3) ->
            let head1 = mk (FStarC_Syntax_Syntax.Tm_fvar head) in
            (match args with
             | [] -> (head1, noaqs)
             | uu___4 ->
                 let uu___5 =
                   FStarC_Util.take
                     (fun uu___6 ->
                        match uu___6 with
                        | (uu___7, imp) -> imp = FStarC_Parser_AST.UnivApp)
                     args in
                 (match uu___5 with
                  | (universes, args1) ->
                      let universes1 =
                        FStarC_List.map
                          (fun x ->
                             desugar_universe (FStar_Pervasives_Native.fst x))
                          universes in
                      let uu___6 =
                        let uu___7 =
                          FStarC_List.map
                            (fun uu___8 ->
                               match uu___8 with
                               | (t, imp) ->
                                   let uu___9 = desugar_term_aq env t in
                                   (match uu___9 with
                                    | (te, aq) ->
                                        let uu___10 = arg_withimp_t imp te in
                                        (uu___10, aq))) args1 in
                        FStarC_List.unzip uu___7 in
                      (match uu___6 with
                       | (args2, aqs) ->
                           let head2 =
                             if universes1 = []
                             then head1
                             else
                               mk
                                 (FStarC_Syntax_Syntax.Tm_uinst
                                    (head1, universes1)) in
                           let tm =
                             if (FStarC_List.length args2) = Prims.int_zero
                             then head2
                             else
                               mk
                                 (FStarC_Syntax_Syntax.Tm_app
                                    {
                                      FStarC_Syntax_Syntax.hd = head2;
                                      FStarC_Syntax_Syntax.args = args2
                                    }) in
                           (tm, (join_aqs aqs)))))
        | FStar_Pervasives_Native.None ->
            let uu___3 = FStarC_Syntax_DsEnv.try_lookup_effect_name env l in
            (match uu___3 with
             | FStar_Pervasives_Native.None ->
                 let uu___4 =
                   let uu___5 =
                     let uu___6 = FStarC_Ident.string_of_lid l in
                     Prims.strcat uu___6 " not found" in
                   Prims.strcat "Constructor " uu___5 in
                 FStarC_Errors.raise_error FStarC_Ident.hasrange_lident l
                   FStarC_Errors_Codes.Fatal_ConstructorNotFound ()
                   (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                   (Obj.magic uu___4)
             | FStar_Pervasives_Native.Some uu___4 ->
                 let uu___5 =
                   let uu___6 =
                     let uu___7 = FStarC_Ident.string_of_lid l in
                     Prims.strcat uu___7 " used at an unexpected position" in
                   Prims.strcat "Effect " uu___6 in
                 FStarC_Errors.raise_error FStarC_Ident.hasrange_lident l
                   FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
                   (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                   (Obj.magic uu___5)))
   | FStarC_Parser_AST.Sum (binders, t) when
       FStarC_Util.for_all
         (fun uu___2 ->
            match uu___2 with
            | FStar_Pervasives.Inr uu___3 -> true
            | uu___3 -> false) binders
       ->
       let terms =
         let uu___2 =
           FStarC_List.map
             (fun uu___3 ->
                match uu___3 with
                | FStar_Pervasives.Inr x -> x
                | FStar_Pervasives.Inl uu___4 -> failwith "Impossible")
             binders in
         FStarC_List.op_At uu___2 [t] in
       let uu___2 =
         let uu___3 =
           FStarC_List.map
             (fun t1 ->
                let uu___4 = desugar_typ_aq env t1 in
                match uu___4 with
                | (t', aq) ->
                    let uu___5 = FStarC_Syntax_Syntax.as_arg t' in
                    (uu___5, aq)) terms in
         FStarC_List.unzip uu___3 in
       (match uu___2 with
        | (targs, aqs) ->
            let tup =
              let uu___3 =
                FStarC_Parser_Const_Tuples.mk_tuple_lid
                  (FStarC_List.length targs) top.FStarC_Parser_AST.range in
              FStarC_Syntax_DsEnv.fail_or env
                (FStarC_Syntax_DsEnv.try_lookup_lid env) uu___3 in
            let uu___3 =
              mk
                (FStarC_Syntax_Syntax.Tm_app
                   {
                     FStarC_Syntax_Syntax.hd = tup;
                     FStarC_Syntax_Syntax.args = targs
                   }) in
            (uu___3, (join_aqs aqs)))
   | FStarC_Parser_AST.Sum (binders, t) ->
       let uu___2 =
         let uu___3 =
           let uu___4 =
             let uu___5 =
               let uu___6 =
                 FStarC_Parser_AST.mk_binder (FStarC_Parser_AST.NoName t)
                   t.FStarC_Parser_AST.range FStarC_Parser_AST.Type_level
                   FStar_Pervasives_Native.None in
               FStar_Pervasives.Inl uu___6 in
             [uu___5] in
           FStarC_List.op_At binders uu___4 in
         FStarC_List.fold_left
           (fun uu___4 b ->
              match uu___4 with
              | (env1, tparams, typs) ->
                  let uu___5 =
                    match b with
                    | FStar_Pervasives.Inl b1 -> desugar_binder env1 b1
                    | FStar_Pervasives.Inr t1 ->
                        let uu___6 = desugar_typ env1 t1 in
                        (FStar_Pervasives_Native.None, uu___6, []) in
                  (match uu___5 with
                   | (xopt, t1, attrs) ->
                       let uu___6 =
                         match xopt with
                         | FStar_Pervasives_Native.None ->
                             let uu___7 =
                               FStarC_Syntax_Syntax.new_bv
                                 (FStar_Pervasives_Native.Some
                                    (top.FStarC_Parser_AST.range))
                                 (setpos FStarC_Syntax_Syntax.tun) in
                             (env1, uu___7)
                         | FStar_Pervasives_Native.Some x ->
                             FStarC_Syntax_DsEnv.push_bv env1 x in
                       (match uu___6 with
                        | (env2, x) ->
                            let uu___7 =
                              let uu___8 =
                                let uu___9 =
                                  mk_binder_with_attrs
                                    {
                                      FStarC_Syntax_Syntax.ppname =
                                        (x.FStarC_Syntax_Syntax.ppname);
                                      FStarC_Syntax_Syntax.index =
                                        (x.FStarC_Syntax_Syntax.index);
                                      FStarC_Syntax_Syntax.sort = t1
                                    } FStar_Pervasives_Native.None attrs in
                                [uu___9] in
                              FStarC_List.op_At tparams uu___8 in
                            let uu___8 =
                              let uu___9 =
                                let uu___10 =
                                  let uu___11 = no_annot_abs tparams t1 in
                                  FStarC_Syntax_Syntax.as_arg uu___11 in
                                [uu___10] in
                              FStarC_List.op_At typs uu___9 in
                            (env2, uu___7, uu___8)))) (env, [], []) uu___3 in
       (match uu___2 with
        | (env1, uu___3, targs) ->
            let tup =
              let uu___4 =
                FStarC_Parser_Const_Tuples.mk_dtuple_lid
                  (FStarC_List.length targs) top.FStarC_Parser_AST.range in
              FStarC_Syntax_DsEnv.fail_or env1
                (FStarC_Syntax_DsEnv.try_lookup_lid env1) uu___4 in
            let uu___4 =
              mk
                (FStarC_Syntax_Syntax.Tm_app
                   {
                     FStarC_Syntax_Syntax.hd = tup;
                     FStarC_Syntax_Syntax.args = targs
                   }) in
            (uu___4, noaqs))
   | FStarC_Parser_AST.Product (binders, t) ->
       let uu___2 = uncurry binders t in
       (match uu___2 with
        | (bs, t1) ->
            let rec aux env1 aqs bs1 uu___3 =
              match uu___3 with
              | [] ->
                  let cod =
                    desugar_comp top.FStarC_Parser_AST.range true env1 t1 in
                  let uu___4 =
                    let uu___5 =
                      FStarC_Syntax_Util.arrow (FStarC_List.rev bs1) cod in
                    setpos uu___5 in
                  (uu___4, aqs)
              | hd::tl ->
                  let uu___4 = desugar_binder_aq env1 hd in
                  (match uu___4 with
                   | (bb, aqs') ->
                       let uu___5 =
                         as_binder env1 hd.FStarC_Parser_AST.aqual bb in
                       (match uu___5 with
                        | (b, env2) ->
                            aux env2 (FStarC_List.op_At aqs' aqs) (b :: bs1)
                              tl)) in
            aux env [] [] bs)
   | FStarC_Parser_AST.Refine (b, f) ->
       let uu___2 = desugar_binder env b in
       (match uu___2 with
        | (FStar_Pervasives_Native.None, uu___3, uu___4) ->
            failwith "Missing binder in refinement"
        | b1 ->
            let uu___3 = as_binder env FStar_Pervasives_Native.None b1 in
            (match uu___3 with
             | (b2, env1) ->
                 let f1 = desugar_formula env1 f in
                 let uu___4 =
                   let uu___5 =
                     FStarC_Syntax_Util.refine
                       b2.FStarC_Syntax_Syntax.binder_bv f1 in
                   setpos uu___5 in
                 (uu___4, noaqs)))
   | FStarC_Parser_AST.Function (branches, r1) ->
       let x = FStarC_Ident.gen r1 in
       let t' =
         let uu___2 =
           let uu___3 =
             let uu___4 =
               let uu___5 =
                 FStarC_Parser_AST.mk_pattern
                   (FStarC_Parser_AST.PatVar
                      (x, FStar_Pervasives_Native.None, [])) r1 in
               [uu___5] in
             let uu___5 =
               let uu___6 =
                 let uu___7 =
                   let uu___8 =
                     let uu___9 =
                       let uu___10 = FStarC_Ident.lid_of_ids [x] in
                       FStarC_Parser_AST.Var uu___10 in
                     FStarC_Parser_AST.mk_term uu___9 r1
                       FStarC_Parser_AST.Expr in
                   (uu___8, FStar_Pervasives_Native.None,
                     FStar_Pervasives_Native.None, branches) in
                 FStarC_Parser_AST.Match uu___7 in
               FStarC_Parser_AST.mk_term uu___6 top.FStarC_Parser_AST.range
                 FStarC_Parser_AST.Expr in
             (uu___4, uu___5) in
           FStarC_Parser_AST.Abs uu___3 in
         FStarC_Parser_AST.mk_term uu___2 top.FStarC_Parser_AST.range
           FStarC_Parser_AST.Expr in
       desugar_term_maybe_top top_level env t'
   | FStarC_Parser_AST.Abs (binders, body) ->
       let bvss = FStarC_List.map gather_pattern_bound_vars binders in
       let check_disjoint sets =
         let rec aux acc sets1 =
           match sets1 with
           | [] -> FStar_Pervasives_Native.None
           | set::sets2 ->
               let i =
                 Obj.magic
                   (FStarC_Class_Setlike.inter ()
                      (Obj.magic
                         (FStarC_FlatSet.setlike_flat_set
                            FStarC_Syntax_Syntax.ord_ident)) (Obj.magic acc)
                      (Obj.magic set)) in
               let uu___2 =
                 FStarC_Class_Setlike.is_empty ()
                   (Obj.magic
                      (FStarC_FlatSet.setlike_flat_set
                         FStarC_Syntax_Syntax.ord_ident)) (Obj.magic i) in
               if uu___2
               then
                 let uu___3 =
                   Obj.magic
                     (FStarC_Class_Setlike.union ()
                        (Obj.magic
                           (FStarC_FlatSet.setlike_flat_set
                              FStarC_Syntax_Syntax.ord_ident))
                        (Obj.magic acc) (Obj.magic set)) in
                 aux uu___3 sets2
               else
                 (let uu___4 =
                    let uu___5 =
                      FStarC_Class_Setlike.elems ()
                        (Obj.magic
                           (FStarC_FlatSet.setlike_flat_set
                              FStarC_Syntax_Syntax.ord_ident)) (Obj.magic i) in
                    FStarC_List.hd uu___5 in
                  FStar_Pervasives_Native.Some uu___4) in
         let uu___2 =
           Obj.magic
             (FStarC_Class_Setlike.empty ()
                (Obj.magic
                   (FStarC_FlatSet.setlike_flat_set
                      FStarC_Syntax_Syntax.ord_ident)) ()) in
         aux uu___2 sets in
       ((let uu___3 = check_disjoint bvss in
         match uu___3 with
         | FStar_Pervasives_Native.None -> ()
         | FStar_Pervasives_Native.Some id ->
             let uu___4 =
               let uu___5 =
                 FStarC_Errors_Msg.text
                   "Non-linear patterns are not permitted." in
               let uu___6 =
                 let uu___7 =
                   let uu___8 = FStarC_Errors_Msg.text "The variable " in
                   let uu___9 =
                     let uu___10 =
                       let uu___11 =
                         FStarC_Class_PP.pp FStarC_Ident.pretty_ident id in
                       FStar_Pprint.squotes uu___11 in
                     let uu___11 =
                       FStarC_Errors_Msg.text
                         " appears more than once in this function definition." in
                     FStar_Pprint.op_Hat_Slash_Hat uu___10 uu___11 in
                   FStar_Pprint.op_Hat_Slash_Hat uu___8 uu___9 in
                 [uu___7] in
               uu___5 :: uu___6 in
             FStarC_Errors.raise_error FStarC_Ident.hasrange_ident id
               FStarC_Errors_Codes.Fatal_NonLinearPatternNotPermitted ()
               (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
               (Obj.magic uu___4));
        (let binders1 = FStarC_List.map replace_unit_pattern binders in
         let uu___3 =
           FStarC_List.fold_left
             (fun uu___4 pat ->
                match uu___4 with
                | (env1, ftvs) ->
                    (match pat.FStarC_Parser_AST.pat with
                     | FStarC_Parser_AST.PatAscribed
                         (uu___5, (t, FStar_Pervasives_Native.None)) ->
                         let uu___6 =
                           let uu___7 =
                             FStarC_ToSyntax_TickedVars.free_ticked_vars env1
                               t in
                           FStarC_List.op_At uu___7 ftvs in
                         (env1, uu___6)
                     | FStarC_Parser_AST.PatAscribed
                         (uu___5, (t, FStar_Pervasives_Native.Some tac)) ->
                         let uu___6 =
                           let uu___7 =
                             FStarC_ToSyntax_TickedVars.free_ticked_vars env1
                               t in
                           let uu___8 =
                             let uu___9 =
                               FStarC_ToSyntax_TickedVars.free_ticked_vars
                                 env1 tac in
                             FStarC_List.op_At uu___9 ftvs in
                           FStarC_List.op_At uu___7 uu___8 in
                         (env1, uu___6)
                     | uu___5 -> (env1, ftvs))) (env, []) binders1 in
         match uu___3 with
         | (uu___4, ftv) ->
             let ftv1 =
               FStarC_Class_Ord.sort_dedup FStarC_Syntax_Syntax.ord_ident ftv in
             let binders2 =
               let uu___5 =
                 FStarC_List.map
                   (fun a ->
                      FStarC_Parser_AST.mk_pattern
                        (FStarC_Parser_AST.PatVar
                           (a,
                             (FStar_Pervasives_Native.Some
                                FStarC_Parser_AST.Implicit), []))
                        top.FStarC_Parser_AST.range) ftv1 in
               FStarC_List.op_At uu___5 binders1 in
             let rec aux aqs env1 bs sc_pat_opt pats =
               match pats with
               | [] ->
                   let uu___5 = desugar_term_aq env1 body in
                   (match uu___5 with
                    | (body1, aq) ->
                        let body2 =
                          match sc_pat_opt with
                          | FStar_Pervasives_Native.Some (sc, pat) ->
                              let body3 =
                                let uu___6 =
                                  let uu___7 =
                                    FStarC_Syntax_Syntax.pat_bvs pat in
                                  FStarC_List.map
                                    FStarC_Syntax_Syntax.mk_binder uu___7 in
                                FStarC_Syntax_Subst.close uu___6 body1 in
                              FStarC_Syntax_Syntax.mk
                                (FStarC_Syntax_Syntax.Tm_match
                                   {
                                     FStarC_Syntax_Syntax.scrutinee = sc;
                                     FStarC_Syntax_Syntax.ret_opt =
                                       FStar_Pervasives_Native.None;
                                     FStarC_Syntax_Syntax.brs =
                                       [(pat, FStar_Pervasives_Native.None,
                                          body3)];
                                     FStarC_Syntax_Syntax.rc_opt1 =
                                       FStar_Pervasives_Native.None
                                   }) body3.FStarC_Syntax_Syntax.pos
                          | FStar_Pervasives_Native.None -> body1 in
                        let uu___6 =
                          let uu___7 =
                            no_annot_abs (FStarC_List.rev bs) body2 in
                          setpos uu___7 in
                        (uu___6, (FStarC_List.op_At aq aqs)))
               | p::rest ->
                   let uu___5 = desugar_binding_pat_aq env1 p in
                   (match uu___5 with
                    | ((env2, b, pat), aq) ->
                        let pat1 =
                          match pat with
                          | [] -> FStar_Pervasives_Native.None
                          | (p1, uu___6)::[] ->
                              FStar_Pervasives_Native.Some p1
                          | uu___6 ->
                              let uu___7 =
                                let uu___8 =
                                  FStarC_Errors_Msg.text
                                    "Disjunctive patterns are not supported in abstractions" in
                                [uu___8] in
                              FStarC_Errors.raise_error
                                FStarC_Parser_AST.hasRange_pattern p
                                FStarC_Errors_Codes.Fatal_UnsupportedDisjuctivePatterns
                                ()
                                (Obj.magic
                                   FStarC_Errors_Msg.is_error_message_list_doc)
                                (Obj.magic uu___7) in
                        let uu___6 =
                          match b with
                          | LetBinder uu___7 -> failwith "Impossible"
                          | LocalBinder (x, aq1, attrs) ->
                              let sc_pat_opt1 =
                                match (pat1, sc_pat_opt) with
                                | (FStar_Pervasives_Native.None, uu___7) ->
                                    sc_pat_opt
                                | (FStar_Pervasives_Native.Some p1,
                                   FStar_Pervasives_Native.None) ->
                                    let uu___7 =
                                      let uu___8 =
                                        FStarC_Syntax_Syntax.bv_to_name x in
                                      (uu___8, p1) in
                                    FStar_Pervasives_Native.Some uu___7
                                | (FStar_Pervasives_Native.Some p1,
                                   FStar_Pervasives_Native.Some (sc, p')) ->
                                    (match ((sc.FStarC_Syntax_Syntax.n),
                                             (p'.FStarC_Syntax_Syntax.v))
                                     with
                                     | (FStarC_Syntax_Syntax.Tm_name uu___7,
                                        uu___8) ->
                                         let tup2 =
                                           let uu___9 =
                                             FStarC_Parser_Const_Tuples.mk_tuple_data_lid
                                               (Prims.of_int (2))
                                               top.FStarC_Parser_AST.range in
                                           FStarC_Syntax_Syntax.lid_and_dd_as_fv
                                             uu___9
                                             (FStar_Pervasives_Native.Some
                                                FStarC_Syntax_Syntax.Data_ctor) in
                                         let sc1 =
                                           let uu___9 =
                                             let uu___10 =
                                               let uu___11 =
                                                 mk
                                                   (FStarC_Syntax_Syntax.Tm_fvar
                                                      tup2) in
                                               let uu___12 =
                                                 let uu___13 =
                                                   FStarC_Syntax_Syntax.as_arg
                                                     sc in
                                                 let uu___14 =
                                                   let uu___15 =
                                                     let uu___16 =
                                                       FStarC_Syntax_Syntax.bv_to_name
                                                         x in
                                                     FStarC_Syntax_Syntax.as_arg
                                                       uu___16 in
                                                   [uu___15] in
                                                 uu___13 :: uu___14 in
                                               {
                                                 FStarC_Syntax_Syntax.hd =
                                                   uu___11;
                                                 FStarC_Syntax_Syntax.args =
                                                   uu___12
                                               } in
                                             FStarC_Syntax_Syntax.Tm_app
                                               uu___10 in
                                           FStarC_Syntax_Syntax.mk uu___9
                                             top.FStarC_Parser_AST.range in
                                         let p2 =
                                           let uu___9 =
                                             FStarC_Range_Ops.union_ranges
                                               p'.FStarC_Syntax_Syntax.p
                                               p1.FStarC_Syntax_Syntax.p in
                                           FStarC_Syntax_Syntax.withinfo
                                             (FStarC_Syntax_Syntax.Pat_cons
                                                (tup2,
                                                  FStar_Pervasives_Native.None,
                                                  [(p', false); (p1, false)]))
                                             uu___9 in
                                         FStar_Pervasives_Native.Some
                                           (sc1, p2)
                                     | (FStarC_Syntax_Syntax.Tm_app
                                        { FStarC_Syntax_Syntax.hd = uu___7;
                                          FStarC_Syntax_Syntax.args = args;_},
                                        FStarC_Syntax_Syntax.Pat_cons
                                        (uu___8, uu___9, pats1)) ->
                                         let tupn =
                                           let uu___10 =
                                             FStarC_Parser_Const_Tuples.mk_tuple_data_lid
                                               (Prims.int_one +
                                                  (FStarC_List.length args))
                                               top.FStarC_Parser_AST.range in
                                           FStarC_Syntax_Syntax.lid_and_dd_as_fv
                                             uu___10
                                             (FStar_Pervasives_Native.Some
                                                FStarC_Syntax_Syntax.Data_ctor) in
                                         let sc1 =
                                           let uu___10 =
                                             let uu___11 =
                                               let uu___12 =
                                                 mk
                                                   (FStarC_Syntax_Syntax.Tm_fvar
                                                      tupn) in
                                               let uu___13 =
                                                 let uu___14 =
                                                   let uu___15 =
                                                     let uu___16 =
                                                       FStarC_Syntax_Syntax.bv_to_name
                                                         x in
                                                     FStarC_Syntax_Syntax.as_arg
                                                       uu___16 in
                                                   [uu___15] in
                                                 FStarC_List.op_At args
                                                   uu___14 in
                                               {
                                                 FStarC_Syntax_Syntax.hd =
                                                   uu___12;
                                                 FStarC_Syntax_Syntax.args =
                                                   uu___13
                                               } in
                                             FStarC_Syntax_Syntax.Tm_app
                                               uu___11 in
                                           mk uu___10 in
                                         let p2 =
                                           let uu___10 =
                                             FStarC_Range_Ops.union_ranges
                                               p'.FStarC_Syntax_Syntax.p
                                               p1.FStarC_Syntax_Syntax.p in
                                           FStarC_Syntax_Syntax.withinfo
                                             (FStarC_Syntax_Syntax.Pat_cons
                                                (tupn,
                                                  FStar_Pervasives_Native.None,
                                                  (FStarC_List.op_At pats1
                                                     [(p1, false)]))) uu___10 in
                                         FStar_Pervasives_Native.Some
                                           (sc1, p2)
                                     | uu___7 -> failwith "Impossible") in
                              let uu___7 = mk_binder_with_attrs x aq1 attrs in
                              (uu___7, sc_pat_opt1) in
                        (match uu___6 with
                         | (b1, sc_pat_opt1) ->
                             aux (FStarC_List.op_At aq aqs) env2 (b1 :: bs)
                               sc_pat_opt1 rest)) in
             aux [] env [] FStar_Pervasives_Native.None binders2))
   | FStarC_Parser_AST.App (uu___2, uu___3, FStarC_Parser_AST.UnivApp) ->
       let rec aux universes e =
         let uu___4 = let uu___5 = unparen e in uu___5.FStarC_Parser_AST.tm in
         match uu___4 with
         | FStarC_Parser_AST.App (e1, t, FStarC_Parser_AST.UnivApp) ->
             let univ_arg = desugar_universe t in
             aux (univ_arg :: universes) e1
         | uu___5 ->
             let uu___6 = desugar_term_aq env e in
             (match uu___6 with
              | (head, aq) ->
                  let uu___7 =
                    mk (FStarC_Syntax_Syntax.Tm_uinst (head, universes)) in
                  (uu___7, aq)) in
       aux [] top
   | FStarC_Parser_AST.App (e, t, imp) ->
       let uu___2 = desugar_term_aq env e in
       (match uu___2 with
        | (head, aq1) ->
            let uu___3 = desugar_term_aq env t in
            (match uu___3 with
             | (t1, aq2) ->
                 let arg = arg_withimp_t imp t1 in
                 let uu___4 =
                   FStarC_Syntax_Syntax.extend_app head arg
                     top.FStarC_Parser_AST.range in
                 (uu___4, (FStarC_List.op_At aq1 aq2))))
   | FStarC_Parser_AST.Bind (x, t1, t2) ->
       ((let uu___3 =
           let uu___4 =
             FStarC_Errors_Msg.text
               "The lightweight do notation [x <-- y; z] or [x ;; z] is deprecated." in
           let uu___5 =
             let uu___6 =
               FStarC_Errors_Msg.text
                 "Use let operators (i.e. [let* x = y in z] or [y ;* z], [*] being any sequence of operator characters) instead." in
             [uu___6] in
           uu___4 :: uu___5 in
         FStarC_Errors.log_issue FStarC_Class_HasRange.hasRange_range
           top.FStarC_Parser_AST.range
           FStarC_Errors_Codes.Warning_DeprecatedLightDoNotation ()
           (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
           (Obj.magic uu___3));
        (let xpat =
           let uu___3 = FStarC_Ident.range_of_id x in
           FStarC_Parser_AST.mk_pattern
             (FStarC_Parser_AST.PatVar (x, FStar_Pervasives_Native.None, []))
             uu___3 in
         let k =
           FStarC_Parser_AST.mk_term (FStarC_Parser_AST.Abs ([xpat], t2))
             t2.FStarC_Parser_AST.range t2.FStarC_Parser_AST.level in
         let bind_lid =
           let uu___3 = FStarC_Ident.range_of_id x in
           FStarC_Ident.lid_of_path ["bind"] uu___3 in
         let bind =
           let uu___3 = FStarC_Ident.range_of_id x in
           FStarC_Parser_AST.mk_term (FStarC_Parser_AST.Var bind_lid) uu___3
             FStarC_Parser_AST.Expr in
         let uu___3 =
           FStarC_Parser_AST.mkExplicitApp bind [t1; k]
             top.FStarC_Parser_AST.range in
         desugar_term_aq env uu___3))
   | FStarC_Parser_AST.Seq (t1, t2) ->
       let p =
         FStarC_Parser_AST.mk_pattern
           (FStarC_Parser_AST.PatWild (FStar_Pervasives_Native.None, []))
           t1.FStarC_Parser_AST.range in
       let p1 =
         let uu___2 =
           let uu___3 =
             let uu___4 =
               let uu___5 = unit_ty p.FStarC_Parser_AST.prange in
               (uu___5, FStar_Pervasives_Native.None) in
             (p, uu___4) in
           FStarC_Parser_AST.PatAscribed uu___3 in
         FStarC_Parser_AST.mk_pattern uu___2 p.FStarC_Parser_AST.prange in
       let t =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.Let
              (FStarC_Parser_AST.LocalNoLetQualifier,
                [(FStar_Pervasives_Native.None, (p1, t1))], t2))
           top.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
       let uu___2 = desugar_term_aq env t in
       (match uu___2 with
        | (tm, s) ->
            let uu___3 =
              mk
                (FStarC_Syntax_Syntax.Tm_meta
                   {
                     FStarC_Syntax_Syntax.tm2 = tm;
                     FStarC_Syntax_Syntax.meta =
                       (FStarC_Syntax_Syntax.Meta_desugared
                          FStarC_Syntax_Syntax.Sequence)
                   }) in
            (uu___3, s))
   | FStarC_Parser_AST.LetOpen (lid, e) ->
       let env1 =
         FStarC_Syntax_DsEnv.push_namespace env lid
           FStarC_Syntax_Syntax.Unrestricted in
       let uu___2 =
         let uu___3 = FStarC_Syntax_DsEnv.expect_typ env1 in
         if uu___3 then desugar_typ_aq else desugar_term_aq in
       uu___2 env1 e
   | FStarC_Parser_AST.LetOpenRecord (r, rty, e) ->
       let rec head_of t =
         match t.FStarC_Parser_AST.tm with
         | FStarC_Parser_AST.App (t1, uu___2, uu___3) -> head_of t1
         | uu___2 -> t in
       let tycon = head_of rty in
       let tycon_name =
         match tycon.FStarC_Parser_AST.tm with
         | FStarC_Parser_AST.Var l -> l
         | uu___2 ->
             let uu___3 =
               let uu___4 = FStarC_Parser_AST.term_to_string rty in
               FStarC_Format.fmt1
                 "This type must be a (possibly applied) record name: %s"
                 uu___4 in
             FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term rty
               FStarC_Errors_Codes.Error_BadLetOpenRecord ()
               (Obj.magic FStarC_Errors_Msg.is_error_message_string)
               (Obj.magic uu___3) in
       let record =
         let uu___2 =
           FStarC_Syntax_DsEnv.try_lookup_record_type env tycon_name in
         match uu___2 with
         | FStar_Pervasives_Native.Some r1 -> r1
         | FStar_Pervasives_Native.None ->
             let uu___3 =
               let uu___4 = FStarC_Parser_AST.term_to_string rty in
               FStarC_Format.fmt1 "Not a record type: `%s`" uu___4 in
             FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term rty
               FStarC_Errors_Codes.Error_BadLetOpenRecord ()
               (Obj.magic FStarC_Errors_Msg.is_error_message_string)
               (Obj.magic uu___3) in
       let constrname =
         let uu___2 =
           FStarC_Ident.ns_of_lid record.FStarC_Syntax_DsEnv.typename in
         FStarC_Ident.lid_of_ns_and_id uu___2
           record.FStarC_Syntax_DsEnv.constrname in
       let mk_pattern p =
         FStarC_Parser_AST.mk_pattern p r.FStarC_Parser_AST.range in
       let elab =
         let pat =
           let uu___2 =
             let uu___3 =
               let uu___4 = mk_pattern (FStarC_Parser_AST.PatName constrname) in
               let uu___5 =
                 FStarC_List.map
                   (fun uu___6 ->
                      match uu___6 with
                      | (field, uu___7) ->
                          mk_pattern
                            (FStarC_Parser_AST.PatVar
                               (field, FStar_Pervasives_Native.None, [])))
                   record.FStarC_Syntax_DsEnv.fields in
               (uu___4, uu___5) in
             FStarC_Parser_AST.PatApp uu___3 in
           mk_pattern uu___2 in
         let branch = (pat, FStar_Pervasives_Native.None, e) in
         let r1 =
           FStarC_Parser_AST.mk_term
             (FStarC_Parser_AST.Ascribed
                (r, rty, FStar_Pervasives_Native.None, false))
             r.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
         {
           FStarC_Parser_AST.tm =
             (FStarC_Parser_AST.Match
                (r1, FStar_Pervasives_Native.None,
                  FStar_Pervasives_Native.None, [branch]));
           FStarC_Parser_AST.range = (top.FStarC_Parser_AST.range);
           FStarC_Parser_AST.level = (top.FStarC_Parser_AST.level)
         } in
       desugar_term_maybe_top top_level env elab
   | FStarC_Parser_AST.LetOperator (lets, body) ->
       (match lets with
        | [] ->
            failwith
              "Impossible: a LetOperator (e.g. let+, let*...) cannot contain zero let binding"
        | (letOp, letPat, letDef)::tl ->
            let term_of_op op =
              let uu___2 = FStarC_Ident.range_of_id op in
              FStarC_Parser_AST.mk_term (FStarC_Parser_AST.Op (op, []))
                uu___2 FStarC_Parser_AST.Expr in
            let mproduct_def =
              FStarC_List.fold_left
                (fun def uu___2 ->
                   match uu___2 with
                   | (andOp, andPat, andDef) ->
                       let uu___3 = term_of_op andOp in
                       FStarC_Parser_AST.mkExplicitApp uu___3 [def; andDef]
                         top.FStarC_Parser_AST.range) letDef tl in
            let mproduct_pat =
              FStarC_List.fold_left
                (fun pat uu___2 ->
                   match uu___2 with
                   | (andOp, andPat, andDef) ->
                       FStarC_Parser_AST.mk_pattern
                         (FStarC_Parser_AST.PatTuple ([pat; andPat], false))
                         andPat.FStarC_Parser_AST.prange) letPat tl in
            let fn =
              let uu___2 =
                let uu___3 =
                  let uu___4 =
                    let uu___5 = hoist_pat_ascription mproduct_pat in
                    [uu___5] in
                  (uu___4, body) in
                FStarC_Parser_AST.Abs uu___3 in
              FStarC_Parser_AST.mk_term uu___2 body.FStarC_Parser_AST.range
                body.FStarC_Parser_AST.level in
            let let_op = term_of_op letOp in
            let t =
              FStarC_Parser_AST.mkExplicitApp let_op [mproduct_def; fn]
                top.FStarC_Parser_AST.range in
            desugar_term_aq env t)
   | FStarC_Parser_AST.Let (qual, lbs, body) ->
       let is_rec = qual = FStarC_Parser_AST.LocalRec in
       (if
          (Prims.op_Negation is_rec) &&
            ((FStarC_List.length lbs) > Prims.int_one)
        then
          (let lb = FStarC_List.nth lbs Prims.int_one in
           FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_pattern
             (FStar_Pervasives_Native.__proj__Mktuple2__item___1
                (FStar_Pervasives_Native.__proj__Mktuple2__item___2 lb))
             FStarC_Errors_Codes.Fatal_MultipleLetBinding ()
             (Obj.magic FStarC_Errors_Msg.is_error_message_string)
             (Obj.magic
                "Multiple 'let' bindings are only allowed in 'let rec'"))
        else ();
        (let extra_attrs =
           if qual = FStarC_Parser_AST.LocalUnfold
           then
             [FStarC_Parser_AST.inline_let_attribute;
             FStarC_Parser_AST.inline_let_vc_attribute]
           else [] in
         let add_extra_attrs attrs =
           match (attrs, extra_attrs) with
           | (uu___3, []) -> attrs
           | (FStar_Pervasives_Native.None, uu___3) ->
               FStar_Pervasives_Native.Some extra_attrs
           | (FStar_Pervasives_Native.Some attrs1, uu___3) ->
               FStar_Pervasives_Native.Some
                 (FStarC_List.op_At attrs1 extra_attrs) in
         let ds_let_rec_or_app uu___3 =
           let bindings = lbs in
           let funs =
             FStarC_List.map
               (fun uu___4 ->
                  match uu___4 with
                  | (attr_opt, (p, def)) ->
                      let uu___5 = is_app_pattern p in
                      if uu___5
                      then
                        let uu___6 = destruct_app_pattern env top_level p in
                        ((add_extra_attrs attr_opt), uu___6, def)
                      else
                        (let uu___7 = FStarC_Parser_AST.un_function p def in
                         match uu___7 with
                         | FStar_Pervasives_Native.Some (p1, def1) ->
                             let uu___8 =
                               destruct_app_pattern env top_level p1 in
                             ((add_extra_attrs attr_opt), uu___8, def1)
                         | uu___8 ->
                             (match p.FStarC_Parser_AST.pat with
                              | FStarC_Parser_AST.PatAscribed
                                  ({
                                     FStarC_Parser_AST.pat =
                                       FStarC_Parser_AST.PatVar
                                       (id, uu___9, uu___10);
                                     FStarC_Parser_AST.prange = uu___11;_},
                                   t)
                                  ->
                                  if top_level
                                  then
                                    let uu___12 =
                                      let uu___13 =
                                        let uu___14 =
                                          FStarC_Syntax_DsEnv.qualify env id in
                                        FStar_Pervasives.Inr uu___14 in
                                      (uu___13, [],
                                        (FStar_Pervasives_Native.Some t)) in
                                    ((add_extra_attrs attr_opt), uu___12,
                                      def)
                                  else
                                    ((add_extra_attrs attr_opt),
                                      ((FStar_Pervasives.Inl id), [],
                                        (FStar_Pervasives_Native.Some t)),
                                      def)
                              | FStarC_Parser_AST.PatVar
                                  (id, uu___9, uu___10) ->
                                  if top_level
                                  then
                                    let uu___11 =
                                      let uu___12 =
                                        let uu___13 =
                                          FStarC_Syntax_DsEnv.qualify env id in
                                        FStar_Pervasives.Inr uu___13 in
                                      (uu___12, [],
                                        FStar_Pervasives_Native.None) in
                                    ((add_extra_attrs attr_opt), uu___11,
                                      def)
                                  else
                                    ((add_extra_attrs attr_opt),
                                      ((FStar_Pervasives.Inl id), [],
                                        FStar_Pervasives_Native.None), def)
                              | uu___9 ->
                                  FStarC_Errors.raise_error
                                    FStarC_Parser_AST.hasRange_pattern p
                                    FStarC_Errors_Codes.Fatal_UnexpectedLetBinding
                                    ()
                                    (Obj.magic
                                       FStarC_Errors_Msg.is_error_message_string)
                                    (Obj.magic "Unexpected let binding"))))
               bindings in
           let uu___4 =
             FStarC_List.fold_left
               (fun uu___5 uu___6 ->
                  match (uu___5, uu___6) with
                  | ((env1, fnames, rec_bindings, used_markers),
                     (_attr_opt, (f, uu___7, uu___8), uu___9)) ->
                      let uu___10 =
                        match f with
                        | FStar_Pervasives.Inl x ->
                            let uu___11 = FStarC_Syntax_DsEnv.push_bv' env1 x in
                            (match uu___11 with
                             | (env2, xx, used_marker) ->
                                 let dummy_ref = FStarC_Effect.mk_ref true in
                                 let uu___12 =
                                   let uu___13 =
                                     FStarC_Syntax_Syntax.mk_binder xx in
                                   uu___13 :: rec_bindings in
                                 (env2, (FStar_Pervasives.Inl xx), uu___12,
                                   (used_marker :: used_markers)))
                        | FStar_Pervasives.Inr l ->
                            let uu___11 =
                              let uu___12 = FStarC_Ident.ident_of_lid l in
                              FStarC_Syntax_DsEnv.push_top_level_rec_binding
                                env1 uu___12 in
                            (match uu___11 with
                             | (env2, used_marker) ->
                                 (env2, (FStar_Pervasives.Inr l),
                                   rec_bindings, (used_marker ::
                                   used_markers))) in
                      (match uu___10 with
                       | (env2, lbname, rec_bindings1, used_markers1) ->
                           (env2, (lbname :: fnames), rec_bindings1,
                             used_markers1))) (env, [], [], []) funs in
           match uu___4 with
           | (env', fnames, rec_bindings, used_markers) ->
               let fnames1 = FStarC_List.rev fnames in
               let rec_bindings1 = FStarC_List.rev rec_bindings in
               let used_markers1 = FStarC_List.rev used_markers in
               let desugar_one_def env1 lbname uu___5 =
                 match uu___5 with
                 | (attrs_opt, (uu___6, args, result_t), def) ->
                     let args1 = FStarC_List.map replace_unit_pattern args in
                     let pos = def.FStarC_Parser_AST.range in
                     let def1 =
                       match result_t with
                       | FStar_Pervasives_Native.None -> def
                       | FStar_Pervasives_Native.Some (t, tacopt) ->
                           let t1 =
                             let uu___7 = is_comp_type env1 t in
                             if uu___7
                             then
                               ((let uu___9 =
                                   FStarC_List.tryFind
                                     (fun x ->
                                        let uu___10 = is_var_pattern x in
                                        Prims.op_Negation uu___10) args1 in
                                 match uu___9 with
                                 | FStar_Pervasives_Native.None -> ()
                                 | FStar_Pervasives_Native.Some p ->
                                     let uu___10 =
                                       let uu___11 =
                                         FStarC_Errors_Msg.text
                                           "Computation type annotations are only permitted on let-bindings without inlined patterns." in
                                       let uu___12 =
                                         let uu___13 =
                                           FStarC_Errors_Msg.text
                                             "Suggestion: replace this pattern with a variable." in
                                         [uu___13] in
                                       uu___11 :: uu___12 in
                                     FStarC_Errors.raise_error
                                       FStarC_Parser_AST.hasRange_pattern p
                                       FStarC_Errors_Codes.Fatal_ComputationTypeNotAllowed
                                       ()
                                       (Obj.magic
                                          FStarC_Errors_Msg.is_error_message_list_doc)
                                       (Obj.magic uu___10));
                                t)
                             else
                               (let uu___9 =
                                  ((FStarC_Options.ml_ish ()) &&
                                     (let uu___10 =
                                        let uu___11 =
                                          FStarC_Parser_Const.effect_ML_lid
                                            () in
                                        FStarC_Syntax_DsEnv.try_lookup_effect_name
                                          env1 uu___11 in
                                      FStar_Pervasives_Native.uu___is_Some
                                        uu___10))
                                    &&
                                    ((Prims.op_Negation is_rec) ||
                                       ((FStarC_List.length args1) <>
                                          Prims.int_zero)) in
                                if uu___9
                                then FStarC_Parser_AST.ml_comp t
                                else FStarC_Parser_AST.tot_comp t) in
                           FStarC_Parser_AST.mk_term
                             (FStarC_Parser_AST.Ascribed
                                (def, t1, tacopt, false))
                             def.FStarC_Parser_AST.range
                             FStarC_Parser_AST.Expr in
                     let def2 =
                       match args1 with
                       | [] -> def1
                       | uu___7 ->
                           let uu___8 =
                             FStarC_Parser_AST.un_curry_abs args1 def1 in
                           FStarC_Parser_AST.mk_term uu___8
                             top.FStarC_Parser_AST.range
                             top.FStarC_Parser_AST.level in
                     let uu___7 = desugar_term_aq env1 def2 in
                     (match uu___7 with
                      | (body1, aq) ->
                          let lbname1 =
                            match lbname with
                            | FStar_Pervasives.Inl x ->
                                FStar_Pervasives.Inl x
                            | FStar_Pervasives.Inr l ->
                                let uu___8 =
                                  FStarC_Syntax_Syntax.lid_and_dd_as_fv l
                                    FStar_Pervasives_Native.None in
                                FStar_Pervasives.Inr uu___8 in
                          let body2 =
                            if is_rec
                            then
                              FStarC_Syntax_Subst.close rec_bindings1 body1
                            else body1 in
                          let attrs =
                            match attrs_opt with
                            | FStar_Pervasives_Native.None -> []
                            | FStar_Pervasives_Native.Some l ->
                                FStarC_List.map (desugar_term env1) l in
                          let uu___8 =
                            mk_lb
                              (attrs, lbname1,
                                (setpos FStarC_Syntax_Syntax.tun), body2,
                                pos) in
                          (uu___8, aq)) in
               let uu___5 =
                 let uu___6 =
                   FStarC_List.map2
                     (desugar_one_def (if is_rec then env' else env)) fnames1
                     funs in
                 FStarC_List.unzip uu___6 in
               (match uu___5 with
                | (lbs1, aqss) ->
                    let uu___6 = desugar_term_aq env' body in
                    (match uu___6 with
                     | (body1, aq) ->
                         (if is_rec
                          then
                            FStarC_List.iter2
                              (fun uu___8 used_marker ->
                                 match uu___8 with
                                 | (_attr_opt, (f, uu___9, uu___10), uu___11)
                                     ->
                                     let uu___12 =
                                       let uu___13 =
                                         FStarC_Effect.op_Bang used_marker in
                                       Prims.op_Negation uu___13 in
                                     if uu___12
                                     then
                                       let uu___13 =
                                         match f with
                                         | FStar_Pervasives.Inl x ->
                                             let uu___14 =
                                               FStarC_Ident.string_of_id x in
                                             let uu___15 =
                                               FStarC_Ident.range_of_id x in
                                             (uu___14, "Local binding",
                                               uu___15)
                                         | FStar_Pervasives.Inr l ->
                                             let uu___14 =
                                               FStarC_Ident.string_of_lid l in
                                             let uu___15 =
                                               FStarC_Ident.range_of_lid l in
                                             (uu___14, "Global binding",
                                               uu___15) in
                                       (match uu___13 with
                                        | (nm, gl, rng) ->
                                            let uu___14 =
                                              let uu___15 =
                                                let uu___16 =
                                                  FStarC_Errors_Msg.text gl in
                                                let uu___17 =
                                                  FStarC_Errors_Msg.text
                                                    "is recursive but not used in its body" in
                                                FStar_Pprint.surround
                                                  (Prims.of_int (4))
                                                  Prims.int_one uu___16
                                                  (FStar_Pprint.squotes
                                                     (FStar_Pprint.doc_of_string
                                                        nm)) uu___17 in
                                              [uu___15] in
                                            FStarC_Errors.log_issue
                                              FStarC_Class_HasRange.hasRange_range
                                              rng
                                              FStarC_Errors_Codes.Warning_UnusedLetRec
                                              ()
                                              (Obj.magic
                                                 FStarC_Errors_Msg.is_error_message_list_doc)
                                              (Obj.magic uu___14))
                                     else ()) funs used_markers1
                          else ();
                          (let uu___8 =
                             let uu___9 =
                               let uu___10 =
                                 let uu___11 =
                                   FStarC_Syntax_Subst.close rec_bindings1
                                     body1 in
                                 {
                                   FStarC_Syntax_Syntax.lbs = (is_rec, lbs1);
                                   FStarC_Syntax_Syntax.body1 = uu___11
                                 } in
                               FStarC_Syntax_Syntax.Tm_let uu___10 in
                             mk uu___9 in
                           (uu___8,
                             (FStarC_List.op_At aq (FStarC_List.flatten aqss))))))) in
         let ds_non_rec attrs_opt pat t1 t2 =
           let attrs =
             match attrs_opt with
             | FStar_Pervasives_Native.None -> []
             | FStar_Pervasives_Native.Some l ->
                 FStarC_List.map (desugar_term env) l in
           let uu___3 = desugar_term_aq env t1 in
           match uu___3 with
           | (t11, aq0) ->
               let uu___4 = desugar_binding_pat_maybe_top top_level env pat in
               (match uu___4 with
                | ((env1, binder, pat1), aqs) ->
                    (check_no_aq aqs;
                     (let uu___6 =
                        match binder with
                        | LetBinder (l, (t, tacopt)) ->
                            (if FStar_Pervasives_Native.uu___is_Some tacopt
                             then
                               (let uu___8 = FStarC_Option.must tacopt in
                                FStarC_Errors.log_issue
                                  (FStarC_Syntax_Syntax.has_range_syntax ())
                                  uu___8
                                  FStarC_Errors_Codes.Warning_DefinitionNotTranslated
                                  ()
                                  (Obj.magic
                                     FStarC_Errors_Msg.is_error_message_string)
                                  (Obj.magic
                                     "Tactic annotation with a value type is not supported yet, try annotating with a computation type; this tactic annotation will be ignored"))
                             else ();
                             (let uu___8 = desugar_term_aq env1 t2 in
                              match uu___8 with
                              | (body1, aq) ->
                                  let fv =
                                    FStarC_Syntax_Syntax.lid_and_dd_as_fv l
                                      FStar_Pervasives_Native.None in
                                  let uu___9 =
                                    let uu___10 =
                                      let uu___11 =
                                        let uu___12 =
                                          let uu___13 =
                                            let uu___14 =
                                              mk_lb
                                                (attrs,
                                                  (FStar_Pervasives.Inr fv),
                                                  t, t11,
                                                  (t11.FStarC_Syntax_Syntax.pos)) in
                                            [uu___14] in
                                          (false, uu___13) in
                                        {
                                          FStarC_Syntax_Syntax.lbs = uu___12;
                                          FStarC_Syntax_Syntax.body1 = body1
                                        } in
                                      FStarC_Syntax_Syntax.Tm_let uu___11 in
                                    mk uu___10 in
                                  (uu___9, aq)))
                        | LocalBinder (x, uu___7, uu___8) ->
                            let uu___9 = desugar_term_aq env1 t2 in
                            (match uu___9 with
                             | (body1, aq) ->
                                 let body2 =
                                   match pat1 with
                                   | [] -> body1
                                   | uu___10 ->
                                       let uu___11 =
                                         let uu___12 =
                                           let uu___13 =
                                             FStarC_Syntax_Syntax.bv_to_name
                                               x in
                                           let uu___14 =
                                             desugar_disjunctive_pattern pat1
                                               FStar_Pervasives_Native.None
                                               body1 in
                                           {
                                             FStarC_Syntax_Syntax.scrutinee =
                                               uu___13;
                                             FStarC_Syntax_Syntax.ret_opt =
                                               FStar_Pervasives_Native.None;
                                             FStarC_Syntax_Syntax.brs =
                                               uu___14;
                                             FStarC_Syntax_Syntax.rc_opt1 =
                                               FStar_Pervasives_Native.None
                                           } in
                                         FStarC_Syntax_Syntax.Tm_match
                                           uu___12 in
                                       FStarC_Syntax_Syntax.mk uu___11
                                         top.FStarC_Parser_AST.range in
                                 let uu___10 =
                                   let uu___11 =
                                     let uu___12 =
                                       let uu___13 =
                                         let uu___14 =
                                           let uu___15 =
                                             mk_lb
                                               (attrs,
                                                 (FStar_Pervasives.Inl x),
                                                 (x.FStarC_Syntax_Syntax.sort),
                                                 t11,
                                                 (t11.FStarC_Syntax_Syntax.pos)) in
                                           [uu___15] in
                                         (false, uu___14) in
                                       let uu___14 =
                                         let uu___15 =
                                           let uu___16 =
                                             FStarC_Syntax_Syntax.mk_binder x in
                                           [uu___16] in
                                         FStarC_Syntax_Subst.close uu___15
                                           body2 in
                                       {
                                         FStarC_Syntax_Syntax.lbs = uu___13;
                                         FStarC_Syntax_Syntax.body1 = uu___14
                                       } in
                                     FStarC_Syntax_Syntax.Tm_let uu___12 in
                                   mk uu___11 in
                                 (uu___10, aq)) in
                      match uu___6 with
                      | (tm, aq1) -> (tm, (FStarC_List.op_At aq0 aq1))))) in
         let uu___3 = FStarC_List.hd lbs in
         match uu___3 with
         | (attrs, (head_pat, defn)) ->
             let attrs1 = add_extra_attrs attrs in
             let uu___4 = is_rec || (is_app_pattern head_pat) in
             if uu___4
             then ds_let_rec_or_app ()
             else ds_non_rec attrs1 head_pat defn body))
   | FStarC_Parser_AST.If
       (e, FStar_Pervasives_Native.Some op, asc_opt, t2, t3) ->
       let var_id =
         FStarC_Ident.mk_ident
           ((Prims.strcat FStarC_Ident.reserved_prefix "if_op_head"),
             (e.FStarC_Parser_AST.range)) in
       let var =
         let uu___2 =
           let uu___3 = FStarC_Ident.lid_of_ids [var_id] in
           FStarC_Parser_AST.Var uu___3 in
         FStarC_Parser_AST.mk_term uu___2 e.FStarC_Parser_AST.range
           FStarC_Parser_AST.Expr in
       let pat =
         FStarC_Parser_AST.mk_pattern
           (FStarC_Parser_AST.PatVar
              (var_id, FStar_Pervasives_Native.None, []))
           e.FStarC_Parser_AST.range in
       let if_ =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.If
              (var, FStar_Pervasives_Native.None, asc_opt, t2, t3))
           top.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
       let t =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.LetOperator ([(op, pat, e)], if_))
           e.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
       desugar_term_aq env t
   | FStarC_Parser_AST.If (t1, FStar_Pervasives_Native.None, asc_opt, t2, t3)
       ->
       let x =
         let uu___2 = tun_r t3.FStarC_Parser_AST.range in
         FStarC_Syntax_Syntax.new_bv
           (FStar_Pervasives_Native.Some (t3.FStarC_Parser_AST.range)) uu___2 in
       let t_bool =
         let uu___2 =
           let uu___3 =
             FStarC_Syntax_Syntax.lid_and_dd_as_fv
               FStarC_Parser_Const.bool_lid FStar_Pervasives_Native.None in
           FStarC_Syntax_Syntax.Tm_fvar uu___3 in
         mk uu___2 in
       let uu___2 = desugar_term_aq env t1 in
       (match uu___2 with
        | (t1', aq1) ->
            let t1'1 =
              FStarC_Syntax_Util.ascribe t1'
                ((FStar_Pervasives.Inl t_bool), FStar_Pervasives_Native.None,
                  false) in
            let uu___3 = desugar_match_returns env t1'1 asc_opt in
            (match uu___3 with
             | (asc_opt1, aq0) ->
                 let uu___4 = desugar_term_aq env t2 in
                 (match uu___4 with
                  | (t2', aq2) ->
                      let uu___5 = desugar_term_aq env t3 in
                      (match uu___5 with
                       | (t3', aq3) ->
                           let uu___6 =
                             let uu___7 =
                               let uu___8 =
                                 let uu___9 =
                                   let uu___10 =
                                     let uu___11 =
                                       FStarC_Syntax_Syntax.withinfo
                                         (FStarC_Syntax_Syntax.Pat_constant
                                            (FStarC_Const.Const_bool true))
                                         t1.FStarC_Parser_AST.range in
                                     (uu___11, FStar_Pervasives_Native.None,
                                       t2') in
                                   let uu___11 =
                                     let uu___12 =
                                       let uu___13 =
                                         FStarC_Syntax_Syntax.withinfo
                                           (FStarC_Syntax_Syntax.Pat_var x)
                                           t1.FStarC_Parser_AST.range in
                                       (uu___13,
                                         FStar_Pervasives_Native.None, t3') in
                                     [uu___12] in
                                   uu___10 :: uu___11 in
                                 {
                                   FStarC_Syntax_Syntax.scrutinee = t1'1;
                                   FStarC_Syntax_Syntax.ret_opt = asc_opt1;
                                   FStarC_Syntax_Syntax.brs = uu___9;
                                   FStarC_Syntax_Syntax.rc_opt1 =
                                     FStar_Pervasives_Native.None
                                 } in
                               FStarC_Syntax_Syntax.Tm_match uu___8 in
                             mk uu___7 in
                           (uu___6, (join_aqs [aq1; aq0; aq2; aq3]))))))
   | FStarC_Parser_AST.TryWith (e, branches) ->
       let r = top.FStarC_Parser_AST.range in
       let handler = FStarC_Parser_AST.mk_function branches r r in
       let body =
         let uu___2 =
           let uu___3 =
             let uu___4 =
               FStarC_Parser_AST.mk_pattern
                 (FStarC_Parser_AST.PatConst FStarC_Const.Const_unit) r in
             (uu___4, FStar_Pervasives_Native.None, e) in
           [uu___3] in
         FStarC_Parser_AST.mk_function uu___2 r r in
       let try_with_lid = FStarC_Ident.lid_of_path ["try_with"] r in
       let try_with =
         FStarC_Parser_AST.mk_term (FStarC_Parser_AST.Var try_with_lid) r
           FStarC_Parser_AST.Expr in
       let a1 =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.App (try_with, body, FStarC_Parser_AST.Nothing))
           r top.FStarC_Parser_AST.level in
       let a2 =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.App (a1, handler, FStarC_Parser_AST.Nothing)) r
           top.FStarC_Parser_AST.level in
       desugar_term_aq env a2
   | FStarC_Parser_AST.Match
       (e, FStar_Pervasives_Native.Some op, topt, branches) ->
       let var_id =
         FStarC_Ident.mk_ident
           ((Prims.strcat FStarC_Ident.reserved_prefix "match_op_head"),
             (e.FStarC_Parser_AST.range)) in
       let var =
         let uu___2 =
           let uu___3 = FStarC_Ident.lid_of_ids [var_id] in
           FStarC_Parser_AST.Var uu___3 in
         FStarC_Parser_AST.mk_term uu___2 e.FStarC_Parser_AST.range
           FStarC_Parser_AST.Expr in
       let pat =
         FStarC_Parser_AST.mk_pattern
           (FStarC_Parser_AST.PatVar
              (var_id, FStar_Pervasives_Native.None, []))
           e.FStarC_Parser_AST.range in
       let mt =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.Match
              (var, FStar_Pervasives_Native.None, topt, branches))
           top.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
       let t =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.LetOperator ([(op, pat, e)], mt))
           e.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
       desugar_term_aq env t
   | FStarC_Parser_AST.Match
       (e, FStar_Pervasives_Native.None, topt, branches) ->
       let desugar_branch uu___2 =
         match uu___2 with
         | (pat, wopt, b) ->
             let uu___3 = desugar_match_pat env pat in
             (match uu___3 with
              | ((env1, pat1), aqP) ->
                  let wopt1 =
                    match wopt with
                    | FStar_Pervasives_Native.None ->
                        FStar_Pervasives_Native.None
                    | FStar_Pervasives_Native.Some e1 ->
                        let uu___4 = desugar_term env1 e1 in
                        FStar_Pervasives_Native.Some uu___4 in
                  let uu___4 = desugar_term_aq env1 b in
                  (match uu___4 with
                   | (b1, aqB) ->
                       let uu___5 = desugar_disjunctive_pattern pat1 wopt1 b1 in
                       (uu___5, (FStarC_List.op_At aqP aqB)))) in
       let uu___2 = desugar_term_aq env e in
       (match uu___2 with
        | (e1, aq) ->
            let uu___3 = desugar_match_returns env e1 topt in
            (match uu___3 with
             | (asc_opt, aq0) ->
                 let uu___4 =
                   let uu___5 =
                     let uu___6 = FStarC_List.map desugar_branch branches in
                     FStarC_List.unzip uu___6 in
                   match uu___5 with | (x, y) -> ((FStarC_List.flatten x), y) in
                 (match uu___4 with
                  | (brs, aqs) ->
                      let uu___5 =
                        mk
                          (FStarC_Syntax_Syntax.Tm_match
                             {
                               FStarC_Syntax_Syntax.scrutinee = e1;
                               FStarC_Syntax_Syntax.ret_opt = asc_opt;
                               FStarC_Syntax_Syntax.brs = brs;
                               FStarC_Syntax_Syntax.rc_opt1 =
                                 FStar_Pervasives_Native.None
                             }) in
                      (uu___5, (join_aqs (aq :: aq0 :: aqs))))))
   | FStarC_Parser_AST.Ascribed (e, t, tac_opt, use_eq) ->
       let uu___2 = desugar_ascription env t tac_opt use_eq in
       (match uu___2 with
        | (asc, aq0) ->
            let uu___3 = desugar_term_aq env e in
            (match uu___3 with
             | (e1, aq) ->
                 let uu___4 =
                   mk
                     (FStarC_Syntax_Syntax.Tm_ascribed
                        {
                          FStarC_Syntax_Syntax.tm = e1;
                          FStarC_Syntax_Syntax.asc = asc;
                          FStarC_Syntax_Syntax.eff_opt =
                            FStar_Pervasives_Native.None
                        }) in
                 (uu___4, (FStarC_List.op_At aq0 aq))))
   | FStarC_Parser_AST.Record (uu___2, []) ->
       FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term top
         FStarC_Errors_Codes.Fatal_UnexpectedEmptyRecord ()
         (Obj.magic FStarC_Errors_Msg.is_error_message_string)
         (Obj.magic "Unexpected empty record")
   | FStarC_Parser_AST.Record (eopt, fields) ->
       let record_opt =
         let fns = FStarC_List.map FStar_Pervasives_Native.fst fields in
         FStarC_Syntax_DsEnv.try_lookup_record_by_field_name_many env fns in
       let uu___2 =
         let uu___3 =
           FStarC_List.map
             (fun uu___4 ->
                match uu___4 with
                | (fn, fval) ->
                    let uu___5 = desugar_term_aq env fval in
                    (match uu___5 with | (fval1, aq) -> ((fn, fval1), aq)))
             fields in
         FStarC_List.unzip uu___3 in
       (match uu___2 with
        | (fields1, aqs) ->
            let uu___3 = FStarC_List.unzip fields1 in
            (match uu___3 with
             | (field_names, assignments) ->
                 let args =
                   FStarC_List.map
                     (fun f -> (f, FStar_Pervasives_Native.None)) assignments in
                 let aqs1 = FStarC_List.flatten aqs in
                 let uc =
                   match record_opt with
                   | FStar_Pervasives_Native.None ->
                       {
                         FStarC_Syntax_Syntax.uc_base_term =
                           (FStar_Pervasives_Native.uu___is_Some eopt);
                         FStarC_Syntax_Syntax.uc_typename =
                           FStar_Pervasives_Native.None;
                         FStarC_Syntax_Syntax.uc_fields = field_names
                       }
                   | FStar_Pervasives_Native.Some record ->
                       let uu___4 =
                         qualify_field_names
                           record.FStarC_Syntax_DsEnv.typename field_names in
                       {
                         FStarC_Syntax_Syntax.uc_base_term =
                           (FStar_Pervasives_Native.uu___is_Some eopt);
                         FStarC_Syntax_Syntax.uc_typename =
                           (FStar_Pervasives_Native.Some
                              (record.FStarC_Syntax_DsEnv.typename));
                         FStarC_Syntax_Syntax.uc_fields = uu___4
                       } in
                 let head =
                   let lid =
                     FStarC_Ident.lid_of_path ["__dummy__"]
                       top.FStarC_Parser_AST.range in
                   FStarC_Syntax_Syntax.fvar_with_dd lid
                     (FStar_Pervasives_Native.Some
                        (FStarC_Syntax_Syntax.Unresolved_constructor uc)) in
                 let mk_result args1 =
                   FStarC_Syntax_Syntax.mk_Tm_app head args1
                     top.FStarC_Parser_AST.range in
                 (match eopt with
                  | FStar_Pervasives_Native.None ->
                      let uu___4 = mk_result args in (uu___4, aqs1)
                  | FStar_Pervasives_Native.Some e ->
                      let uu___4 = desugar_term_aq env e in
                      (match uu___4 with
                       | (e1, aq) ->
                           let tm =
                             let uu___5 =
                               let uu___6 = FStarC_Syntax_Subst.compress e1 in
                               uu___6.FStarC_Syntax_Syntax.n in
                             match uu___5 with
                             | FStarC_Syntax_Syntax.Tm_name uu___6 ->
                                 mk_result
                                   ((e1, FStar_Pervasives_Native.None) ::
                                   args)
                             | FStarC_Syntax_Syntax.Tm_fvar uu___6 ->
                                 mk_result
                                   ((e1, FStar_Pervasives_Native.None) ::
                                   args)
                             | uu___6 ->
                                 let x =
                                   FStarC_Ident.gen
                                     e1.FStarC_Syntax_Syntax.pos in
                                 let uu___7 =
                                   FStarC_Syntax_DsEnv.push_bv env x in
                                 (match uu___7 with
                                  | (env', bv_x) ->
                                      let nm =
                                        FStarC_Syntax_Syntax.bv_to_name bv_x in
                                      let body =
                                        mk_result
                                          ((nm, FStar_Pervasives_Native.None)
                                          :: args) in
                                      let body1 =
                                        let uu___8 =
                                          let uu___9 =
                                            FStarC_Syntax_Syntax.mk_binder
                                              bv_x in
                                          [uu___9] in
                                        FStarC_Syntax_Subst.close uu___8 body in
                                      let lb =
                                        mk_lb
                                          ([], (FStar_Pervasives.Inl bv_x),
                                            FStarC_Syntax_Syntax.tun, e1,
                                            (e1.FStarC_Syntax_Syntax.pos)) in
                                      mk
                                        (FStarC_Syntax_Syntax.Tm_let
                                           {
                                             FStarC_Syntax_Syntax.lbs =
                                               (false, [lb]);
                                             FStarC_Syntax_Syntax.body1 =
                                               body1
                                           })) in
                           (tm, (FStarC_List.op_At aq aqs1))))))
   | FStarC_Parser_AST.Project (e, f) ->
       let uu___2 = desugar_term_aq env e in
       (match uu___2 with
        | (e1, s) ->
            let head =
              let uu___3 =
                FStarC_Syntax_DsEnv.try_lookup_dc_by_field_name env f in
              match uu___3 with
              | FStar_Pervasives_Native.None ->
                  FStarC_Syntax_Syntax.fvar_with_dd f
                    (FStar_Pervasives_Native.Some
                       (FStarC_Syntax_Syntax.Unresolved_projector
                          FStar_Pervasives_Native.None))
              | FStar_Pervasives_Native.Some (constrname, is_rec) ->
                  let projname =
                    let uu___4 = FStarC_Ident.ident_of_lid f in
                    FStarC_Syntax_Util.mk_field_projector_name_from_ident
                      constrname uu___4 in
                  let qual =
                    if is_rec
                    then
                      let uu___4 =
                        let uu___5 =
                          let uu___6 = FStarC_Ident.ident_of_lid f in
                          (constrname, uu___6) in
                        FStarC_Syntax_Syntax.Record_projector uu___5 in
                      FStar_Pervasives_Native.Some uu___4
                    else FStar_Pervasives_Native.None in
                  let candidate_projector =
                    let uu___4 =
                      FStarC_Ident.set_lid_range projname
                        top.FStarC_Parser_AST.range in
                    FStarC_Syntax_Syntax.lid_and_dd_as_fv uu___4 qual in
                  let qual1 =
                    FStarC_Syntax_Syntax.Unresolved_projector
                      (FStar_Pervasives_Native.Some candidate_projector) in
                  let f1 =
                    let uu___4 = qualify_field_names constrname [f] in
                    FStarC_List.hd uu___4 in
                  FStarC_Syntax_Syntax.fvar_with_dd f1
                    (FStar_Pervasives_Native.Some qual1) in
            let uu___3 =
              let uu___4 =
                let uu___5 =
                  let uu___6 =
                    let uu___7 = FStarC_Syntax_Syntax.as_arg e1 in [uu___7] in
                  {
                    FStarC_Syntax_Syntax.hd = head;
                    FStarC_Syntax_Syntax.args = uu___6
                  } in
                FStarC_Syntax_Syntax.Tm_app uu___5 in
              mk uu___4 in
            (uu___3, s))
   | FStarC_Parser_AST.NamedTyp (n, e) ->
       (FStarC_Errors.log_issue FStarC_Ident.hasrange_ident n
          FStarC_Errors_Codes.Warning_IgnoredBinding ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_string)
          (Obj.magic "This name is being ignored");
        desugar_term_aq env e)
   | FStarC_Parser_AST.Paren e -> failwith "impossible"
   | FStarC_Parser_AST.VQuote e ->
       let uu___2 =
         let uu___3 =
           let uu___4 = desugar_vquote env e top.FStarC_Parser_AST.range in
           FStarC_Syntax_Util.exp_string uu___4 in
         {
           FStarC_Syntax_Syntax.n = (uu___3.FStarC_Syntax_Syntax.n);
           FStarC_Syntax_Syntax.pos = (e.FStarC_Parser_AST.range);
           FStarC_Syntax_Syntax.vars = (uu___3.FStarC_Syntax_Syntax.vars);
           FStarC_Syntax_Syntax.hash_code =
             (uu___3.FStarC_Syntax_Syntax.hash_code)
         } in
       (uu___2, noaqs)
   | FStarC_Parser_AST.Quote (e, FStarC_Parser_AST.Static) ->
       let uu___2 = desugar_term_aq env e in
       (match uu___2 with
        | (tm, vts) ->
            let vt_binders =
              FStarC_List.map
                (fun uu___3 ->
                   match uu___3 with
                   | (bv, _tm) -> FStarC_Syntax_Syntax.mk_binder bv) vts in
            let vt_tms = FStarC_List.map FStar_Pervasives_Native.snd vts in
            let tm1 = FStarC_Syntax_Subst.close vt_binders tm in
            ((let fvs = FStarC_Syntax_Free.names tm1 in
              let uu___4 =
                let uu___5 =
                  FStarC_Class_Setlike.is_empty ()
                    (Obj.magic
                       (FStarC_FlatSet.setlike_flat_set
                          FStarC_Syntax_Syntax.ord_bv)) (Obj.magic fvs) in
                Prims.op_Negation uu___5 in
              if uu___4
              then
                let uu___5 =
                  let uu___6 =
                    FStarC_Class_Show.show
                      (FStarC_FlatSet.showable_set
                         FStarC_Syntax_Syntax.ord_bv
                         FStarC_Syntax_Print.showable_bv) fvs in
                  FStarC_Format.fmt1
                    "Static quotation refers to external variables: %s"
                    uu___6 in
                FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term e
                  FStarC_Errors_Codes.Fatal_MissingFieldInRecord ()
                  (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                  (Obj.magic uu___5)
              else ());
             (match () with
              | () ->
                  let qi =
                    {
                      FStarC_Syntax_Syntax.qkind =
                        FStarC_Syntax_Syntax.Quote_static;
                      FStarC_Syntax_Syntax.antiquotations =
                        (Prims.int_zero, vt_tms)
                    } in
                  let uu___4 = mk (FStarC_Syntax_Syntax.Tm_quoted (tm1, qi)) in
                  (uu___4, noaqs))))
   | FStarC_Parser_AST.Antiquote e ->
       let bv =
         FStarC_Syntax_Syntax.new_bv
           (FStar_Pervasives_Native.Some (e.FStarC_Parser_AST.range))
           FStarC_Syntax_Syntax.tun in
       let tm = desugar_term env e in
       let uu___2 = FStarC_Syntax_Syntax.bv_to_name bv in
       (uu___2, [(bv, tm)])
   | FStarC_Parser_AST.Quote (e, FStarC_Parser_AST.Dynamic) ->
       let qi =
         {
           FStarC_Syntax_Syntax.qkind = FStarC_Syntax_Syntax.Quote_dynamic;
           FStarC_Syntax_Syntax.antiquotations = (Prims.int_zero, [])
         } in
       let uu___2 =
         let uu___3 =
           let uu___4 = let uu___5 = desugar_term env e in (uu___5, qi) in
           FStarC_Syntax_Syntax.Tm_quoted uu___4 in
         mk uu___3 in
       (uu___2, noaqs)
   | FStarC_Parser_AST.CalcProof (rel, init_expr, steps) ->
       let is_impl rel1 =
         let is_impl_t t =
           match t.FStarC_Syntax_Syntax.n with
           | FStarC_Syntax_Syntax.Tm_fvar fv ->
               FStarC_Syntax_Syntax.fv_eq_lid fv FStarC_Parser_Const.imp_lid
           | uu___2 -> false in
         let uu___2 =
           let uu___3 = unparen rel1 in uu___3.FStarC_Parser_AST.tm in
         match uu___2 with
         | FStarC_Parser_AST.Op (id, uu___3) ->
             let uu___4 = op_as_term env (Prims.of_int (2)) id in
             (match uu___4 with
              | FStar_Pervasives_Native.Some t -> is_impl_t t
              | FStar_Pervasives_Native.None -> false)
         | FStarC_Parser_AST.Var lid ->
             let uu___3 = desugar_name' (fun x -> x) env true lid in
             (match uu___3 with
              | FStar_Pervasives_Native.Some t -> is_impl_t t
              | FStar_Pervasives_Native.None -> false)
         | uu___3 -> false in
       let eta_and_annot rel1 =
         let x = FStarC_Ident.gen' "x" rel1.FStarC_Parser_AST.range in
         let y = FStarC_Ident.gen' "y" rel1.FStarC_Parser_AST.range in
         let xt =
           let uu___2 =
             let uu___3 = FStarC_Ident.id_as_lid x in
             FStarC_Parser_AST.Var uu___3 in
           FStarC_Parser_AST.mk_term uu___2 rel1.FStarC_Parser_AST.range
             FStarC_Parser_AST.Expr in
         let yt =
           let uu___2 =
             let uu___3 = FStarC_Ident.id_as_lid y in
             FStarC_Parser_AST.Var uu___3 in
           FStarC_Parser_AST.mk_term uu___2 rel1.FStarC_Parser_AST.range
             FStarC_Parser_AST.Expr in
         let pats =
           let uu___2 =
             FStarC_Parser_AST.mk_pattern
               (FStarC_Parser_AST.PatVar
                  (x, FStar_Pervasives_Native.None, []))
               rel1.FStarC_Parser_AST.range in
           let uu___3 =
             let uu___4 =
               FStarC_Parser_AST.mk_pattern
                 (FStarC_Parser_AST.PatVar
                    (y, FStar_Pervasives_Native.None, []))
                 rel1.FStarC_Parser_AST.range in
             [uu___4] in
           uu___2 :: uu___3 in
         let uu___2 =
           let uu___3 =
             let uu___4 =
               let uu___5 =
                 let uu___6 =
                   let uu___7 =
                     FStarC_Parser_AST.mkApp rel1
                       [(xt, FStarC_Parser_AST.Nothing);
                       (yt, FStarC_Parser_AST.Nothing)]
                       rel1.FStarC_Parser_AST.range in
                   let uu___8 =
                     let uu___9 =
                       let uu___10 = FStarC_Ident.lid_of_str "Type0" in
                       FStarC_Parser_AST.Name uu___10 in
                     FStarC_Parser_AST.mk_term uu___9
                       rel1.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
                   (uu___7, uu___8, FStar_Pervasives_Native.None, false) in
                 FStarC_Parser_AST.Ascribed uu___6 in
               FStarC_Parser_AST.mk_term uu___5 rel1.FStarC_Parser_AST.range
                 FStarC_Parser_AST.Expr in
             (pats, uu___4) in
           FStarC_Parser_AST.Abs uu___3 in
         FStarC_Parser_AST.mk_term uu___2 rel1.FStarC_Parser_AST.range
           FStarC_Parser_AST.Expr in
       let rel1 = eta_and_annot rel in
       let wild r =
         FStarC_Parser_AST.mk_term FStarC_Parser_AST.Wild r
           FStarC_Parser_AST.Expr in
       let init =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.Var FStarC_Parser_Const.calc_init_lid)
           init_expr.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
       let push_impl r =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.Var FStarC_Parser_Const.calc_push_impl_lid) r
           FStarC_Parser_AST.Expr in
       let last_expr =
         let uu___2 = FStarC_List.last_opt steps in
         match uu___2 with
         | FStar_Pervasives_Native.Some (FStarC_Parser_AST.CalcStep
             (uu___3, uu___4, last_expr1)) -> last_expr1
         | FStar_Pervasives_Native.None -> init_expr in
       let step r =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.Var FStarC_Parser_Const.calc_step_lid) r
           FStarC_Parser_AST.Expr in
       let finish =
         let uu___2 =
           FStarC_Parser_AST.mk_term
             (FStarC_Parser_AST.Var FStarC_Parser_Const.calc_finish_lid)
             top.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
         FStarC_Parser_AST.mkApp uu___2 [(rel1, FStarC_Parser_AST.Nothing)]
           top.FStarC_Parser_AST.range in
       let e =
         FStarC_Parser_AST.mkApp init
           [(init_expr, FStarC_Parser_AST.Nothing)]
           init_expr.FStarC_Parser_AST.range in
       let uu___2 =
         FStarC_List.fold_left
           (fun uu___3 uu___4 ->
              match (uu___3, uu___4) with
              | ((e1, prev), FStarC_Parser_AST.CalcStep
                 (rel2, just, next_expr)) ->
                  let just1 =
                    let uu___5 = is_impl rel2 in
                    if uu___5
                    then
                      let uu___6 = push_impl just.FStarC_Parser_AST.range in
                      let uu___7 =
                        let uu___8 =
                          let uu___9 = FStarC_Parser_AST.thunk just in
                          (uu___9, FStarC_Parser_AST.Nothing) in
                        [uu___8] in
                      FStarC_Parser_AST.mkApp uu___6 uu___7
                        just.FStarC_Parser_AST.range
                    else just in
                  let pf =
                    let uu___5 = step rel2.FStarC_Parser_AST.range in
                    let uu___6 =
                      let uu___7 =
                        let uu___8 = wild rel2.FStarC_Parser_AST.range in
                        (uu___8, FStarC_Parser_AST.Hash) in
                      let uu___8 =
                        let uu___9 =
                          let uu___10 =
                            let uu___11 =
                              let uu___12 = eta_and_annot rel2 in
                              (uu___12, FStarC_Parser_AST.Nothing) in
                            let uu___12 =
                              let uu___13 =
                                let uu___14 =
                                  let uu___15 = FStarC_Parser_AST.thunk e1 in
                                  (uu___15, FStarC_Parser_AST.Nothing) in
                                let uu___15 =
                                  let uu___16 =
                                    let uu___17 =
                                      FStarC_Parser_AST.thunk just1 in
                                    (uu___17, FStarC_Parser_AST.Nothing) in
                                  [uu___16] in
                                uu___14 :: uu___15 in
                              (next_expr, FStarC_Parser_AST.Nothing) ::
                                uu___13 in
                            uu___11 :: uu___12 in
                          (prev, FStarC_Parser_AST.Hash) :: uu___10 in
                        (init_expr, FStarC_Parser_AST.Hash) :: uu___9 in
                      uu___7 :: uu___8 in
                    FStarC_Parser_AST.mkApp uu___5 uu___6
                      FStarC_Range_Type.dummyRange in
                  (pf, next_expr)) (e, init_expr) steps in
       (match uu___2 with
        | (e1, uu___3) ->
            let e2 =
              let uu___4 =
                let uu___5 =
                  let uu___6 =
                    let uu___7 =
                      let uu___8 = FStarC_Parser_AST.thunk e1 in
                      (uu___8, FStarC_Parser_AST.Nothing) in
                    [uu___7] in
                  (last_expr, FStarC_Parser_AST.Hash) :: uu___6 in
                (init_expr, FStarC_Parser_AST.Hash) :: uu___5 in
              FStarC_Parser_AST.mkApp finish uu___4
                top.FStarC_Parser_AST.range in
            desugar_term_maybe_top top_level env e2)
   | FStarC_Parser_AST.IntroForall (bs, p, e) ->
       let uu___2 = desugar_binders env bs in
       (match uu___2 with
        | (env', bs1) ->
            let p1 = desugar_term env' p in
            let e1 = desugar_term env' e in
            let mk_forall_intro t p2 pf =
              let head =
                let uu___3 =
                  FStarC_Syntax_Syntax.lid_and_dd_as_fv
                    FStarC_Parser_Const.forall_intro_lid
                    FStar_Pervasives_Native.None in
                FStarC_Syntax_Syntax.fv_to_tm uu___3 in
              let args =
                [(t, FStar_Pervasives_Native.None);
                (p2, FStar_Pervasives_Native.None);
                (pf, FStar_Pervasives_Native.None)] in
              FStarC_Syntax_Syntax.mk_Tm_app head args
                top.FStarC_Parser_AST.range in
            let rec aux bs2 =
              match bs2 with
              | [] ->
                  let sq_p =
                    FStarC_Syntax_Util.mk_squash
                      FStarC_Syntax_Syntax.U_unknown p1 in
                  FStarC_Syntax_Util.ascribe e1
                    ((FStar_Pervasives.Inl sq_p),
                      FStar_Pervasives_Native.None, false)
              | b::bs3 ->
                  let tail = aux bs3 in
                  let x = unqual_bv_of_binder b in
                  let uu___3 =
                    let uu___4 =
                      FStarC_Syntax_Util.close_forall_no_univs bs3 p1 in
                    FStarC_Syntax_Util.abs [b] uu___4
                      FStar_Pervasives_Native.None in
                  let uu___4 =
                    FStarC_Syntax_Util.abs [b] tail
                      FStar_Pervasives_Native.None in
                  mk_forall_intro x.FStarC_Syntax_Syntax.sort uu___3 uu___4 in
            let uu___3 = aux bs1 in (uu___3, noaqs))
   | FStarC_Parser_AST.IntroExists (bs, p, vs, e) ->
       let uu___2 = desugar_binders env bs in
       (match uu___2 with
        | (env', bs1) ->
            let p1 = desugar_term env' p in
            let vs1 = FStarC_List.map (desugar_term env) vs in
            let e1 = desugar_term env e in
            let mk_exists_intro t p2 v e2 =
              let head =
                let uu___3 =
                  FStarC_Syntax_Syntax.lid_and_dd_as_fv
                    FStarC_Parser_Const.exists_intro_lid
                    FStar_Pervasives_Native.None in
                FStarC_Syntax_Syntax.fv_to_tm uu___3 in
              let args =
                let uu___3 =
                  let uu___4 =
                    let uu___5 =
                      let uu___6 =
                        let uu___7 = mk_thunk e2 in
                        (uu___7, FStar_Pervasives_Native.None) in
                      [uu___6] in
                    (v, FStar_Pervasives_Native.None) :: uu___5 in
                  (p2, FStar_Pervasives_Native.None) :: uu___4 in
                (t, FStar_Pervasives_Native.None) :: uu___3 in
              FStarC_Syntax_Syntax.mk_Tm_app head args
                top.FStarC_Parser_AST.range in
            let rec aux bs2 vs2 sub token =
              match (bs2, vs2) with
              | ([], []) -> token
              | (b::bs3, v::vs3) ->
                  let x = unqual_bv_of_binder b in
                  let token1 =
                    let uu___3 =
                      FStarC_Syntax_Subst.subst_binders
                        ((FStarC_Syntax_Syntax.NT (x, v)) :: sub) bs3 in
                    aux uu___3 vs3 ((FStarC_Syntax_Syntax.NT (x, v)) :: sub)
                      token in
                  let token2 =
                    let uu___3 =
                      let uu___4 =
                        let uu___5 = FStarC_Syntax_Subst.subst sub p1 in
                        FStarC_Syntax_Util.close_exists_no_univs bs3 uu___5 in
                      FStarC_Syntax_Util.abs [b] uu___4
                        FStar_Pervasives_Native.None in
                    mk_exists_intro x.FStarC_Syntax_Syntax.sort uu___3 v
                      token1 in
                  token2
              | uu___3 ->
                  FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term
                    top FStarC_Errors_Codes.Fatal_UnexpectedTerm ()
                    (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                    (Obj.magic
                       "Unexpected number of instantiations in _intro_ exists") in
            let uu___3 = aux bs1 vs1 [] e1 in (uu___3, noaqs))
   | FStarC_Parser_AST.IntroImplies (p, q, x, e) ->
       let p1 = desugar_term env p in
       let q1 = desugar_term env q in
       let uu___2 = desugar_binders env [x] in
       (match uu___2 with
        | (env', x1::[]) ->
            let e1 = desugar_term env' e in
            let head =
              let uu___3 =
                FStarC_Syntax_Syntax.lid_and_dd_as_fv
                  FStarC_Parser_Const.implies_intro_lid
                  FStar_Pervasives_Native.None in
              FStarC_Syntax_Syntax.fv_to_tm uu___3 in
            let args =
              let uu___3 =
                let uu___4 =
                  let uu___5 = mk_thunk q1 in
                  (uu___5, FStar_Pervasives_Native.None) in
                let uu___5 =
                  let uu___6 =
                    let uu___7 =
                      FStarC_Syntax_Util.abs [x1] e1
                        FStar_Pervasives_Native.None in
                    (uu___7, FStar_Pervasives_Native.None) in
                  [uu___6] in
                uu___4 :: uu___5 in
              (p1, FStar_Pervasives_Native.None) :: uu___3 in
            let uu___3 =
              FStarC_Syntax_Syntax.mk_Tm_app head args
                top.FStarC_Parser_AST.range in
            (uu___3, noaqs))
   | FStarC_Parser_AST.IntroOr (lr, p, q, e) ->
       let p1 = desugar_term env p in
       let q1 = desugar_term env q in
       let e1 = desugar_term env e in
       let lid =
         if lr
         then FStarC_Parser_Const.or_intro_left_lid
         else FStarC_Parser_Const.or_intro_right_lid in
       let head =
         let uu___2 =
           FStarC_Syntax_Syntax.lid_and_dd_as_fv lid
             FStar_Pervasives_Native.None in
         FStarC_Syntax_Syntax.fv_to_tm uu___2 in
       let args =
         let uu___2 =
           let uu___3 =
             let uu___4 = mk_thunk q1 in
             (uu___4, FStar_Pervasives_Native.None) in
           let uu___4 =
             let uu___5 =
               let uu___6 = mk_thunk e1 in
               (uu___6, FStar_Pervasives_Native.None) in
             [uu___5] in
           uu___3 :: uu___4 in
         (p1, FStar_Pervasives_Native.None) :: uu___2 in
       let uu___2 =
         FStarC_Syntax_Syntax.mk_Tm_app head args top.FStarC_Parser_AST.range in
       (uu___2, noaqs)
   | FStarC_Parser_AST.IntroAnd (p, q, e1, e2) ->
       let p1 = desugar_term env p in
       let q1 = desugar_term env q in
       let e11 = desugar_term env e1 in
       let e21 = desugar_term env e2 in
       let head =
         let uu___2 =
           FStarC_Syntax_Syntax.lid_and_dd_as_fv
             FStarC_Parser_Const.and_intro_lid FStar_Pervasives_Native.None in
         FStarC_Syntax_Syntax.fv_to_tm uu___2 in
       let args =
         let uu___2 =
           let uu___3 =
             let uu___4 = mk_thunk q1 in
             (uu___4, FStar_Pervasives_Native.None) in
           let uu___4 =
             let uu___5 =
               let uu___6 = mk_thunk e11 in
               (uu___6, FStar_Pervasives_Native.None) in
             let uu___6 =
               let uu___7 =
                 let uu___8 = mk_thunk e21 in
                 (uu___8, FStar_Pervasives_Native.None) in
               [uu___7] in
             uu___5 :: uu___6 in
           uu___3 :: uu___4 in
         (p1, FStar_Pervasives_Native.None) :: uu___2 in
       let uu___2 =
         FStarC_Syntax_Syntax.mk_Tm_app head args top.FStarC_Parser_AST.range in
       (uu___2, noaqs)
   | FStarC_Parser_AST.ElimForall (bs, p, vs) ->
       let uu___2 = desugar_binders env bs in
       (match uu___2 with
        | (env', bs1) ->
            let p1 = desugar_term env' p in
            let vs1 = FStarC_List.map (desugar_term env) vs in
            let mk_forall_elim a p2 v tok =
              let head =
                let uu___3 =
                  FStarC_Syntax_Syntax.lid_and_dd_as_fv
                    FStarC_Parser_Const.forall_elim_lid
                    FStar_Pervasives_Native.None in
                FStarC_Syntax_Syntax.fv_to_tm uu___3 in
              let args =
                let uu___3 =
                  let uu___4 = FStarC_Syntax_Syntax.as_aqual_implicit true in
                  (a, uu___4) in
                let uu___4 =
                  let uu___5 =
                    let uu___6 = FStarC_Syntax_Syntax.as_aqual_implicit true in
                    (p2, uu___6) in
                  [uu___5;
                  (v, FStar_Pervasives_Native.None);
                  (tok, FStar_Pervasives_Native.None)] in
                uu___3 :: uu___4 in
              FStarC_Syntax_Syntax.mk_Tm_app head args
                tok.FStarC_Syntax_Syntax.pos in
            let rec aux bs2 vs2 sub token =
              match (bs2, vs2) with
              | ([], []) -> token
              | (b::bs3, v::vs3) ->
                  let x = unqual_bv_of_binder b in
                  let token1 =
                    let uu___3 =
                      let uu___4 =
                        let uu___5 = FStarC_Syntax_Subst.subst sub p1 in
                        FStarC_Syntax_Util.close_forall_no_univs bs3 uu___5 in
                      FStarC_Syntax_Util.abs [b] uu___4
                        FStar_Pervasives_Native.None in
                    mk_forall_elim x.FStarC_Syntax_Syntax.sort uu___3 v token in
                  let sub1 = (FStarC_Syntax_Syntax.NT (x, v)) :: sub in
                  let uu___3 = FStarC_Syntax_Subst.subst_binders sub1 bs3 in
                  aux uu___3 vs3 sub1 token1
              | uu___3 ->
                  FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term
                    top FStarC_Errors_Codes.Fatal_UnexpectedTerm ()
                    (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                    (Obj.magic
                       "Unexpected number of instantiations in _elim_forall_") in
            let range =
              FStarC_List.fold_right
                (fun bs2 r ->
                   let uu___3 =
                     FStarC_Syntax_Syntax.range_of_bv
                       bs2.FStarC_Syntax_Syntax.binder_bv in
                   FStarC_Range_Ops.union_ranges uu___3 r) bs1
                p1.FStarC_Syntax_Syntax.pos in
            let uu___3 =
              aux bs1 vs1 []
                {
                  FStarC_Syntax_Syntax.n =
                    (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.n);
                  FStarC_Syntax_Syntax.pos = range;
                  FStarC_Syntax_Syntax.vars =
                    (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.vars);
                  FStarC_Syntax_Syntax.hash_code =
                    (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.hash_code)
                } in
            (uu___3, noaqs))
   | FStarC_Parser_AST.ElimExists (binders, p, q, binder, e) ->
       let uu___2 = desugar_binders env binders in
       (match uu___2 with
        | (env', bs) ->
            let p1 = desugar_term env' p in
            let q1 = desugar_term env q in
            let sq_q =
              FStarC_Syntax_Util.mk_squash FStarC_Syntax_Syntax.U_unknown q1 in
            let uu___3 = desugar_binders env' [binder] in
            (match uu___3 with
             | (env'', b_pf_p::[]) ->
                 let e1 = desugar_term env'' e in
                 let rec mk_exists bs1 p2 =
                   match bs1 with
                   | [] -> failwith "Impossible"
                   | b::[] ->
                       let x = b.FStarC_Syntax_Syntax.binder_bv in
                       let head =
                         let uu___4 =
                           FStarC_Syntax_Syntax.lid_and_dd_as_fv
                             FStarC_Parser_Const.exists_lid
                             FStar_Pervasives_Native.None in
                         FStarC_Syntax_Syntax.fv_to_tm uu___4 in
                       let args =
                         let uu___4 =
                           let uu___5 =
                             FStarC_Syntax_Syntax.as_aqual_implicit true in
                           ((x.FStarC_Syntax_Syntax.sort), uu___5) in
                         let uu___5 =
                           let uu___6 =
                             let uu___7 =
                               let uu___8 =
                                 let uu___9 = FStarC_List.hd bs1 in [uu___9] in
                               FStarC_Syntax_Util.abs uu___8 p2
                                 FStar_Pervasives_Native.None in
                             (uu___7, FStar_Pervasives_Native.None) in
                           [uu___6] in
                         uu___4 :: uu___5 in
                       FStarC_Syntax_Syntax.mk_Tm_app head args
                         p2.FStarC_Syntax_Syntax.pos
                   | b::bs2 ->
                       let body = mk_exists bs2 p2 in mk_exists [b] body in
                 let mk_exists_elim t x_p s_ex_p f r =
                   let head =
                     let uu___4 =
                       FStarC_Syntax_Syntax.lid_and_dd_as_fv
                         FStarC_Parser_Const.exists_elim_lid
                         FStar_Pervasives_Native.None in
                     FStarC_Syntax_Syntax.fv_to_tm uu___4 in
                   let args =
                     let uu___4 =
                       let uu___5 =
                         FStarC_Syntax_Syntax.as_aqual_implicit true in
                       (t, uu___5) in
                     let uu___5 =
                       let uu___6 =
                         let uu___7 =
                           FStarC_Syntax_Syntax.as_aqual_implicit true in
                         (x_p, uu___7) in
                       [uu___6;
                       (s_ex_p, FStar_Pervasives_Native.None);
                       (f, FStar_Pervasives_Native.None)] in
                     uu___4 :: uu___5 in
                   FStarC_Syntax_Syntax.mk_Tm_app head args r in
                 let rec aux binders1 squash_token =
                   match binders1 with
                   | [] ->
                       FStarC_Errors.raise_error
                         FStarC_Parser_AST.hasRange_term top
                         FStarC_Errors_Codes.Fatal_UnexpectedTerm ()
                         (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                         (Obj.magic "Empty binders in ELIM_EXISTS")
                   | b::[] ->
                       let x = unqual_bv_of_binder b in
                       let uu___4 =
                         FStarC_Syntax_Util.abs [b] p1
                           FStar_Pervasives_Native.None in
                       let uu___5 =
                         let uu___6 =
                           FStarC_Syntax_Util.ascribe e1
                             ((FStar_Pervasives.Inl sq_q),
                               FStar_Pervasives_Native.None, false) in
                         FStarC_Syntax_Util.abs [b; b_pf_p] uu___6
                           FStar_Pervasives_Native.None in
                       mk_exists_elim x.FStarC_Syntax_Syntax.sort uu___4
                         squash_token uu___5
                         squash_token.FStarC_Syntax_Syntax.pos
                   | b::bs1 ->
                       let pf_i =
                         let uu___4 =
                           let uu___5 =
                             FStarC_Syntax_Syntax.range_of_bv
                               b.FStarC_Syntax_Syntax.binder_bv in
                           FStar_Pervasives_Native.Some uu___5 in
                         FStarC_Syntax_Syntax.gen_bv "pf" uu___4
                           FStarC_Syntax_Syntax.tun in
                       let k =
                         let uu___4 = FStarC_Syntax_Syntax.bv_to_name pf_i in
                         aux bs1 uu___4 in
                       let x = unqual_bv_of_binder b in
                       let uu___4 =
                         let uu___5 = mk_exists bs1 p1 in
                         FStarC_Syntax_Util.abs [b] uu___5
                           FStar_Pervasives_Native.None in
                       let uu___5 =
                         let uu___6 =
                           let uu___7 =
                             let uu___8 = FStarC_Syntax_Syntax.mk_binder pf_i in
                             [uu___8] in
                           b :: uu___7 in
                         FStarC_Syntax_Util.abs uu___6 k
                           FStar_Pervasives_Native.None in
                       mk_exists_elim x.FStarC_Syntax_Syntax.sort uu___4
                         squash_token uu___5
                         squash_token.FStarC_Syntax_Syntax.pos in
                 let range =
                   FStarC_List.fold_right
                     (fun bs1 r ->
                        let uu___4 =
                          FStarC_Syntax_Syntax.range_of_bv
                            bs1.FStarC_Syntax_Syntax.binder_bv in
                        FStarC_Range_Ops.union_ranges uu___4 r) bs
                     p1.FStarC_Syntax_Syntax.pos in
                 let uu___4 =
                   aux bs
                     {
                       FStarC_Syntax_Syntax.n =
                         (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.n);
                       FStarC_Syntax_Syntax.pos = range;
                       FStarC_Syntax_Syntax.vars =
                         (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.vars);
                       FStarC_Syntax_Syntax.hash_code =
                         (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.hash_code)
                     } in
                 (uu___4, noaqs)))
   | FStarC_Parser_AST.ElimImplies (p, q, e) ->
       let p1 = desugar_term env p in
       let q1 = desugar_term env q in
       let e1 = desugar_term env e in
       let head =
         let uu___2 =
           FStarC_Syntax_Syntax.lid_and_dd_as_fv
             FStarC_Parser_Const.implies_elim_lid
             FStar_Pervasives_Native.None in
         FStarC_Syntax_Syntax.fv_to_tm uu___2 in
       let args =
         let uu___2 =
           let uu___3 =
             let uu___4 =
               let uu___5 =
                 let uu___6 =
                   FStarC_Range_Ops.union_ranges p1.FStarC_Syntax_Syntax.pos
                     q1.FStarC_Syntax_Syntax.pos in
                 {
                   FStarC_Syntax_Syntax.n =
                     (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.n);
                   FStarC_Syntax_Syntax.pos = uu___6;
                   FStarC_Syntax_Syntax.vars =
                     (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.vars);
                   FStarC_Syntax_Syntax.hash_code =
                     (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.hash_code)
                 } in
               (uu___5, FStar_Pervasives_Native.None) in
             let uu___5 =
               let uu___6 =
                 let uu___7 = mk_thunk e1 in
                 (uu___7, FStar_Pervasives_Native.None) in
               [uu___6] in
             uu___4 :: uu___5 in
           (q1, FStar_Pervasives_Native.None) :: uu___3 in
         (p1, FStar_Pervasives_Native.None) :: uu___2 in
       let uu___2 =
         FStarC_Syntax_Syntax.mk_Tm_app head args top.FStarC_Parser_AST.range in
       (uu___2, noaqs)
   | FStarC_Parser_AST.ElimOr (p, q, r, x, e1, y, e2) ->
       let p1 = desugar_term env p in
       let q1 = desugar_term env q in
       let r1 = desugar_term env r in
       let uu___2 = desugar_binders env [x] in
       (match uu___2 with
        | (env_x, x1::[]) ->
            let e11 = desugar_term env_x e1 in
            let uu___3 = desugar_binders env [y] in
            (match uu___3 with
             | (env_y, y1::[]) ->
                 let e21 = desugar_term env_y e2 in
                 let head =
                   let uu___4 =
                     FStarC_Syntax_Syntax.lid_and_dd_as_fv
                       FStarC_Parser_Const.or_elim_lid
                       FStar_Pervasives_Native.None in
                   FStarC_Syntax_Syntax.fv_to_tm uu___4 in
                 let extra_binder =
                   let uu___4 =
                     FStarC_Syntax_Syntax.new_bv FStar_Pervasives_Native.None
                       FStarC_Syntax_Syntax.tun in
                   FStarC_Syntax_Syntax.mk_binder uu___4 in
                 let args =
                   let uu___4 =
                     let uu___5 =
                       let uu___6 = mk_thunk q1 in
                       (uu___6, FStar_Pervasives_Native.None) in
                     let uu___6 =
                       let uu___7 =
                         let uu___8 =
                           let uu___9 =
                             let uu___10 =
                               FStarC_Range_Ops.union_ranges
                                 p1.FStarC_Syntax_Syntax.pos
                                 q1.FStarC_Syntax_Syntax.pos in
                             {
                               FStarC_Syntax_Syntax.n =
                                 (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.n);
                               FStarC_Syntax_Syntax.pos = uu___10;
                               FStarC_Syntax_Syntax.vars =
                                 (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.vars);
                               FStarC_Syntax_Syntax.hash_code =
                                 (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.hash_code)
                             } in
                           (uu___9, FStar_Pervasives_Native.None) in
                         let uu___9 =
                           let uu___10 =
                             let uu___11 =
                               FStarC_Syntax_Util.abs [x1] e11
                                 FStar_Pervasives_Native.None in
                             (uu___11, FStar_Pervasives_Native.None) in
                           let uu___11 =
                             let uu___12 =
                               let uu___13 =
                                 FStarC_Syntax_Util.abs [extra_binder; y1]
                                   e21 FStar_Pervasives_Native.None in
                               (uu___13, FStar_Pervasives_Native.None) in
                             [uu___12] in
                           uu___10 :: uu___11 in
                         uu___8 :: uu___9 in
                       (r1, FStar_Pervasives_Native.None) :: uu___7 in
                     uu___5 :: uu___6 in
                   (p1, FStar_Pervasives_Native.None) :: uu___4 in
                 let uu___4 =
                   FStarC_Syntax_Syntax.mk_Tm_app head args
                     top.FStarC_Parser_AST.range in
                 (uu___4, noaqs)))
   | FStarC_Parser_AST.ElimAnd (p, q, r, x, y, e) ->
       let p1 = desugar_term env p in
       let q1 = desugar_term env q in
       let r1 = desugar_term env r in
       let uu___2 = desugar_binders env [x; y] in
       (match uu___2 with
        | (env', x1::y1::[]) ->
            let e1 = desugar_term env' e in
            let head =
              let uu___3 =
                FStarC_Syntax_Syntax.lid_and_dd_as_fv
                  FStarC_Parser_Const.and_elim_lid
                  FStar_Pervasives_Native.None in
              FStarC_Syntax_Syntax.fv_to_tm uu___3 in
            let args =
              let uu___3 =
                let uu___4 =
                  let uu___5 = mk_thunk q1 in
                  (uu___5, FStar_Pervasives_Native.None) in
                let uu___5 =
                  let uu___6 =
                    let uu___7 =
                      let uu___8 =
                        let uu___9 =
                          FStarC_Range_Ops.union_ranges
                            p1.FStarC_Syntax_Syntax.pos
                            q1.FStarC_Syntax_Syntax.pos in
                        {
                          FStarC_Syntax_Syntax.n =
                            (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.n);
                          FStarC_Syntax_Syntax.pos = uu___9;
                          FStarC_Syntax_Syntax.vars =
                            (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.vars);
                          FStarC_Syntax_Syntax.hash_code =
                            (FStarC_Syntax_Util.exp_unit.FStarC_Syntax_Syntax.hash_code)
                        } in
                      (uu___8, FStar_Pervasives_Native.None) in
                    let uu___8 =
                      let uu___9 =
                        let uu___10 =
                          FStarC_Syntax_Util.abs [x1; y1] e1
                            FStar_Pervasives_Native.None in
                        (uu___10, FStar_Pervasives_Native.None) in
                      [uu___9] in
                    uu___7 :: uu___8 in
                  (r1, FStar_Pervasives_Native.None) :: uu___6 in
                uu___4 :: uu___5 in
              (p1, FStar_Pervasives_Native.None) :: uu___3 in
            let uu___3 =
              FStarC_Syntax_Syntax.mk_Tm_app head args
                top.FStarC_Parser_AST.range in
            (uu___3, noaqs))
   | FStarC_Parser_AST.ListLiteral ts ->
       let nil r =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.Construct (FStarC_Parser_Const.nil_lid, [])) r
           FStarC_Parser_AST.Expr in
       let cons r hd tl =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.Construct
              (FStarC_Parser_Const.cons_lid,
                [(hd, FStarC_Parser_AST.Nothing);
                (tl, FStarC_Parser_AST.Nothing)])) r FStarC_Parser_AST.Expr in
       let t' =
         let uu___2 = nil top.FStarC_Parser_AST.range in
         FStarC_List.fold_right (cons top.FStarC_Parser_AST.range) ts uu___2 in
       desugar_term_aq env t'
   | FStarC_Parser_AST.SeqLiteral ts ->
       let nil r =
         FStarC_Parser_AST.mk_term
           (FStarC_Parser_AST.Var FStarC_Parser_Const.seq_empty_lid) r
           FStarC_Parser_AST.Expr in
       let cons r hd tl =
         let uu___2 =
           FStarC_Parser_AST.mk_term
             (FStarC_Parser_AST.Var FStarC_Parser_Const.seq_cons_lid) r
             FStarC_Parser_AST.Expr in
         FStarC_Parser_AST.mkApp uu___2
           [(hd, FStarC_Parser_AST.Nothing); (tl, FStarC_Parser_AST.Nothing)]
           r in
       let t' =
         let uu___2 = nil top.FStarC_Parser_AST.range in
         FStarC_List.fold_right (cons top.FStarC_Parser_AST.range) ts uu___2 in
       desugar_term_aq env t'
   | uu___2 when top.FStarC_Parser_AST.level = FStarC_Parser_AST.Formula ->
       let uu___3 = desugar_formula env top in (uu___3, noaqs)
   | uu___2 ->
       let uu___3 =
         let uu___4 = FStarC_Parser_AST.term_to_string top in
         Prims.strcat "Unexpected term: " uu___4 in
       FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term top
         FStarC_Errors_Codes.Fatal_UnexpectedTerm ()
         (Obj.magic FStarC_Errors_Msg.is_error_message_string)
         (Obj.magic uu___3))
and desugar_match_returns (env : env_t)
  (scrutinee : FStarC_Syntax_Syntax.term)
  (asc_opt :
    (FStarC_Ident.ident FStar_Pervasives_Native.option *
      FStarC_Parser_AST.term * Prims.bool) FStar_Pervasives_Native.option)
  :
  ((FStarC_Syntax_Syntax.binder *
    ((FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax,
    FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
    FStar_Pervasives.either * FStarC_Syntax_Syntax.term'
    FStarC_Syntax_Syntax.syntax FStar_Pervasives_Native.option * Prims.bool))
    FStar_Pervasives_Native.option * (FStarC_Syntax_Syntax.bv *
    FStarC_Syntax_Syntax.term) Prims.list)=
  match asc_opt with
  | FStar_Pervasives_Native.None -> (FStar_Pervasives_Native.None, [])
  | FStar_Pervasives_Native.Some asc ->
      let uu___ = asc in
      (match uu___ with
       | (asc_b, asc_tc, asc_use_eq) ->
           let uu___1 =
             match asc_b with
             | FStar_Pervasives_Native.None ->
                 let bv =
                   FStarC_Syntax_Syntax.gen_bv
                     FStarC_Parser_Const.match_returns_def_name
                     (FStar_Pervasives_Native.Some
                        (scrutinee.FStarC_Syntax_Syntax.pos))
                     FStarC_Syntax_Syntax.tun in
                 let uu___2 = FStarC_Syntax_Syntax.mk_binder bv in
                 (env, uu___2)
             | FStar_Pervasives_Native.Some b ->
                 let uu___2 = FStarC_Syntax_DsEnv.push_bv env b in
                 (match uu___2 with
                  | (env1, bv) ->
                      let uu___3 = FStarC_Syntax_Syntax.mk_binder bv in
                      (env1, uu___3)) in
           (match uu___1 with
            | (env_asc, b) ->
                let uu___2 =
                  desugar_ascription env_asc asc_tc
                    FStar_Pervasives_Native.None asc_use_eq in
                (match uu___2 with
                 | (asc1, aq) ->
                     let asc2 =
                       let uu___3 =
                         let uu___4 = FStarC_Syntax_Util.unascribe scrutinee in
                         uu___4.FStarC_Syntax_Syntax.n in
                       match uu___3 with
                       | FStarC_Syntax_Syntax.Tm_name sbv ->
                           let uu___4 =
                             let uu___5 =
                               let uu___6 =
                                 let uu___7 =
                                   FStarC_Syntax_Syntax.bv_to_name
                                     b.FStarC_Syntax_Syntax.binder_bv in
                                 (sbv, uu___7) in
                               FStarC_Syntax_Syntax.NT uu___6 in
                             [uu___5] in
                           FStarC_Syntax_Subst.subst_ascription uu___4 asc1
                       | uu___4 -> asc1 in
                     let asc3 = FStarC_Syntax_Subst.close_ascription [b] asc2 in
                     let b1 =
                       let uu___3 = FStarC_Syntax_Subst.close_binders [b] in
                       FStarC_List.hd uu___3 in
                     ((FStar_Pervasives_Native.Some (b1, asc3)), aq))))
and desugar_ascription (env : env_t) (t : FStarC_Parser_AST.term)
  (tac_opt : FStarC_Parser_AST.term FStar_Pervasives_Native.option)
  (use_eq : Prims.bool) :
  (FStarC_Syntax_Syntax.ascription * antiquotations_temp)=
  let uu___ =
    let uu___1 = is_comp_type env t in
    if uu___1
    then
      (if use_eq
       then
         FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term t
           FStarC_Errors_Codes.Fatal_NotSupported ()
           (Obj.magic FStarC_Errors_Msg.is_error_message_string)
           (Obj.magic
              "Equality ascription with computation types is not supported yet")
       else
         (let comp = desugar_comp t.FStarC_Parser_AST.range true env t in
          ((FStar_Pervasives.Inr comp), [])))
    else
      (let uu___3 = desugar_term_aq env t in
       match uu___3 with | (tm, aq) -> ((FStar_Pervasives.Inl tm), aq)) in
  match uu___ with
  | (annot, aq0) ->
      let uu___1 =
        let uu___2 = FStarC_Option.map (desugar_term env) tac_opt in
        (annot, uu___2, use_eq) in
      (uu___1, aq0)
and desugar_args (env : FStarC_Syntax_DsEnv.env)
  (args : (FStarC_Parser_AST.term * FStarC_Parser_AST.imp) Prims.list) :
  (FStarC_Syntax_Syntax.term * FStarC_Syntax_Syntax.arg_qualifier
    FStar_Pervasives_Native.option) Prims.list=
  FStarC_List.map
    (fun uu___ ->
       match uu___ with
       | (a, imp) ->
           let uu___1 = desugar_term env a in arg_withimp_t imp uu___1) args
and desugar_comp (r : FStarC_Range_Type.range)
  (allow_type_promotion : Prims.bool) (env : FStarC_Syntax_DsEnv.env)
  (t : FStarC_Parser_AST.term) : FStarC_Syntax_Syntax.comp=
  let fail code msg =
    FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r code ()
      (Obj.magic FStarC_Errors_Msg.is_error_message_string) (Obj.magic msg) in
  let is_requires uu___ =
    match uu___ with
    | (t1, uu___1) ->
        let uu___2 = let uu___3 = unparen t1 in uu___3.FStarC_Parser_AST.tm in
        (match uu___2 with
         | FStarC_Parser_AST.Requires uu___3 -> true
         | uu___3 -> false) in
  let is_ensures uu___ =
    match uu___ with
    | (t1, uu___1) ->
        let uu___2 = let uu___3 = unparen t1 in uu___3.FStarC_Parser_AST.tm in
        (match uu___2 with
         | FStarC_Parser_AST.Ensures uu___3 -> true
         | uu___3 -> false) in
  let is_decreases uu___ =
    match uu___ with
    | (t1, uu___1) ->
        let uu___2 = let uu___3 = unparen t1 in uu___3.FStarC_Parser_AST.tm in
        (match uu___2 with
         | FStarC_Parser_AST.Decreases uu___3 -> true
         | uu___3 -> false) in
  let is_smt_pat1 t1 =
    let uu___ = let uu___1 = unparen t1 in uu___1.FStarC_Parser_AST.tm in
    match uu___ with
    | FStarC_Parser_AST.Construct (smtpat, uu___1) ->
        FStarC_Util.for_some
          (fun s ->
             let uu___2 = FStarC_Ident.string_of_lid smtpat in uu___2 = s)
          ["SMTPat"; "SMTPatT"; "SMTPatOr"]
    | FStarC_Parser_AST.Var smtpat ->
        FStarC_Util.for_some
          (fun s ->
             let uu___1 = FStarC_Ident.string_of_lid smtpat in uu___1 = s)
          ["smt_pat"; "smt_pat_or"]
    | uu___1 -> false in
  let is_smt_pat uu___ =
    match uu___ with
    | (t1, uu___1) ->
        let uu___2 = let uu___3 = unparen t1 in uu___3.FStarC_Parser_AST.tm in
        (match uu___2 with
         | FStarC_Parser_AST.ListLiteral ts ->
             FStarC_Util.for_all is_smt_pat1 ts
         | uu___3 -> false) in
  let pre_process_comp_typ t1 =
    let uu___ = head_and_args t1 in
    match uu___ with
    | (head, args) ->
        (match head.FStarC_Parser_AST.tm with
         | FStarC_Parser_AST.Name lemma when
             let uu___1 =
               let uu___2 = FStarC_Ident.ident_of_lid lemma in
               FStarC_Ident.string_of_id uu___2 in
             uu___1 = "Lemma" ->
             let unit_tm =
               let uu___1 =
                 FStarC_Parser_AST.mk_term
                   (FStarC_Parser_AST.Name FStarC_Parser_Const.unit_lid)
                   t1.FStarC_Parser_AST.range FStarC_Parser_AST.Type_level in
               (uu___1, FStarC_Parser_AST.Nothing) in
             let nil_pat =
               let uu___1 =
                 FStarC_Parser_AST.mk_term
                   (FStarC_Parser_AST.Name FStarC_Parser_Const.nil_lid)
                   t1.FStarC_Parser_AST.range FStarC_Parser_AST.Expr in
               (uu___1, FStarC_Parser_AST.Nothing) in
             let req_true =
               let req =
                 let uu___1 =
                   FStarC_Parser_AST.mk_term
                     (FStarC_Parser_AST.Name FStarC_Parser_Const.true_lid)
                     t1.FStarC_Parser_AST.range FStarC_Parser_AST.Formula in
                 FStarC_Parser_AST.Requires uu___1 in
               let uu___1 =
                 FStarC_Parser_AST.mk_term req t1.FStarC_Parser_AST.range
                   FStarC_Parser_AST.Type_level in
               (uu___1, FStarC_Parser_AST.Nothing) in
             let thunk_ens uu___1 =
               match uu___1 with
               | (e, i) ->
                   let uu___2 = FStarC_Parser_AST.thunk e in (uu___2, i) in
             let fail_lemma uu___1 =
               let expected_one_of =
                 ["Lemma post";
                 "Lemma (ensures post)";
                 "Lemma (requires pre) (ensures post)";
                 "Lemma post [SMTPat ...]";
                 "Lemma (ensures post) [SMTPat ...]";
                 "Lemma (ensures post) (decreases d)";
                 "Lemma (ensures post) (decreases d) [SMTPat ...]";
                 "Lemma (requires pre) (ensures post) (decreases d)";
                 "Lemma (requires pre) (ensures post) [SMTPat ...]";
                 "Lemma (requires pre) (ensures post) (decreases d) [SMTPat ...]"] in
               let uu___2 =
                 let uu___3 =
                   let uu___4 =
                     FStarC_Errors_Msg.text
                       "Invalid arguments to 'Lemma'; expected one of the following" in
                   let uu___5 =
                     let uu___6 =
                       FStarC_List.map FStar_Pprint.doc_of_string
                         expected_one_of in
                     FStarC_Errors_Msg.sublist FStar_Pprint.empty uu___6 in
                   FStar_Pprint.op_Hat_Hat uu___4 uu___5 in
                 [uu___3] in
               FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term t1
                 FStarC_Errors_Codes.Fatal_InvalidLemmaArgument ()
                 (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
                 (Obj.magic uu___2) in
             let args1 =
               match args with
               | [] -> fail_lemma ()
               | req::[] when is_requires req -> fail_lemma ()
               | smtpat::[] when is_smt_pat smtpat -> fail_lemma ()
               | dec::[] when is_decreases dec -> fail_lemma ()
               | ens::[] ->
                   let uu___1 =
                     let uu___2 =
                       let uu___3 = thunk_ens ens in [uu___3; nil_pat] in
                     req_true :: uu___2 in
                   unit_tm :: uu___1
               | req::ens::[] when (is_requires req) && (is_ensures ens) ->
                   let uu___1 =
                     let uu___2 =
                       let uu___3 = thunk_ens ens in [uu___3; nil_pat] in
                     req :: uu___2 in
                   unit_tm :: uu___1
               | ens::smtpat::[] when
                   (((let uu___1 = is_requires ens in
                      Prims.op_Negation uu___1) &&
                       (let uu___1 = is_smt_pat ens in
                        Prims.op_Negation uu___1))
                      &&
                      (let uu___1 = is_decreases ens in
                       Prims.op_Negation uu___1))
                     && (is_smt_pat smtpat)
                   ->
                   let uu___1 =
                     let uu___2 =
                       let uu___3 = thunk_ens ens in [uu___3; smtpat] in
                     req_true :: uu___2 in
                   unit_tm :: uu___1
               | ens::dec::[] when (is_ensures ens) && (is_decreases dec) ->
                   let uu___1 =
                     let uu___2 =
                       let uu___3 = thunk_ens ens in [uu___3; nil_pat; dec] in
                     req_true :: uu___2 in
                   unit_tm :: uu___1
               | ens::dec::smtpat::[] when
                   ((is_ensures ens) && (is_decreases dec)) &&
                     (is_smt_pat smtpat)
                   ->
                   let uu___1 =
                     let uu___2 =
                       let uu___3 = thunk_ens ens in [uu___3; smtpat; dec] in
                     req_true :: uu___2 in
                   unit_tm :: uu___1
               | req::ens::dec::[] when
                   ((is_requires req) && (is_ensures ens)) &&
                     (is_decreases dec)
                   ->
                   let uu___1 =
                     let uu___2 =
                       let uu___3 = thunk_ens ens in [uu___3; nil_pat; dec] in
                     req :: uu___2 in
                   unit_tm :: uu___1
               | req::ens::smtpat::[] when
                   ((is_requires req) && (is_ensures ens)) &&
                     (is_smt_pat smtpat)
                   ->
                   let uu___1 =
                     let uu___2 =
                       let uu___3 = thunk_ens ens in [uu___3; smtpat] in
                     req :: uu___2 in
                   unit_tm :: uu___1
               | req::ens::dec::smtpat::[] when
                   (((is_requires req) && (is_ensures ens)) &&
                      (is_smt_pat smtpat))
                     && (is_decreases dec)
                   ->
                   let uu___1 =
                     let uu___2 =
                       let uu___3 = thunk_ens ens in [uu___3; dec; smtpat] in
                     req :: uu___2 in
                   unit_tm :: uu___1
               | _other -> fail_lemma () in
             let head_and_attributes =
               FStarC_Syntax_DsEnv.fail_or env
                 (FStarC_Syntax_DsEnv.try_lookup_effect_name_and_attributes
                    env) lemma in
             (head_and_attributes, args1)
         | FStarC_Parser_AST.Name l when
             FStarC_Syntax_DsEnv.is_effect_name env l ->
             let uu___1 =
               FStarC_Syntax_DsEnv.fail_or env
                 (FStarC_Syntax_DsEnv.try_lookup_effect_name_and_attributes
                    env) l in
             (uu___1, args)
         | FStarC_Parser_AST.Name l when
             (let uu___1 = FStarC_Syntax_DsEnv.current_module env in
              FStarC_Ident.lid_equals uu___1 FStarC_Parser_Const.prims_lid)
               &&
               (let uu___1 =
                  let uu___2 = FStarC_Ident.ident_of_lid l in
                  FStarC_Ident.string_of_id uu___2 in
                uu___1 = "Tot")
             ->
             let uu___1 =
               let uu___2 =
                 FStarC_Ident.set_lid_range
                   FStarC_Parser_Const.effect_Tot_lid
                   head.FStarC_Parser_AST.range in
               (uu___2, []) in
             (uu___1, args)
         | FStarC_Parser_AST.Name l when
             (let uu___1 = FStarC_Syntax_DsEnv.current_module env in
              FStarC_Ident.lid_equals uu___1 FStarC_Parser_Const.prims_lid)
               &&
               (let uu___1 =
                  let uu___2 = FStarC_Ident.ident_of_lid l in
                  FStarC_Ident.string_of_id uu___2 in
                uu___1 = "GTot")
             ->
             let uu___1 =
               let uu___2 =
                 FStarC_Ident.set_lid_range
                   FStarC_Parser_Const.effect_GTot_lid
                   head.FStarC_Parser_AST.range in
               (uu___2, []) in
             (uu___1, args)
         | FStarC_Parser_AST.Name l when
             ((let uu___1 =
                 let uu___2 = FStarC_Ident.ident_of_lid l in
                 FStarC_Ident.string_of_id uu___2 in
               uu___1 = "Type") ||
                (let uu___1 =
                   let uu___2 = FStarC_Ident.ident_of_lid l in
                   FStarC_Ident.string_of_id uu___2 in
                 uu___1 = "Type0"))
               ||
               (let uu___1 =
                  let uu___2 = FStarC_Ident.ident_of_lid l in
                  FStarC_Ident.string_of_id uu___2 in
                uu___1 = "Effect")
             ->
             let uu___1 =
               let uu___2 =
                 FStarC_Ident.set_lid_range
                   FStarC_Parser_Const.effect_Tot_lid
                   head.FStarC_Parser_AST.range in
               (uu___2, []) in
             (uu___1, [(t1, FStarC_Parser_AST.Nothing)])
         | uu___1 when allow_type_promotion ->
             let default_effect =
               let uu___2 = FStarC_Options.ml_ish () in
               if uu___2
               then FStarC_Parser_Const.effect_ML_lid ()
               else
                 ((let uu___5 = FStarC_Options.warn_default_effects () in
                   if uu___5
                   then
                     FStarC_Errors.log_issue FStarC_Parser_AST.hasRange_term
                       head FStarC_Errors_Codes.Warning_UseDefaultEffect ()
                       (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                       (Obj.magic "Using default effect Tot")
                   else ());
                  FStarC_Parser_Const.effect_Tot_lid) in
             let uu___2 =
               let uu___3 =
                 FStarC_Ident.set_lid_range default_effect
                   head.FStarC_Parser_AST.range in
               (uu___3, []) in
             (uu___2, [(t1, FStarC_Parser_AST.Nothing)])
         | uu___1 ->
             FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term t1
               FStarC_Errors_Codes.Fatal_EffectNotFound ()
               (Obj.magic FStarC_Errors_Msg.is_error_message_string)
               (Obj.magic "Expected an effect constructor")) in
  let uu___ = pre_process_comp_typ t in
  match uu___ with
  | ((eff, cattributes), args) ->
      (if (FStarC_List.length args) = Prims.int_zero
       then
         (let uu___2 =
            let uu___3 =
              FStarC_Class_Show.show FStarC_Ident.showable_lident eff in
            FStarC_Format.fmt1 "Not enough args to effect %s" uu___3 in
          fail FStarC_Errors_Codes.Fatal_NotEnoughArgsToEffect uu___2)
       else ();
       (let is_universe uu___2 =
          match uu___2 with
          | (uu___3, imp) -> imp = FStarC_Parser_AST.UnivApp in
        let uu___2 = FStarC_Util.take is_universe args in
        match uu___2 with
        | (universes, args1) ->
            let universes1 =
              FStarC_List.map
                (fun uu___3 ->
                   match uu___3 with | (u, imp) -> desugar_universe u)
                universes in
            let uu___3 =
              let uu___4 = FStarC_List.hd args1 in
              let uu___5 = FStarC_List.tl args1 in (uu___4, uu___5) in
            (match uu___3 with
             | (result_arg, rest) ->
                 let result_typ =
                   desugar_typ env (FStar_Pervasives_Native.fst result_arg) in
                 let uu___4 =
                   let is_decrease t1 =
                     let uu___5 =
                       let uu___6 = unparen (FStar_Pervasives_Native.fst t1) in
                       uu___6.FStarC_Parser_AST.tm in
                     match uu___5 with
                     | FStarC_Parser_AST.Decreases uu___6 -> true
                     | uu___6 -> false in
                   FStarC_List.partition is_decrease rest in
                 (match uu___4 with
                  | (dec, rest1) ->
                      let rest2 = desugar_args env rest1 in
                      let decreases_clause =
                        FStarC_List.map
                          (fun t1 ->
                             let uu___5 =
                               let uu___6 =
                                 unparen (FStar_Pervasives_Native.fst t1) in
                               uu___6.FStarC_Parser_AST.tm in
                             match uu___5 with
                             | FStarC_Parser_AST.Decreases t2 ->
                                 let dec_order =
                                   let t3 = unparen t2 in
                                   match t3.FStarC_Parser_AST.tm with
                                   | FStarC_Parser_AST.LexList l ->
                                       let uu___6 =
                                         FStarC_List.map (desugar_term env) l in
                                       FStarC_Syntax_Syntax.Decreases_lex
                                         uu___6
                                   | FStarC_Parser_AST.WFOrder (t11, t21) ->
                                       let uu___6 =
                                         let uu___7 = desugar_term env t11 in
                                         let uu___8 = desugar_term env t21 in
                                         (uu___7, uu___8) in
                                       FStarC_Syntax_Syntax.Decreases_wf
                                         uu___6
                                   | uu___6 ->
                                       let uu___7 =
                                         let uu___8 = desugar_term env t3 in
                                         [uu___8] in
                                       FStarC_Syntax_Syntax.Decreases_lex
                                         uu___7 in
                                 FStarC_Syntax_Syntax.DECREASES dec_order
                             | uu___6 ->
                                 fail
                                   FStarC_Errors_Codes.Fatal_UnexpectedComputationTypeForLetRec
                                   "Unexpected decreases clause") dec in
                      let no_additional_args =
                        let is_empty l =
                          match l with | [] -> true | uu___5 -> false in
                        (((is_empty decreases_clause) && (is_empty rest2)) &&
                           (is_empty cattributes))
                          && (is_empty universes1) in
                      let uu___5 =
                        no_additional_args &&
                          (FStarC_Ident.lid_equals eff
                             FStarC_Parser_Const.effect_Tot_lid) in
                      if uu___5
                      then FStarC_Syntax_Syntax.mk_Total result_typ
                      else
                        (let uu___7 =
                           no_additional_args &&
                             (FStarC_Ident.lid_equals eff
                                FStarC_Parser_Const.effect_GTot_lid) in
                         if uu___7
                         then FStarC_Syntax_Syntax.mk_GTotal result_typ
                         else
                           (let flags =
                              let uu___9 =
                                FStarC_Ident.lid_equals eff
                                  FStarC_Parser_Const.effect_Lemma_lid in
                              if uu___9
                              then [FStarC_Syntax_Syntax.LEMMA]
                              else
                                (let uu___11 =
                                   FStarC_Ident.lid_equals eff
                                     FStarC_Parser_Const.effect_Tot_lid in
                                 if uu___11
                                 then [FStarC_Syntax_Syntax.TOTAL]
                                 else
                                   (let uu___13 =
                                      let uu___14 =
                                        FStarC_Parser_Const.effect_ML_lid () in
                                      FStarC_Ident.lid_equals eff uu___14 in
                                    if uu___13
                                    then [FStarC_Syntax_Syntax.MLEFFECT]
                                    else
                                      (let uu___15 =
                                         FStarC_Ident.lid_equals eff
                                           FStarC_Parser_Const.effect_GTot_lid in
                                       if uu___15
                                       then
                                         [FStarC_Syntax_Syntax.SOMETRIVIAL]
                                       else []))) in
                            let flags1 = FStarC_List.op_At flags cattributes in
                            let rest3 =
                              let uu___9 =
                                FStarC_Ident.lid_equals eff
                                  FStarC_Parser_Const.effect_Lemma_lid in
                              if uu___9
                              then
                                match rest2 with
                                | req::ens::(pat, aq)::[] ->
                                    let pat1 =
                                      match pat.FStarC_Syntax_Syntax.n with
                                      | FStarC_Syntax_Syntax.Tm_fvar fv when
                                          FStarC_Syntax_Syntax.fv_eq_lid fv
                                            FStarC_Parser_Const.nil_lid
                                          ->
                                          let nil =
                                            FStarC_Syntax_Syntax.mk_Tm_uinst
                                              pat
                                              [FStarC_Syntax_Syntax.U_zero] in
                                          let pattern =
                                            let uu___10 =
                                              FStarC_Ident.set_lid_range
                                                FStarC_Parser_Const.pattern_lid
                                                pat.FStarC_Syntax_Syntax.pos in
                                            FStarC_Syntax_Syntax.fvar_with_dd
                                              uu___10
                                              FStar_Pervasives_Native.None in
                                          let uu___10 =
                                            let uu___11 =
                                              let uu___12 =
                                                FStarC_Syntax_Syntax.as_aqual_implicit
                                                  true in
                                              (pattern, uu___12) in
                                            [uu___11] in
                                          FStarC_Syntax_Syntax.mk_Tm_app nil
                                            uu___10
                                            pat.FStarC_Syntax_Syntax.pos
                                      | uu___10 -> pat in
                                    let uu___10 =
                                      let uu___11 =
                                        let uu___12 =
                                          let uu___13 =
                                            FStarC_Syntax_Syntax.mk
                                              (FStarC_Syntax_Syntax.Tm_meta
                                                 {
                                                   FStarC_Syntax_Syntax.tm2 =
                                                     pat1;
                                                   FStarC_Syntax_Syntax.meta
                                                     =
                                                     (FStarC_Syntax_Syntax.Meta_desugared
                                                        FStarC_Syntax_Syntax.Meta_smt_pat)
                                                 })
                                              pat1.FStarC_Syntax_Syntax.pos in
                                          (uu___13, aq) in
                                        [uu___12] in
                                      ens :: uu___11 in
                                    req :: uu___10
                                | uu___10 -> rest2
                              else rest2 in
                            FStarC_Syntax_Syntax.mk_Comp
                              {
                                FStarC_Syntax_Syntax.comp_univs = universes1;
                                FStarC_Syntax_Syntax.effect_name = eff;
                                FStarC_Syntax_Syntax.result_typ = result_typ;
                                FStarC_Syntax_Syntax.effect_args = rest3;
                                FStarC_Syntax_Syntax.flags =
                                  (FStarC_List.op_At flags1 decreases_clause)
                              }))))))
and desugar_formula (env : FStarC_Syntax_DsEnv.env)
  (f : FStarC_Parser_AST.term) : FStarC_Syntax_Syntax.term=
  let mk t = FStarC_Syntax_Syntax.mk t f.FStarC_Parser_AST.range in
  let setpos t =
    {
      FStarC_Syntax_Syntax.n = (t.FStarC_Syntax_Syntax.n);
      FStarC_Syntax_Syntax.pos = (f.FStarC_Parser_AST.range);
      FStarC_Syntax_Syntax.vars = (t.FStarC_Syntax_Syntax.vars);
      FStarC_Syntax_Syntax.hash_code = (t.FStarC_Syntax_Syntax.hash_code)
    } in
  let desugar_quant q_head b pats should_wrap_with_pat body =
    let tk =
      desugar_binder env
        {
          FStarC_Parser_AST.b = (b.FStarC_Parser_AST.b);
          FStarC_Parser_AST.brange = (b.FStarC_Parser_AST.brange);
          FStarC_Parser_AST.blevel = FStarC_Parser_AST.Formula;
          FStarC_Parser_AST.aqual = (b.FStarC_Parser_AST.aqual);
          FStarC_Parser_AST.battributes = (b.FStarC_Parser_AST.battributes)
        } in
    let with_pats env1 uu___ body1 =
      match uu___ with
      | (names, pats1) ->
          (match (names, pats1) with
           | ([], []) -> body1
           | ([], uu___1::uu___2) ->
               failwith
                 "Impossible: Annotated pattern without binders in scope"
           | uu___1 ->
               let names1 =
                 FStarC_List.map
                   (fun i ->
                      let uu___2 =
                        FStarC_Syntax_DsEnv.fail_or2 env1
                          (FStarC_Syntax_DsEnv.try_lookup_id env1) i in
                      let uu___3 = FStarC_Ident.range_of_id i in
                      {
                        FStarC_Syntax_Syntax.n =
                          (uu___2.FStarC_Syntax_Syntax.n);
                        FStarC_Syntax_Syntax.pos = uu___3;
                        FStarC_Syntax_Syntax.vars =
                          (uu___2.FStarC_Syntax_Syntax.vars);
                        FStarC_Syntax_Syntax.hash_code =
                          (uu___2.FStarC_Syntax_Syntax.hash_code)
                      }) names in
               let pats2 =
                 FStarC_List.map
                   (fun es ->
                      FStarC_List.map
                        (fun e ->
                           let uu___2 = desugar_term env1 e in
                           arg_withimp_t FStarC_Parser_AST.Nothing uu___2) es)
                   pats1 in
               (match pats2 with
                | [] when Prims.op_Negation should_wrap_with_pat -> body1
                | uu___2 ->
                    mk
                      (FStarC_Syntax_Syntax.Tm_meta
                         {
                           FStarC_Syntax_Syntax.tm2 = body1;
                           FStarC_Syntax_Syntax.meta =
                             (FStarC_Syntax_Syntax.Meta_pattern
                                (names1, pats2))
                         }))) in
    match tk with
    | (FStar_Pervasives_Native.Some a, k, uu___) ->
        let uu___1 = FStarC_Syntax_DsEnv.push_bv env a in
        (match uu___1 with
         | (env1, a1) ->
             let a2 =
               {
                 FStarC_Syntax_Syntax.ppname =
                   (a1.FStarC_Syntax_Syntax.ppname);
                 FStarC_Syntax_Syntax.index = (a1.FStarC_Syntax_Syntax.index);
                 FStarC_Syntax_Syntax.sort = k
               } in
             let body1 = desugar_formula env1 body in
             let body2 = with_pats env1 pats body1 in
             let body3 =
               let uu___2 =
                 let uu___3 =
                   let uu___4 = FStarC_Syntax_Syntax.mk_binder a2 in [uu___4] in
                 no_annot_abs uu___3 body2 in
               setpos uu___2 in
             let uu___2 =
               let uu___3 =
                 let uu___4 =
                   let uu___5 = FStarC_Syntax_Syntax.as_arg body3 in [uu___5] in
                 {
                   FStarC_Syntax_Syntax.hd = q_head;
                   FStarC_Syntax_Syntax.args = uu___4
                 } in
               FStarC_Syntax_Syntax.Tm_app uu___3 in
             mk uu___2)
    | uu___ -> failwith "impossible" in
  let push_quant q binders pats body =
    match binders with
    | b::b'::_rest ->
        let rest = b' :: _rest in
        let body1 =
          let uu___ = q (rest, pats, body) in
          let uu___1 =
            FStarC_Range_Ops.union_ranges b'.FStarC_Parser_AST.brange
              body.FStarC_Parser_AST.range in
          FStarC_Parser_AST.mk_term uu___ uu___1 FStarC_Parser_AST.Formula in
        let uu___ = q ([b], ([], []), body1) in
        FStarC_Parser_AST.mk_term uu___ f.FStarC_Parser_AST.range
          FStarC_Parser_AST.Formula
    | uu___ -> failwith "impossible" in
  let uu___ = let uu___1 = unparen f in uu___1.FStarC_Parser_AST.tm in
  match uu___ with
  | FStarC_Parser_AST.Labeled (f1, l, p) ->
      let f2 = desugar_formula env f1 in
      let uu___1 =
        let uu___2 =
          let uu___3 =
            let uu___4 =
              let uu___5 = FStarC_Errors_Msg.mkmsg l in
              (uu___5, (f2.FStarC_Syntax_Syntax.pos), p) in
            FStarC_Syntax_Syntax.Meta_labeled uu___4 in
          { FStarC_Syntax_Syntax.tm2 = f2; FStarC_Syntax_Syntax.meta = uu___3
          } in
        FStarC_Syntax_Syntax.Tm_meta uu___2 in
      mk uu___1
  | FStarC_Parser_AST.QForall ([], uu___1, uu___2) ->
      failwith "Impossible: Quantifier without binders"
  | FStarC_Parser_AST.QExists ([], uu___1, uu___2) ->
      failwith "Impossible: Quantifier without binders"
  | FStarC_Parser_AST.QuantOp (uu___1, [], uu___2, uu___3) ->
      failwith "Impossible: Quantifier without binders"
  | FStarC_Parser_AST.QForall (_1::_2::_3, pats, body) ->
      let binders = _1 :: _2 :: _3 in
      let uu___1 =
        push_quant (fun x -> FStarC_Parser_AST.QForall x) binders pats body in
      desugar_formula env uu___1
  | FStarC_Parser_AST.QExists (_1::_2::_3, pats, body) ->
      let binders = _1 :: _2 :: _3 in
      let uu___1 =
        push_quant (fun x -> FStarC_Parser_AST.QExists x) binders pats body in
      desugar_formula env uu___1
  | FStarC_Parser_AST.QuantOp (i, _1::_2::_3, pats, body) ->
      let binders = _1 :: _2 :: _3 in
      let uu___1 =
        push_quant
          (fun uu___2 ->
             match uu___2 with
             | (x, y, z) -> FStarC_Parser_AST.QuantOp (i, x, y, z)) binders
          pats body in
      desugar_formula env uu___1
  | FStarC_Parser_AST.QForall (b::[], pats, body) ->
      let q = FStarC_Parser_Const.forall_lid in
      let q_head =
        let uu___1 = FStarC_Ident.set_lid_range q b.FStarC_Parser_AST.brange in
        FStarC_Syntax_Syntax.fvar_with_dd uu___1 FStar_Pervasives_Native.None in
      desugar_quant q_head b pats true body
  | FStarC_Parser_AST.QExists (b::[], pats, body) ->
      let q = FStarC_Parser_Const.exists_lid in
      let q_head =
        let uu___1 = FStarC_Ident.set_lid_range q b.FStarC_Parser_AST.brange in
        FStarC_Syntax_Syntax.fvar_with_dd uu___1 FStar_Pervasives_Native.None in
      desugar_quant q_head b pats true body
  | FStarC_Parser_AST.QuantOp (i, b::[], pats, body) ->
      let q_head =
        let uu___1 = op_as_term env Prims.int_zero i in
        match uu___1 with
        | FStar_Pervasives_Native.None ->
            let uu___2 =
              let uu___3 = FStarC_Ident.string_of_id i in
              FStarC_Format.fmt1 "quantifier operator %s not found" uu___3 in
            FStarC_Errors.raise_error FStarC_Ident.hasrange_ident i
              FStarC_Errors_Codes.Fatal_VariableNotFound ()
              (Obj.magic FStarC_Errors_Msg.is_error_message_string)
              (Obj.magic uu___2)
        | FStar_Pervasives_Native.Some t -> t in
      desugar_quant q_head b pats false body
  | FStarC_Parser_AST.Paren f1 -> failwith "impossible"
  | uu___1 -> desugar_term env f
and desugar_binder_aq (env : FStarC_Syntax_DsEnv.env)
  (b : FStarC_Parser_AST.binder) :
  ((FStarC_Ident.ident FStar_Pervasives_Native.option *
    FStarC_Syntax_Syntax.term * FStarC_Syntax_Syntax.attribute Prims.list) *
    antiquotations_temp)=
  let attrs =
    FStarC_List.map (desugar_term env) b.FStarC_Parser_AST.battributes in
  match b.FStarC_Parser_AST.b with
  | FStarC_Parser_AST.Annotated (x, t) ->
      let uu___ = desugar_typ_aq env t in
      (match uu___ with
       | (ty, aqs) -> (((FStar_Pervasives_Native.Some x), ty, attrs), aqs))
  | FStarC_Parser_AST.NoName t ->
      let uu___ = desugar_typ_aq env t in
      (match uu___ with
       | (ty, aqs) -> ((FStar_Pervasives_Native.None, ty, attrs), aqs))
  | FStarC_Parser_AST.Variable x ->
      let ident_is_ticked id =
        let nm = FStarC_Ident.string_of_id id in
        ((FStarC_String.length nm) > Prims.int_zero) &&
          (let uu___ = FStarC_String.get nm Prims.int_zero in uu___ = 39) in
      let uu___ = ident_is_ticked x in
      if uu___
      then
        let uu___1 =
          let uu___2 =
            let uu___3 = FStarC_Ident.range_of_id x in
            FStarC_Class_HasRange.setPos
              (FStarC_Syntax_Syntax.has_range_syntax ()) uu___3
              FStarC_Syntax_Util.ktype in
          ((FStar_Pervasives_Native.Some x), uu___2, attrs) in
        (uu___1, [])
      else
        (let uu___2 =
           let uu___3 =
             let uu___4 = FStarC_Ident.range_of_id x in tun_r uu___4 in
           ((FStar_Pervasives_Native.Some x), uu___3, attrs) in
         (uu___2, []))
and desugar_binder (env : FStarC_Syntax_DsEnv.env)
  (b : FStarC_Parser_AST.binder) :
  (FStarC_Ident.ident FStar_Pervasives_Native.option *
    FStarC_Syntax_Syntax.term * FStarC_Syntax_Syntax.attribute Prims.list)=
  let uu___ = desugar_binder_aq env b in
  match uu___ with | (r, aqs) -> (check_no_aq aqs; r)
and desugar_vquote (env : env_t) (e : FStarC_Parser_AST.term)
  (r : FStarC_Range_Type.range) : Prims.string=
  let tm = desugar_term env e in
  let uu___ =
    let uu___1 = FStarC_Syntax_Subst.compress tm in
    uu___1.FStarC_Syntax_Syntax.n in
  match uu___ with
  | FStarC_Syntax_Syntax.Tm_fvar fv ->
      let uu___1 = FStarC_Syntax_Syntax.lid_of_fv fv in
      FStarC_Ident.string_of_lid uu___1
  | uu___1 ->
      let uu___2 =
        let uu___3 =
          FStarC_Class_Show.show FStarC_Syntax_Print.showable_term tm in
        Prims.strcat "VQuote, expected an fvar, got: " uu___3 in
      FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
        FStarC_Errors_Codes.Fatal_UnexpectedTermVQuote ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic uu___2)
and as_binder (env : FStarC_Syntax_DsEnv.env)
  (imp : FStarC_Parser_AST.arg_qualifier FStar_Pervasives_Native.option)
  (uu___ :
    (FStarC_Ident.ident FStar_Pervasives_Native.option *
      FStarC_Syntax_Syntax.term * FStarC_Syntax_Syntax.attribute Prims.list))
  : (FStarC_Syntax_Syntax.binder * FStarC_Syntax_DsEnv.env)=
  match uu___ with
  | (FStar_Pervasives_Native.None, k, attrs) ->
      let uu___1 =
        let uu___2 = FStarC_Syntax_Syntax.null_bv k in
        let uu___3 = trans_bqual env imp in
        mk_binder_with_attrs uu___2 uu___3 attrs in
      (uu___1, env)
  | (FStar_Pervasives_Native.Some a, k, attrs) ->
      let uu___1 = FStarC_Syntax_DsEnv.push_bv env a in
      (match uu___1 with
       | (env1, a1) ->
           let uu___2 =
             let uu___3 = trans_bqual env1 imp in
             mk_binder_with_attrs
               {
                 FStarC_Syntax_Syntax.ppname =
                   (a1.FStarC_Syntax_Syntax.ppname);
                 FStarC_Syntax_Syntax.index = (a1.FStarC_Syntax_Syntax.index);
                 FStarC_Syntax_Syntax.sort = k
               } uu___3 attrs in
           (uu___2, env1))
and trans_bqual (env : env_t)
  (uu___ : FStarC_Parser_AST.arg_qualifier FStar_Pervasives_Native.option) :
  FStarC_Syntax_Syntax.bqual=
  match uu___ with
  | FStar_Pervasives_Native.Some (FStarC_Parser_AST.Implicit) ->
      FStar_Pervasives_Native.Some FStarC_Syntax_Syntax.imp_tag
  | FStar_Pervasives_Native.Some (FStarC_Parser_AST.Equality) ->
      FStar_Pervasives_Native.Some FStarC_Syntax_Syntax.Equality
  | FStar_Pervasives_Native.Some (FStarC_Parser_AST.Meta t) ->
      let uu___1 =
        let uu___2 = desugar_term env t in FStarC_Syntax_Syntax.Meta uu___2 in
      FStar_Pervasives_Native.Some uu___1
  | FStar_Pervasives_Native.Some (FStarC_Parser_AST.TypeClassArg) ->
      let tcresolve =
        let uu___1 =
          FStarC_Parser_AST.mk_term
            (FStarC_Parser_AST.Var FStarC_Parser_Const.tcresolve_lid)
            FStarC_Range_Type.dummyRange FStarC_Parser_AST.Expr in
        desugar_term env uu___1 in
      FStar_Pervasives_Native.Some (FStarC_Syntax_Syntax.Meta tcresolve)
  | FStar_Pervasives_Native.None -> FStar_Pervasives_Native.None
let typars_of_binders (env : FStarC_Syntax_DsEnv.env)
  (bs : FStarC_Parser_AST.binder Prims.list) :
  (FStarC_Syntax_DsEnv.env * FStarC_Syntax_Syntax.binders)=
  let uu___ =
    FStarC_List.fold_left
      (fun uu___1 b ->
         match uu___1 with
         | (env1, out) ->
             let tk =
               desugar_binder env1
                 {
                   FStarC_Parser_AST.b = (b.FStarC_Parser_AST.b);
                   FStarC_Parser_AST.brange = (b.FStarC_Parser_AST.brange);
                   FStarC_Parser_AST.blevel = FStarC_Parser_AST.Formula;
                   FStarC_Parser_AST.aqual = (b.FStarC_Parser_AST.aqual);
                   FStarC_Parser_AST.battributes =
                     (b.FStarC_Parser_AST.battributes)
                 } in
             (match tk with
              | (FStar_Pervasives_Native.Some a, k, attrs) ->
                  let uu___2 = FStarC_Syntax_DsEnv.push_bv env1 a in
                  (match uu___2 with
                   | (env2, a1) ->
                       let a2 =
                         {
                           FStarC_Syntax_Syntax.ppname =
                             (a1.FStarC_Syntax_Syntax.ppname);
                           FStarC_Syntax_Syntax.index =
                             (a1.FStarC_Syntax_Syntax.index);
                           FStarC_Syntax_Syntax.sort = k
                         } in
                       let uu___3 =
                         let uu___4 =
                           let uu___5 =
                             trans_bqual env2 b.FStarC_Parser_AST.aqual in
                           mk_binder_with_attrs a2 uu___5 attrs in
                         uu___4 :: out in
                       (env2, uu___3))
              | uu___2 ->
                  FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_binder
                    b FStarC_Errors_Codes.Fatal_UnexpectedBinder ()
                    (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                    (Obj.magic "Unexpected binder"))) (env, []) bs in
  match uu___ with | (env1, tpars) -> (env1, (FStarC_List.rev tpars))
let desugar_attributes (env : env_t)
  (cattributes : FStarC_Parser_AST.term Prims.list) :
  FStarC_Syntax_Syntax.cflag Prims.list=
  let desugar_attribute t =
    let uu___ = let uu___1 = unparen t in uu___1.FStarC_Parser_AST.tm in
    match uu___ with
    | FStarC_Parser_AST.Var lid when
        let uu___1 = FStarC_Ident.string_of_lid lid in uu___1 = "cps" ->
        FStarC_Syntax_Syntax.CPS
    | uu___1 ->
        let uu___2 =
          let uu___3 = FStarC_Parser_AST.term_to_string t in
          Prims.strcat "Unknown attribute " uu___3 in
        FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term t
          FStarC_Errors_Codes.Fatal_UnknownAttribute ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_string)
          (Obj.magic uu___2) in
  FStarC_List.map desugar_attribute cattributes
let binder_ident (b : FStarC_Parser_AST.binder) :
  FStarC_Ident.ident FStar_Pervasives_Native.option=
  match b.FStarC_Parser_AST.b with
  | FStarC_Parser_AST.Annotated (x, uu___) -> FStar_Pervasives_Native.Some x
  | FStarC_Parser_AST.Variable x -> FStar_Pervasives_Native.Some x
  | FStarC_Parser_AST.NoName uu___ -> FStar_Pervasives_Native.None
let binder_idents (bs : FStarC_Parser_AST.binder Prims.list) :
  FStarC_Ident.ident Prims.list=
  FStarC_List.collect
    (fun b ->
       let uu___ = binder_ident b in FStarC_Common.list_of_option uu___) bs
let mk_typ_abbrev (env : FStarC_Syntax_DsEnv.env)
  (d : FStarC_Parser_AST.decl) (lid : FStarC_Ident.lident)
  (uvs : FStarC_Syntax_Syntax.univ_name Prims.list)
  (typars : FStarC_Syntax_Syntax.binders)
  (kopt : FStarC_Syntax_Syntax.typ FStar_Pervasives_Native.option)
  (t : FStarC_Syntax_Syntax.term) (lids : FStarC_Ident.lident Prims.list)
  (quals : FStarC_Syntax_Syntax.qualifier Prims.list)
  (rng : FStarC_Range_Type.range) : FStarC_Syntax_Syntax.sigelt=
  let attrs =
    let uu___ = FStarC_List.map (desugar_term env) d.FStarC_Parser_AST.attrs in
    FStarC_Syntax_Util.deduplicate_terms uu___ in
  let val_attrs =
    let uu___ = FStarC_Syntax_DsEnv.lookup_letbinding_quals_and_attrs env lid in
    FStar_Pervasives_Native.snd uu___ in
  let lb =
    let uu___ =
      let uu___1 =
        FStarC_Syntax_Syntax.lid_and_dd_as_fv lid
          FStar_Pervasives_Native.None in
      FStar_Pervasives.Inr uu___1 in
    let uu___1 =
      if FStar_Pervasives_Native.uu___is_Some kopt
      then
        let uu___2 =
          let uu___3 = FStarC_Option.must kopt in
          FStarC_Syntax_Syntax.mk_Total uu___3 in
        FStarC_Syntax_Util.arrow typars uu___2
      else FStarC_Syntax_Syntax.tun in
    let uu___2 = no_annot_abs typars t in
    {
      FStarC_Syntax_Syntax.lbname = uu___;
      FStarC_Syntax_Syntax.lbunivs = uvs;
      FStarC_Syntax_Syntax.lbtyp = uu___1;
      FStarC_Syntax_Syntax.lbeff = FStarC_Parser_Const.effect_Tot_lid;
      FStarC_Syntax_Syntax.lbdef = uu___2;
      FStarC_Syntax_Syntax.lbattrs = [];
      FStarC_Syntax_Syntax.lbpos = rng
    } in
  let uu___ =
    FStarC_Syntax_Util.deduplicate_terms (FStarC_List.op_At val_attrs attrs) in
  let uu___1 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
  {
    FStarC_Syntax_Syntax.sigel =
      (FStarC_Syntax_Syntax.Sig_let
         {
           FStarC_Syntax_Syntax.lbs1 = (false, [lb]);
           FStarC_Syntax_Syntax.lids1 = lids
         });
    FStarC_Syntax_Syntax.sigrng = rng;
    FStarC_Syntax_Syntax.sigquals = quals;
    FStarC_Syntax_Syntax.sigmeta = FStarC_Syntax_Syntax.default_sigmeta;
    FStarC_Syntax_Syntax.sigattrs = uu___;
    FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___1;
    FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
  }
let rec desugar_tycon (env : FStarC_Syntax_DsEnv.env)
  (d : FStarC_Parser_AST.decl)
  (d_attrs_initial : FStarC_Syntax_Syntax.term Prims.list)
  (quals : FStarC_Syntax_Syntax.qualifier Prims.list)
  (tcs : FStarC_Parser_AST.tycon Prims.list) :
  (env_t * FStarC_Syntax_Syntax.sigelts)=
  let rng = d.FStarC_Parser_AST.drange in
  let tycon_id uu___ =
    match uu___ with
    | FStarC_Parser_AST.TyconAbstract (id, uu___1, uu___2) -> id
    | FStarC_Parser_AST.TyconAbbrev (id, uu___1, uu___2, uu___3) -> id
    | FStarC_Parser_AST.TyconRecord (id, uu___1, uu___2, uu___3, uu___4) ->
        id
    | FStarC_Parser_AST.TyconVariant (id, uu___1, uu___2, uu___3) -> id in
  let binder_to_term b =
    match b.FStarC_Parser_AST.b with
    | FStarC_Parser_AST.Annotated (x, uu___) ->
        let uu___1 =
          let uu___2 = FStarC_Ident.lid_of_ids [x] in
          FStarC_Parser_AST.Var uu___2 in
        let uu___2 = FStarC_Ident.range_of_id x in
        FStarC_Parser_AST.mk_term uu___1 uu___2 FStarC_Parser_AST.Expr
    | FStarC_Parser_AST.Variable x ->
        let uu___ =
          let uu___1 = FStarC_Ident.lid_of_ids [x] in
          FStarC_Parser_AST.Var uu___1 in
        let uu___1 = FStarC_Ident.range_of_id x in
        FStarC_Parser_AST.mk_term uu___ uu___1 FStarC_Parser_AST.Expr
    | FStarC_Parser_AST.NoName t -> t in
  let desugar_tycon_variant_record uu___ =
    match uu___ with
    | FStarC_Parser_AST.TyconVariant (id, bds, k, variants) ->
        let uu___1 =
          let uu___2 =
            FStarC_List.map
              (fun uu___3 ->
                 match uu___3 with
                 | (cid, payload, attrs) ->
                     (match payload with
                      | FStar_Pervasives_Native.Some
                          (FStarC_Parser_AST.VpRecord (r, k1)) ->
                          let record_id =
                            let uu___4 =
                              let uu___5 =
                                let uu___6 = FStarC_Ident.string_of_id id in
                                let uu___7 =
                                  let uu___8 =
                                    let uu___9 =
                                      FStarC_Ident.string_of_id cid in
                                    Prims.strcat uu___9 "__payload" in
                                  Prims.strcat "__" uu___8 in
                                Prims.strcat uu___6 uu___7 in
                              let uu___6 = FStarC_Ident.range_of_id cid in
                              (uu___5, uu___6) in
                            FStarC_Ident.mk_ident uu___4 in
                          let record_id_t =
                            let uu___4 =
                              let uu___5 =
                                FStarC_Ident.lid_of_ns_and_id [] record_id in
                              FStarC_Parser_AST.Var uu___5 in
                            let uu___5 = FStarC_Ident.range_of_id cid in
                            {
                              FStarC_Parser_AST.tm = uu___4;
                              FStarC_Parser_AST.range = uu___5;
                              FStarC_Parser_AST.level =
                                FStarC_Parser_AST.Type_level
                            } in
                          let payload_typ =
                            let uu___4 =
                              FStarC_List.map
                                (fun bd ->
                                   let uu___5 = binder_to_term bd in
                                   (uu___5, FStarC_Parser_AST.Nothing)) bds in
                            let uu___5 = FStarC_Ident.range_of_id record_id in
                            FStarC_Parser_AST.mkApp record_id_t uu___4 uu___5 in
                          let desugar_marker =
                            let range = FStarC_Ident.range_of_id record_id in
                            let desugar_attr_fv =
                              let uu___4 =
                                FStarC_Class_HasRange.setPos
                                  FStarC_Ident.hasrange_lident range
                                  FStarC_Parser_Const.desugar_of_variant_record_lid in
                              {
                                FStarC_Syntax_Syntax.fv_name = uu___4;
                                FStarC_Syntax_Syntax.fv_qual =
                                  FStar_Pervasives_Native.None
                              } in
                            let desugar_attr =
                              FStarC_Syntax_Syntax.mk
                                (FStarC_Syntax_Syntax.Tm_fvar desugar_attr_fv)
                                range in
                            let cid_as_constant =
                              let uu___4 =
                                let uu___5 =
                                  let uu___6 =
                                    FStarC_Syntax_DsEnv.qualify env cid in
                                  FStarC_Ident.string_of_lid uu___6 in
                                FStarC_Syntax_Embeddings_Base.embed
                                  FStarC_Syntax_Embeddings.e_string uu___5 in
                              uu___4 range FStar_Pervasives_Native.None
                                FStarC_Syntax_Embeddings_Base.id_norm_cb in
                            FStarC_Syntax_Syntax.mk_Tm_app desugar_attr
                              [(cid_as_constant,
                                 FStar_Pervasives_Native.None)] range in
                          let uu___4 =
                            let uu___5 =
                              let uu___6 =
                                match k1 with
                                | FStar_Pervasives_Native.None ->
                                    FStarC_Parser_AST.VpOfNotation
                                      payload_typ
                                | FStar_Pervasives_Native.Some k2 ->
                                    let uu___7 =
                                      let uu___8 =
                                        let uu___9 =
                                          let uu___10 =
                                            let uu___11 =
                                              let uu___12 =
                                                FStarC_Ident.range_of_id
                                                  record_id in
                                              FStarC_Parser_AST.mk_binder
                                                (FStarC_Parser_AST.NoName
                                                   payload_typ) uu___12
                                                FStarC_Parser_AST.Type_level
                                                FStar_Pervasives_Native.None in
                                            [uu___11] in
                                          (uu___10, k2) in
                                        FStarC_Parser_AST.Product uu___9 in
                                      {
                                        FStarC_Parser_AST.tm = uu___8;
                                        FStarC_Parser_AST.range =
                                          (payload_typ.FStarC_Parser_AST.range);
                                        FStarC_Parser_AST.level =
                                          FStarC_Parser_AST.Type_level
                                      } in
                                    FStarC_Parser_AST.VpArbitrary uu___7 in
                              FStar_Pervasives_Native.Some uu___6 in
                            (cid, uu___5, attrs) in
                          ((FStar_Pervasives_Native.Some
                              ((FStarC_Parser_AST.TyconRecord
                                  (record_id, bds,
                                    FStar_Pervasives_Native.None, attrs, r)),
                                (desugar_marker :: d_attrs_initial))),
                            uu___4)
                      | uu___4 ->
                          (FStar_Pervasives_Native.None,
                            (cid, payload, attrs)))) variants in
          FStarC_List.unzip uu___2 in
        (match uu___1 with
         | (additional_records, variants1) ->
             let concat_options = FStarC_List.filter_map (fun r -> r) in
             let uu___2 = concat_options additional_records in
             FStarC_List.op_At uu___2
               [((FStarC_Parser_AST.TyconVariant (id, bds, k, variants1)),
                  d_attrs_initial)])
    | tycon -> [(tycon, d_attrs_initial)] in
  let tcs1 = FStarC_List.concatMap desugar_tycon_variant_record tcs in
  let tot rng1 =
    FStarC_Parser_AST.mk_term
      (FStarC_Parser_AST.Name FStarC_Parser_Const.effect_Tot_lid) rng1
      FStarC_Parser_AST.Expr in
  let with_constructor_effect t =
    let uu___ =
      let uu___1 =
        let uu___2 = tot t.FStarC_Parser_AST.range in
        (uu___2, t, FStarC_Parser_AST.Nothing) in
      FStarC_Parser_AST.App uu___1 in
    FStarC_Parser_AST.mk_term uu___ t.FStarC_Parser_AST.range
      t.FStarC_Parser_AST.level in
  let apply_binders t binders =
    let imp_of_aqual b =
      match b.FStarC_Parser_AST.aqual with
      | FStar_Pervasives_Native.Some (FStarC_Parser_AST.Implicit) ->
          FStarC_Parser_AST.Hash
      | FStar_Pervasives_Native.Some (FStarC_Parser_AST.Meta uu___) ->
          FStarC_Parser_AST.Hash
      | FStar_Pervasives_Native.Some (FStarC_Parser_AST.TypeClassArg) ->
          FStarC_Parser_AST.Hash
      | uu___ -> FStarC_Parser_AST.Nothing in
    FStarC_List.fold_left
      (fun out b ->
         let uu___ =
           let uu___1 =
             let uu___2 = binder_to_term b in (out, uu___2, (imp_of_aqual b)) in
           FStarC_Parser_AST.App uu___1 in
         FStarC_Parser_AST.mk_term uu___ out.FStarC_Parser_AST.range
           out.FStarC_Parser_AST.level) t binders in
  let tycon_record_as_variant uu___ =
    match uu___ with
    | FStarC_Parser_AST.TyconRecord (id, parms, kopt, attrs, fields) ->
        let constrName =
          let uu___1 =
            let uu___2 =
              let uu___3 = FStarC_Ident.string_of_id id in
              Prims.strcat "Mk" uu___3 in
            let uu___3 = FStarC_Ident.range_of_id id in (uu___2, uu___3) in
          FStarC_Ident.mk_ident uu___1 in
        let mfields =
          FStarC_List.map
            (fun uu___1 ->
               match uu___1 with
               | (x, q, attrs1, t) ->
                   let uu___2 = FStarC_Ident.range_of_id x in
                   FStarC_Parser_AST.mk_binder_with_attrs
                     (FStarC_Parser_AST.Annotated (x, t)) uu___2
                     FStarC_Parser_AST.Expr q attrs1) fields in
        let result =
          let uu___1 =
            let uu___2 =
              let uu___3 = FStarC_Ident.lid_of_ids [id] in
              FStarC_Parser_AST.Var uu___3 in
            let uu___3 = FStarC_Ident.range_of_id id in
            FStarC_Parser_AST.mk_term uu___2 uu___3
              FStarC_Parser_AST.Type_level in
          apply_binders uu___1 parms in
        let constrTyp =
          let uu___1 =
            let uu___2 =
              let uu___3 = with_constructor_effect result in
              (mfields, uu___3) in
            FStarC_Parser_AST.Product uu___2 in
          let uu___2 = FStarC_Ident.range_of_id id in
          FStarC_Parser_AST.mk_term uu___1 uu___2
            FStarC_Parser_AST.Type_level in
        let names = let uu___1 = binder_idents parms in id :: uu___1 in
        (FStarC_List.iter
           (fun uu___2 ->
              match uu___2 with
              | (f, uu___3, uu___4, uu___5) ->
                  let uu___6 =
                    FStarC_Util.for_some
                      (fun i -> FStarC_Ident.ident_equals f i) names in
                  if uu___6
                  then
                    let uu___7 =
                      let uu___8 = FStarC_Ident.string_of_id f in
                      FStarC_Format.fmt1
                        "Field %s shadows the record's name or a parameter of it, please rename it"
                        uu___8 in
                    FStarC_Errors.raise_error FStarC_Ident.hasrange_ident f
                      FStarC_Errors_Codes.Error_FieldShadow ()
                      (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                      (Obj.magic uu___7)
                  else ()) fields;
         (let uu___2 =
            FStarC_List.map
              (fun uu___3 ->
                 match uu___3 with | (f, uu___4, uu___5, uu___6) -> f) fields in
          ((FStarC_Parser_AST.TyconVariant
              (id, parms, kopt,
                [(constrName,
                   (FStar_Pervasives_Native.Some
                      (FStarC_Parser_AST.VpArbitrary constrTyp)), attrs)])),
            uu___2)))
    | uu___1 -> failwith "impossible" in
  let desugar_abstract_tc quals1 _env mutuals d_attrs uu___ =
    match uu___ with
    | FStarC_Parser_AST.TyconAbstract (id, binders, kopt) ->
        let uu___1 = typars_of_binders _env binders in
        (match uu___1 with
         | (_env', typars) ->
             let k =
               match kopt with
               | FStar_Pervasives_Native.None -> FStarC_Syntax_Util.ktype
               | FStar_Pervasives_Native.Some k1 -> desugar_term _env' k1 in
             let tconstr =
               let uu___2 =
                 let uu___3 =
                   let uu___4 = FStarC_Ident.lid_of_ids [id] in
                   FStarC_Parser_AST.Var uu___4 in
                 let uu___4 = FStarC_Ident.range_of_id id in
                 FStarC_Parser_AST.mk_term uu___3 uu___4
                   FStarC_Parser_AST.Type_level in
               apply_binders uu___2 binders in
             let qlid = FStarC_Syntax_DsEnv.qualify _env id in
             let typars1 = FStarC_Syntax_Subst.close_binders typars in
             let k1 = FStarC_Syntax_Subst.close typars1 k in
             let se =
               let uu___2 = FStarC_Ident.range_of_id id in
               let uu___3 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
               {
                 FStarC_Syntax_Syntax.sigel =
                   (FStarC_Syntax_Syntax.Sig_inductive_typ
                      {
                        FStarC_Syntax_Syntax.lid = qlid;
                        FStarC_Syntax_Syntax.us = [];
                        FStarC_Syntax_Syntax.params = typars1;
                        FStarC_Syntax_Syntax.num_uniform_params =
                          FStar_Pervasives_Native.None;
                        FStarC_Syntax_Syntax.t = k1;
                        FStarC_Syntax_Syntax.mutuals = mutuals;
                        FStarC_Syntax_Syntax.ds = [];
                        FStarC_Syntax_Syntax.injective_type_params = false
                      });
                 FStarC_Syntax_Syntax.sigrng = uu___2;
                 FStarC_Syntax_Syntax.sigquals = quals1;
                 FStarC_Syntax_Syntax.sigmeta =
                   FStarC_Syntax_Syntax.default_sigmeta;
                 FStarC_Syntax_Syntax.sigattrs = d_attrs;
                 FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___3;
                 FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
               } in
             let uu___2 =
               FStarC_Syntax_DsEnv.push_top_level_rec_binding _env id in
             (match uu___2 with
              | (_env1, uu___3) ->
                  let uu___4 =
                    FStarC_Syntax_DsEnv.push_top_level_rec_binding _env' id in
                  (match uu___4 with
                   | (_env2, uu___5) -> (_env1, _env2, se, tconstr))))
    | uu___1 -> failwith "Unexpected tycon" in
  let push_tparams env1 bs =
    let uu___ =
      FStarC_List.fold_left
        (fun uu___1 b ->
           match uu___1 with
           | (env2, tps) ->
               let uu___2 =
                 FStarC_Syntax_DsEnv.push_bv env2
                   (b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.ppname in
               (match uu___2 with
                | (env3, y) ->
                    let uu___3 =
                      let uu___4 =
                        mk_binder_with_attrs y
                          b.FStarC_Syntax_Syntax.binder_qual
                          b.FStarC_Syntax_Syntax.binder_attrs in
                      uu___4 :: tps in
                    (env3, uu___3))) (env1, []) bs in
    match uu___ with | (env2, bs1) -> (env2, (FStarC_List.rev bs1)) in
  match tcs1 with
  | (FStarC_Parser_AST.TyconAbstract (id, bs, kopt), d_attrs)::[] ->
      let kopt1 =
        match kopt with
        | FStar_Pervasives_Native.None ->
            let uu___ =
              let uu___1 = FStarC_Ident.range_of_id id in tm_type_z uu___1 in
            FStar_Pervasives_Native.Some uu___
        | uu___ -> kopt in
      let tc = FStarC_Parser_AST.TyconAbstract (id, bs, kopt1) in
      let uu___ = desugar_abstract_tc quals env [] d_attrs tc in
      (match uu___ with
       | (uu___1, uu___2, se, uu___3) ->
           let se1 =
             match se.FStarC_Syntax_Syntax.sigel with
             | FStarC_Syntax_Syntax.Sig_inductive_typ
                 { FStarC_Syntax_Syntax.lid = l;
                   FStarC_Syntax_Syntax.us = uu___4;
                   FStarC_Syntax_Syntax.params = typars;
                   FStarC_Syntax_Syntax.num_uniform_params = uu___5;
                   FStarC_Syntax_Syntax.t = k;
                   FStarC_Syntax_Syntax.mutuals = [];
                   FStarC_Syntax_Syntax.ds = [];
                   FStarC_Syntax_Syntax.injective_type_params = uu___6;_}
                 ->
                 let quals1 = se.FStarC_Syntax_Syntax.sigquals in
                 let quals2 =
                   if
                     FStarC_List.contains FStarC_Syntax_Syntax.Assumption
                       quals1
                   then quals1
                   else
                     ((let uu___9 =
                         let uu___10 = FStarC_Options.ml_ish () in
                         Prims.op_Negation uu___10 in
                       if uu___9
                       then
                         let uu___10 =
                           let uu___11 =
                             FStarC_Class_Show.show
                               FStarC_Ident.showable_lident l in
                           FStarC_Format.fmt1
                             "Adding an implicit 'assume new' qualifier on %s"
                             uu___11 in
                         FStarC_Errors.log_issue
                           FStarC_Syntax_Syntax.has_range_sigelt se
                           FStarC_Errors_Codes.Warning_AddImplicitAssumeNewQualifier
                           ()
                           (Obj.magic
                              FStarC_Errors_Msg.is_error_message_string)
                           (Obj.magic uu___10)
                       else ());
                      FStarC_Syntax_Syntax.Assumption
                      ::
                      FStarC_Syntax_Syntax.New
                      ::
                      quals1) in
                 let t =
                   match typars with
                   | [] -> k
                   | uu___7 ->
                       let uu___8 =
                         let uu___9 =
                           let uu___10 = FStarC_Syntax_Syntax.mk_Total k in
                           {
                             FStarC_Syntax_Syntax.bs1 = typars;
                             FStarC_Syntax_Syntax.comp = uu___10
                           } in
                         FStarC_Syntax_Syntax.Tm_arrow uu___9 in
                       FStarC_Syntax_Syntax.mk uu___8
                         se.FStarC_Syntax_Syntax.sigrng in
                 {
                   FStarC_Syntax_Syntax.sigel =
                     (FStarC_Syntax_Syntax.Sig_declare_typ
                        {
                          FStarC_Syntax_Syntax.lid2 = l;
                          FStarC_Syntax_Syntax.us2 = [];
                          FStarC_Syntax_Syntax.t2 = t
                        });
                   FStarC_Syntax_Syntax.sigrng =
                     (se.FStarC_Syntax_Syntax.sigrng);
                   FStarC_Syntax_Syntax.sigquals = quals2;
                   FStarC_Syntax_Syntax.sigmeta =
                     (se.FStarC_Syntax_Syntax.sigmeta);
                   FStarC_Syntax_Syntax.sigattrs =
                     (se.FStarC_Syntax_Syntax.sigattrs);
                   FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                     (se.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
                   FStarC_Syntax_Syntax.sigopts =
                     (se.FStarC_Syntax_Syntax.sigopts)
                 }
             | uu___4 -> failwith "Impossible" in
           let env1 = FStarC_Syntax_DsEnv.push_sigelt env se1 in
           (env1, [se1]))
  | (FStarC_Parser_AST.TyconAbbrev (id, binders, kopt, t), _d_attrs)::[] ->
      let uu___ = typars_of_binders env binders in
      (match uu___ with
       | (env', typars) ->
           let kopt1 =
             match kopt with
             | FStar_Pervasives_Native.None ->
                 let uu___1 =
                   FStarC_Util.for_some
                     (fun uu___2 ->
                        match uu___2 with
                        | FStarC_Syntax_Syntax.Effect -> true
                        | uu___3 -> false) quals in
                 if uu___1
                 then FStar_Pervasives_Native.Some FStarC_Syntax_Syntax.teff
                 else FStar_Pervasives_Native.None
             | FStar_Pervasives_Native.Some k ->
                 let uu___1 = desugar_term env' k in
                 FStar_Pervasives_Native.Some uu___1 in
           let t0 = t in
           let quals1 =
             let uu___1 =
               FStarC_Util.for_some
                 (fun uu___2 ->
                    match uu___2 with
                    | FStarC_Syntax_Syntax.Logic -> true
                    | uu___3 -> false) quals in
             if uu___1
             then quals
             else
               if t0.FStarC_Parser_AST.level = FStarC_Parser_AST.Formula
               then FStarC_Syntax_Syntax.Logic :: quals
               else quals in
           let qlid = FStarC_Syntax_DsEnv.qualify env id in
           let se =
             if FStarC_List.contains FStarC_Syntax_Syntax.Effect quals1
             then
               let uu___1 =
                 let uu___2 =
                   let uu___3 = unparen t in uu___3.FStarC_Parser_AST.tm in
                 match uu___2 with
                 | FStarC_Parser_AST.Construct (head, args) ->
                     let uu___3 =
                       match FStarC_List.rev args with
                       | (last_arg, uu___4)::args_rev ->
                           let uu___5 =
                             let uu___6 = unparen last_arg in
                             uu___6.FStarC_Parser_AST.tm in
                           (match uu___5 with
                            | FStarC_Parser_AST.Attributes ts ->
                                (ts, (FStarC_List.rev args_rev))
                            | uu___6 -> ([], args))
                       | uu___4 -> ([], args) in
                     (match uu___3 with
                      | (cattributes, args1) ->
                          let uu___4 =
                            FStarC_Parser_AST.mk_term
                              (FStarC_Parser_AST.Construct (head, args1))
                              t.FStarC_Parser_AST.range
                              t.FStarC_Parser_AST.level in
                          let uu___5 = desugar_attributes env cattributes in
                          (uu___4, uu___5))
                 | uu___3 -> (t, []) in
               match uu___1 with
               | (t1, cattributes) ->
                   let c =
                     desugar_comp t1.FStarC_Parser_AST.range false env' t1 in
                   let typars1 = FStarC_Syntax_Subst.close_binders typars in
                   let c1 = FStarC_Syntax_Subst.close_comp typars1 c in
                   let quals2 =
                     FStarC_List.filter
                       (fun uu___2 ->
                          match uu___2 with
                          | FStarC_Syntax_Syntax.Effect -> false
                          | uu___3 -> true) quals1 in
                   let uu___2 =
                     let uu___3 =
                       let uu___4 =
                         let uu___5 = FStarC_Syntax_Util.comp_flags c1 in
                         FStarC_List.op_At cattributes uu___5 in
                       {
                         FStarC_Syntax_Syntax.lid4 = qlid;
                         FStarC_Syntax_Syntax.us4 = [];
                         FStarC_Syntax_Syntax.bs2 = typars1;
                         FStarC_Syntax_Syntax.comp1 = c1;
                         FStarC_Syntax_Syntax.cflags = uu___4
                       } in
                     FStarC_Syntax_Syntax.Sig_effect_abbrev uu___3 in
                   let uu___3 = FStarC_Ident.range_of_id id in
                   let uu___4 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
                   {
                     FStarC_Syntax_Syntax.sigel = uu___2;
                     FStarC_Syntax_Syntax.sigrng = uu___3;
                     FStarC_Syntax_Syntax.sigquals = quals2;
                     FStarC_Syntax_Syntax.sigmeta =
                       FStarC_Syntax_Syntax.default_sigmeta;
                     FStarC_Syntax_Syntax.sigattrs = [];
                     FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___4;
                     FStarC_Syntax_Syntax.sigopts =
                       FStar_Pervasives_Native.None
                   }
             else
               (let t1 = desugar_typ env' t in
                let uu___2 = FStarC_Ident.range_of_id id in
                mk_typ_abbrev env d qlid [] typars kopt1 t1 [qlid] quals1
                  uu___2) in
           let env1 = FStarC_Syntax_DsEnv.push_sigelt env se in (env1, [se]))
  | (FStarC_Parser_AST.TyconRecord payload, d_attrs)::[] ->
      let trec = FStarC_Parser_AST.TyconRecord payload in
      let uu___ = tycon_record_as_variant trec in
      (match uu___ with
       | (t, fs) ->
           let uu___1 =
             let uu___2 =
               let uu___3 =
                 let uu___4 =
                   let uu___5 = FStarC_Syntax_DsEnv.current_module env in
                   FStarC_Ident.ids_of_lid uu___5 in
                 (uu___4, fs) in
               FStarC_Syntax_Syntax.RecordType uu___3 in
             uu___2 :: quals in
           desugar_tycon env d d_attrs uu___1 [t])
  | uu___::uu___1 ->
      let env0 = env in
      let mutuals =
        FStarC_List.map
          (fun uu___2 ->
             match uu___2 with
             | (x, uu___3) -> FStarC_Syntax_DsEnv.qualify env (tycon_id x))
          tcs1 in
      let rec collect_tcs quals1 et uu___2 =
        match uu___2 with
        | (tc, d_attrs) ->
            let uu___3 = et in
            (match uu___3 with
             | (env1, tcs2) ->
                 (match tc with
                  | FStarC_Parser_AST.TyconRecord uu___4 ->
                      let trec = tc in
                      let uu___5 = tycon_record_as_variant trec in
                      (match uu___5 with
                       | (t, fs) ->
                           let uu___6 =
                             let uu___7 =
                               let uu___8 =
                                 let uu___9 =
                                   let uu___10 =
                                     FStarC_Syntax_DsEnv.current_module env1 in
                                   FStarC_Ident.ids_of_lid uu___10 in
                                 (uu___9, fs) in
                               FStarC_Syntax_Syntax.RecordType uu___8 in
                             uu___7 :: quals1 in
                           collect_tcs uu___6 (env1, tcs2) (t, d_attrs))
                  | FStarC_Parser_AST.TyconVariant
                      (id, binders, kopt, constructors) ->
                      let uu___4 =
                        desugar_abstract_tc quals1 env1 mutuals d_attrs
                          (FStarC_Parser_AST.TyconAbstract
                             (id, binders, kopt)) in
                      (match uu___4 with
                       | (env2, uu___5, se, tconstr) ->
                           (env2,
                             (((FStar_Pervasives.Inl
                                  (se, constructors, tconstr, quals1)),
                                d_attrs) :: tcs2)))
                  | FStarC_Parser_AST.TyconAbbrev (id, binders, kopt, t) ->
                      let uu___4 =
                        desugar_abstract_tc quals1 env1 mutuals d_attrs
                          (FStarC_Parser_AST.TyconAbstract
                             (id, binders, kopt)) in
                      (match uu___4 with
                       | (env2, uu___5, se, tconstr) ->
                           (env2,
                             (((FStar_Pervasives.Inr (se, binders, t, quals1)),
                                d_attrs) :: tcs2)))
                  | uu___4 ->
                      FStarC_Errors.raise_error
                        FStarC_Class_HasRange.hasRange_range rng
                        FStarC_Errors_Codes.Fatal_NonInductiveInMutuallyDefinedType
                        ()
                        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                        (Obj.magic
                           "Mutually defined type contains a non-inductive element"))) in
      let uu___2 = FStarC_List.fold_left (collect_tcs quals) (env, []) tcs1 in
      (match uu___2 with
       | (env1, tcs2) ->
           let tcs3 = FStarC_List.rev tcs2 in
           let tps_sigelts =
             FStarC_List.collect
               (fun uu___3 ->
                  match uu___3 with
                  | (tc, d_attrs) ->
                      (match tc with
                       | FStar_Pervasives.Inr
                           ({
                              FStarC_Syntax_Syntax.sigel =
                                FStarC_Syntax_Syntax.Sig_inductive_typ
                                { FStarC_Syntax_Syntax.lid = id;
                                  FStarC_Syntax_Syntax.us = uvs;
                                  FStarC_Syntax_Syntax.params = tpars;
                                  FStarC_Syntax_Syntax.num_uniform_params =
                                    uu___4;
                                  FStarC_Syntax_Syntax.t = k;
                                  FStarC_Syntax_Syntax.mutuals = uu___5;
                                  FStarC_Syntax_Syntax.ds = uu___6;
                                  FStarC_Syntax_Syntax.injective_type_params
                                    = uu___7;_};
                              FStarC_Syntax_Syntax.sigrng = uu___8;
                              FStarC_Syntax_Syntax.sigquals = uu___9;
                              FStarC_Syntax_Syntax.sigmeta = uu___10;
                              FStarC_Syntax_Syntax.sigattrs = uu___11;
                              FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                                uu___12;
                              FStarC_Syntax_Syntax.sigopts = uu___13;_},
                            binders, t, quals1)
                           ->
                           let t1 =
                             let uu___14 = typars_of_binders env1 binders in
                             match uu___14 with
                             | (env2, tpars1) ->
                                 let uu___15 = push_tparams env2 tpars1 in
                                 (match uu___15 with
                                  | (env_tps, tpars2) ->
                                      let t2 = desugar_typ env_tps t in
                                      let tpars3 =
                                        FStarC_Syntax_Subst.close_binders
                                          tpars2 in
                                      FStarC_Syntax_Subst.close tpars3 t2) in
                           let uu___14 =
                             let uu___15 =
                               let uu___16 = FStarC_Ident.range_of_lid id in
                               mk_typ_abbrev env1 d id uvs tpars
                                 (FStar_Pervasives_Native.Some k) t1 
                                 [id] quals1 uu___16 in
                             ([], uu___15) in
                           [uu___14]
                       | FStar_Pervasives.Inl
                           ({
                              FStarC_Syntax_Syntax.sigel =
                                FStarC_Syntax_Syntax.Sig_inductive_typ
                                { FStarC_Syntax_Syntax.lid = tname;
                                  FStarC_Syntax_Syntax.us = univs;
                                  FStarC_Syntax_Syntax.params = tpars;
                                  FStarC_Syntax_Syntax.num_uniform_params =
                                    num_uniform;
                                  FStarC_Syntax_Syntax.t = k;
                                  FStarC_Syntax_Syntax.mutuals = mutuals1;
                                  FStarC_Syntax_Syntax.ds = uu___4;
                                  FStarC_Syntax_Syntax.injective_type_params
                                    = injective_type_params;_};
                              FStarC_Syntax_Syntax.sigrng = uu___5;
                              FStarC_Syntax_Syntax.sigquals = tname_quals;
                              FStarC_Syntax_Syntax.sigmeta = uu___6;
                              FStarC_Syntax_Syntax.sigattrs = uu___7;
                              FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                                uu___8;
                              FStarC_Syntax_Syntax.sigopts = uu___9;_},
                            constrs, tconstr, quals1)
                           ->
                           let mk_tot t =
                             let tot1 =
                               FStarC_Parser_AST.mk_term
                                 (FStarC_Parser_AST.Name
                                    FStarC_Parser_Const.effect_Tot_lid)
                                 t.FStarC_Parser_AST.range
                                 t.FStarC_Parser_AST.level in
                             FStarC_Parser_AST.mk_term
                               (FStarC_Parser_AST.App
                                  (tot1, t, FStarC_Parser_AST.Nothing))
                               t.FStarC_Parser_AST.range
                               t.FStarC_Parser_AST.level in
                           let tycon = (tname, tpars, k) in
                           let uu___10 = push_tparams env1 tpars in
                           (match uu___10 with
                            | (env_tps, tps) ->
                                let data_tpars =
                                  FStarC_List.map
                                    (fun tp ->
                                       {
                                         FStarC_Syntax_Syntax.binder_bv =
                                           (tp.FStarC_Syntax_Syntax.binder_bv);
                                         FStarC_Syntax_Syntax.binder_qual =
                                           (FStar_Pervasives_Native.Some
                                              (FStarC_Syntax_Syntax.Implicit
                                                 true));
                                         FStarC_Syntax_Syntax.binder_positivity
                                           =
                                           (tp.FStarC_Syntax_Syntax.binder_positivity);
                                         FStarC_Syntax_Syntax.binder_attrs =
                                           (tp.FStarC_Syntax_Syntax.binder_attrs)
                                       }) tps in
                                let tot_tconstr = mk_tot tconstr in
                                let val_attrs =
                                  let uu___11 =
                                    FStarC_Syntax_DsEnv.lookup_letbinding_quals_and_attrs
                                      env0 tname in
                                  FStar_Pervasives_Native.snd uu___11 in
                                let uu___11 =
                                  let uu___12 =
                                    FStarC_List.map
                                      (fun uu___13 ->
                                         match uu___13 with
                                         | (id, payload, cons_attrs) ->
                                             let t =
                                               match payload with
                                               | FStar_Pervasives_Native.Some
                                                   (FStarC_Parser_AST.VpArbitrary
                                                   t1) -> t1
                                               | FStar_Pervasives_Native.Some
                                                   (FStarC_Parser_AST.VpOfNotation
                                                   t1) ->
                                                   let uu___14 =
                                                     let uu___15 =
                                                       let uu___16 =
                                                         let uu___17 =
                                                           FStarC_Parser_AST.mk_binder
                                                             (FStarC_Parser_AST.NoName
                                                                t1)
                                                             t1.FStarC_Parser_AST.range
                                                             t1.FStarC_Parser_AST.level
                                                             FStar_Pervasives_Native.None in
                                                         [uu___17] in
                                                       (uu___16, tot_tconstr) in
                                                     FStarC_Parser_AST.Product
                                                       uu___15 in
                                                   FStarC_Parser_AST.mk_term
                                                     uu___14
                                                     t1.FStarC_Parser_AST.range
                                                     t1.FStarC_Parser_AST.level
                                               | FStar_Pervasives_Native.Some
                                                   (FStarC_Parser_AST.VpRecord
                                                   uu___14) ->
                                                   failwith
                                                     "Impossible: [VpRecord _] should have disappeared after [desugar_tycon_variant_record]"
                                               | FStar_Pervasives_Native.None
                                                   ->
                                                   let uu___14 =
                                                     FStarC_Ident.range_of_id
                                                       id in
                                                   {
                                                     FStarC_Parser_AST.tm =
                                                       (tconstr.FStarC_Parser_AST.tm);
                                                     FStarC_Parser_AST.range
                                                       = uu___14;
                                                     FStarC_Parser_AST.level
                                                       =
                                                       (tconstr.FStarC_Parser_AST.level)
                                                   } in
                                             let t1 =
                                               let uu___14 =
                                                 FStarC_ToSyntax_TickedVars.close
                                                   env_tps t in
                                               desugar_term env_tps uu___14 in
                                             let name =
                                               FStarC_Syntax_DsEnv.qualify
                                                 env1 id in
                                             let quals2 =
                                               FStarC_List.collect
                                                 (fun uu___14 ->
                                                    match uu___14 with
                                                    | FStarC_Syntax_Syntax.RecordType
                                                        fns ->
                                                        [FStarC_Syntax_Syntax.RecordConstructor
                                                           fns]
                                                    | uu___15 -> [])
                                                 tname_quals in
                                             let ntps =
                                               FStarC_List.length data_tpars in
                                             let t2 =
                                               FStarC_Syntax_Util.name_function_binders
                                                 t1 in
                                             let proj_names =
                                               let uu___14 =
                                                 FStarC_Syntax_Util.arrow_formals
                                                   t2 in
                                               match uu___14 with
                                               | (bs, c) ->
                                                   FStarC_List.mapi
                                                     (fun i b ->
                                                        FStarC_Syntax_Util.mk_field_projector_name
                                                          name
                                                          b.FStarC_Syntax_Syntax.binder_bv
                                                          i) bs in
                                             let uu___14 =
                                               let uu___15 =
                                                 let uu___16 =
                                                   let uu___17 =
                                                     let uu___18 =
                                                       let uu___19 =
                                                         FStarC_Syntax_Syntax.mk_Total
                                                           t2 in
                                                       FStarC_Syntax_Util.arrow
                                                         data_tpars uu___19 in
                                                     let uu___19 =
                                                       let uu___20 =
                                                         let uu___21 =
                                                           FStarC_Syntax_Util.mk_discriminator
                                                             name in
                                                         [uu___21] in
                                                       FStarC_List.op_At
                                                         uu___20 proj_names in
                                                     {
                                                       FStarC_Syntax_Syntax.lid1
                                                         = name;
                                                       FStarC_Syntax_Syntax.us1
                                                         = univs;
                                                       FStarC_Syntax_Syntax.t1
                                                         = uu___18;
                                                       FStarC_Syntax_Syntax.ty_lid
                                                         = tname;
                                                       FStarC_Syntax_Syntax.num_ty_params
                                                         = ntps;
                                                       FStarC_Syntax_Syntax.mutuals1
                                                         = mutuals1;
                                                       FStarC_Syntax_Syntax.injective_type_params1
                                                         =
                                                         injective_type_params;
                                                       FStarC_Syntax_Syntax.proj_disc_lids
                                                         = uu___19
                                                     } in
                                                   FStarC_Syntax_Syntax.Sig_datacon
                                                     uu___17 in
                                                 let uu___17 =
                                                   FStarC_Ident.range_of_lid
                                                     name in
                                                 let uu___18 =
                                                   let uu___19 =
                                                     let uu___20 =
                                                       let uu___21 =
                                                         FStarC_List.map
                                                           (desugar_term env1)
                                                           cons_attrs in
                                                       FStarC_List.op_At
                                                         d_attrs uu___21 in
                                                     FStarC_List.op_At
                                                       val_attrs uu___20 in
                                                   FStarC_Syntax_Util.deduplicate_terms
                                                     uu___19 in
                                                 let uu___19 =
                                                   FStarC_Syntax_DsEnv.opens_and_abbrevs
                                                     env1 in
                                                 {
                                                   FStarC_Syntax_Syntax.sigel
                                                     = uu___16;
                                                   FStarC_Syntax_Syntax.sigrng
                                                     = uu___17;
                                                   FStarC_Syntax_Syntax.sigquals
                                                     = quals2;
                                                   FStarC_Syntax_Syntax.sigmeta
                                                     =
                                                     FStarC_Syntax_Syntax.default_sigmeta;
                                                   FStarC_Syntax_Syntax.sigattrs
                                                     = uu___18;
                                                   FStarC_Syntax_Syntax.sigopens_and_abbrevs
                                                     = uu___19;
                                                   FStarC_Syntax_Syntax.sigopts
                                                     =
                                                     FStar_Pervasives_Native.None
                                                 } in
                                               (tps, uu___15) in
                                             (name, uu___14)) constrs in
                                  FStarC_List.split uu___12 in
                                (match uu___11 with
                                 | (constrNames, constrs1) ->
                                     ((let uu___13 =
                                         FStarC_Effect.op_Bang dbg_attrs in
                                       if uu___13
                                       then
                                         let uu___14 =
                                           FStarC_Class_Show.show
                                             FStarC_Ident.showable_lident
                                             tname in
                                         let uu___15 =
                                           FStarC_Class_Show.show
                                             (FStarC_Class_Show.show_list
                                                FStarC_Syntax_Print.showable_term)
                                             val_attrs in
                                         let uu___16 =
                                           FStarC_Class_Show.show
                                             (FStarC_Class_Show.show_list
                                                FStarC_Syntax_Print.showable_term)
                                             d_attrs in
                                         FStarC_Format.print3
                                           "Adding attributes to type %s: val_attrs=[@@%s] attrs=[@@%s]\n"
                                           uu___14 uu___15 uu___16
                                       else ());
                                      (let uu___13 =
                                         let uu___14 =
                                           let uu___15 =
                                             FStarC_Ident.range_of_lid tname in
                                           let uu___16 =
                                             FStarC_Syntax_Util.deduplicate_terms
                                               (FStarC_List.op_At val_attrs
                                                  d_attrs) in
                                           let uu___17 =
                                             FStarC_Syntax_DsEnv.opens_and_abbrevs
                                               env1 in
                                           {
                                             FStarC_Syntax_Syntax.sigel =
                                               (FStarC_Syntax_Syntax.Sig_inductive_typ
                                                  {
                                                    FStarC_Syntax_Syntax.lid
                                                      = tname;
                                                    FStarC_Syntax_Syntax.us =
                                                      univs;
                                                    FStarC_Syntax_Syntax.params
                                                      = tpars;
                                                    FStarC_Syntax_Syntax.num_uniform_params
                                                      = num_uniform;
                                                    FStarC_Syntax_Syntax.t =
                                                      k;
                                                    FStarC_Syntax_Syntax.mutuals
                                                      = mutuals1;
                                                    FStarC_Syntax_Syntax.ds =
                                                      constrNames;
                                                    FStarC_Syntax_Syntax.injective_type_params
                                                      = injective_type_params
                                                  });
                                             FStarC_Syntax_Syntax.sigrng =
                                               uu___15;
                                             FStarC_Syntax_Syntax.sigquals =
                                               tname_quals;
                                             FStarC_Syntax_Syntax.sigmeta =
                                               FStarC_Syntax_Syntax.default_sigmeta;
                                             FStarC_Syntax_Syntax.sigattrs =
                                               uu___16;
                                             FStarC_Syntax_Syntax.sigopens_and_abbrevs
                                               = uu___17;
                                             FStarC_Syntax_Syntax.sigopts =
                                               FStar_Pervasives_Native.None
                                           } in
                                         ([], uu___14) in
                                       uu___13 :: constrs1))))
                       | uu___4 -> failwith "impossible")) tcs3 in
           let sigelts =
             FStarC_List.map
               (fun uu___3 -> match uu___3 with | (uu___4, se) -> se)
               tps_sigelts in
           let uu___3 =
             let uu___4 =
               FStarC_List.collect FStarC_Syntax_Util.lids_of_sigelt sigelts in
             FStarC_Syntax_MutRecTy.disentangle_abbrevs_from_bundle sigelts
               quals uu___4 rng in
           (match uu___3 with
            | (bundle, abbrevs) ->
                ((let uu___5 = FStarC_Effect.op_Bang dbg_attrs in
                  if uu___5
                  then
                    let uu___6 =
                      FStarC_Class_Show.show
                        FStarC_Syntax_Print.showable_sigelt bundle in
                    FStarC_Format.print1 "After disentangling: %s\n" uu___6
                  else ());
                 (let env2 = FStarC_Syntax_DsEnv.push_sigelt env0 bundle in
                  let env3 =
                    FStarC_List.fold_left FStarC_Syntax_DsEnv.push_sigelt
                      env2 abbrevs in
                  (env3, (FStarC_List.op_At [bundle] abbrevs))))))
  | [] -> failwith "impossible"
let desugar_binders (env : FStarC_Syntax_DsEnv.env)
  (binders : FStarC_Parser_AST.binder Prims.list) :
  (FStarC_Syntax_DsEnv.env * FStarC_Syntax_Syntax.binder Prims.list)=
  let uu___ =
    FStarC_List.fold_left
      (fun uu___1 b ->
         match uu___1 with
         | (env1, binders1) ->
             let uu___2 = desugar_binder env1 b in
             (match uu___2 with
              | (FStar_Pervasives_Native.Some a, k, attrs) ->
                  let uu___3 =
                    as_binder env1 b.FStarC_Parser_AST.aqual
                      ((FStar_Pervasives_Native.Some a), k, attrs) in
                  (match uu___3 with
                   | (binder, env2) -> (env2, (binder :: binders1)))
              | uu___3 ->
                  FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_binder
                    b FStarC_Errors_Codes.Fatal_MissingNameInBinder ()
                    (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                    (Obj.magic "Missing name in binder"))) (env, []) binders in
  match uu___ with | (env1, binders1) -> (env1, (FStarC_List.rev binders1))
let push_reflect_effect (env : FStarC_Syntax_DsEnv.env)
  (quals : FStarC_Syntax_Syntax.qualifier Prims.list)
  (effect_name : FStarC_Ident.lid) (range : FStarC_Range_Type.range) :
  FStarC_Syntax_DsEnv.env=
  let uu___ =
    FStarC_Util.for_some
      (fun uu___1 ->
         match uu___1 with
         | FStarC_Syntax_Syntax.Reflectable uu___2 -> true
         | uu___2 -> false) quals in
  if uu___
  then
    let monad_env =
      let uu___1 = FStarC_Ident.ident_of_lid effect_name in
      FStarC_Syntax_DsEnv.enter_monad_scope env uu___1 in
    let reflect_lid =
      let uu___1 = FStarC_Ident.id_of_text "reflect" in
      FStarC_Syntax_DsEnv.qualify monad_env uu___1 in
    let quals1 =
      [FStarC_Syntax_Syntax.Assumption;
      FStarC_Syntax_Syntax.Reflectable effect_name] in
    let refl_decl =
      let uu___1 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
      {
        FStarC_Syntax_Syntax.sigel =
          (FStarC_Syntax_Syntax.Sig_declare_typ
             {
               FStarC_Syntax_Syntax.lid2 = reflect_lid;
               FStarC_Syntax_Syntax.us2 = [];
               FStarC_Syntax_Syntax.t2 = FStarC_Syntax_Syntax.tun
             });
        FStarC_Syntax_Syntax.sigrng = range;
        FStarC_Syntax_Syntax.sigquals = quals1;
        FStarC_Syntax_Syntax.sigmeta = FStarC_Syntax_Syntax.default_sigmeta;
        FStarC_Syntax_Syntax.sigattrs = [];
        FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___1;
        FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
      } in
    FStarC_Syntax_DsEnv.push_sigelt env refl_decl
  else env
let parse_attr_with_list (warn : Prims.bool) (at : FStarC_Syntax_Syntax.term)
  (head : FStarC_Ident.lident) :
  ((Prims.int Prims.list * FStarC_Range_Type.t)
    FStar_Pervasives_Native.option * Prims.bool)=
  let warn1 uu___ =
    if warn
    then
      let uu___1 =
        let uu___2 = FStarC_Ident.string_of_lid head in
        FStarC_Format.fmt1
          "Found ill-applied '%s', argument should be a non-empty list of integer literals"
          uu___2 in
      FStarC_Errors.log_issue (FStarC_Syntax_Syntax.has_range_syntax ()) at
        FStarC_Errors_Codes.Warning_UnappliedFail ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic uu___1)
    else () in
  let uu___ = FStarC_Syntax_Util.head_and_args at in
  match uu___ with
  | (hd, args) ->
      let uu___1 =
        let uu___2 = FStarC_Syntax_Subst.compress hd in
        uu___2.FStarC_Syntax_Syntax.n in
      (match uu___1 with
       | FStarC_Syntax_Syntax.Tm_fvar fv when
           FStarC_Syntax_Syntax.fv_eq_lid fv head ->
           (match args with
            | [] ->
                ((FStar_Pervasives_Native.Some
                    ([], (at.FStarC_Syntax_Syntax.pos))), true)
            | (a1, uu___2)::[] ->
                let uu___3 =
                  FStarC_Syntax_Embeddings_Base.unembed
                    (FStarC_Syntax_Embeddings.e_list
                       FStarC_Syntax_Embeddings.e_int) a1
                    FStarC_Syntax_Embeddings_Base.id_norm_cb in
                (match uu___3 with
                 | FStar_Pervasives_Native.Some es ->
                     ((FStar_Pervasives_Native.Some
                         (es, (at.FStarC_Syntax_Syntax.pos))), true)
                 | uu___4 -> (warn1 (); (FStar_Pervasives_Native.None, true)))
            | uu___2 -> (warn1 (); (FStar_Pervasives_Native.None, true)))
       | uu___2 -> (FStar_Pervasives_Native.None, false))
let get_fail_attr1 (warn : Prims.bool) (at : FStarC_Syntax_Syntax.term) :
  (Prims.int Prims.list * FStarC_Range_Type.t * Prims.bool)
    FStar_Pervasives_Native.option=
  let rebind res b =
    match res with
    | FStar_Pervasives_Native.None -> FStar_Pervasives_Native.None
    | FStar_Pervasives_Native.Some (l, rng) ->
        FStar_Pervasives_Native.Some (l, rng, b) in
  let uu___ = parse_attr_with_list warn at FStarC_Parser_Const.fail_attr in
  match uu___ with
  | (res, matched) ->
      if matched
      then rebind res false
      else
        (let uu___2 =
           parse_attr_with_list warn at FStarC_Parser_Const.fail_lax_attr in
         match uu___2 with | (res1, uu___3) -> rebind res1 true)
let get_fail_attr (warn : Prims.bool)
  (ats : FStarC_Syntax_Syntax.term Prims.list) :
  (Prims.int Prims.list * FStarC_Range_Type.t * Prims.bool)
    FStar_Pervasives_Native.option=
  let comb f1 f2 =
    match (f1, f2) with
    | (FStar_Pervasives_Native.Some (e1, rng1, l1),
       FStar_Pervasives_Native.Some (e2, rng2, l2)) ->
        let uu___ =
          let uu___1 = FStarC_Range_Ops.union_ranges rng1 rng2 in
          ((FStarC_List.op_At e1 e2), uu___1, (l1 || l2)) in
        FStar_Pervasives_Native.Some uu___
    | (FStar_Pervasives_Native.Some x, FStar_Pervasives_Native.None) ->
        FStar_Pervasives_Native.Some x
    | (FStar_Pervasives_Native.None, FStar_Pervasives_Native.Some x) ->
        FStar_Pervasives_Native.Some x
    | uu___ -> FStar_Pervasives_Native.None in
  FStarC_List.fold_right
    (fun at acc -> let uu___ = get_fail_attr1 warn at in comb uu___ acc) ats
    FStar_Pervasives_Native.None
let lookup_effect_lid (env : FStarC_Syntax_DsEnv.env)
  (l : FStarC_Ident.lident) (r : FStarC_Range_Type.t) :
  FStarC_Syntax_Syntax.eff_decl=
  let uu___ = FStarC_Syntax_DsEnv.try_lookup_effect_defn env l in
  match uu___ with
  | FStar_Pervasives_Native.None ->
      let uu___1 =
        let uu___2 =
          let uu___3 = FStarC_Class_Show.show FStarC_Ident.showable_lident l in
          Prims.strcat uu___3 " not found" in
        Prims.strcat "Effect name " uu___2 in
      FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
        FStarC_Errors_Codes.Fatal_EffectNotFound ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic uu___1)
  | FStar_Pervasives_Native.Some l1 -> l1
let trans_pragma (env : env_t) (uu___ : FStarC_Parser_AST.pragma) :
  FStarC_Syntax_Syntax.pragma=
  match uu___ with
  | FStarC_Parser_AST.ShowOptions -> FStarC_Syntax_Syntax.ShowOptions
  | FStarC_Parser_AST.SetOptions s -> FStarC_Syntax_Syntax.SetOptions s
  | FStarC_Parser_AST.ResetOptions sopt ->
      FStarC_Syntax_Syntax.ResetOptions sopt
  | FStarC_Parser_AST.PushOptions sopt ->
      FStarC_Syntax_Syntax.PushOptions sopt
  | FStarC_Parser_AST.PopOptions -> FStarC_Syntax_Syntax.PopOptions
  | FStarC_Parser_AST.RestartSolver -> FStarC_Syntax_Syntax.RestartSolver
  | FStarC_Parser_AST.PrintEffectsGraph ->
      FStarC_Syntax_Syntax.PrintEffectsGraph
  | FStarC_Parser_AST.Check t ->
      let uu___1 = desugar_term_maybe_top true env t in
      (match uu___1 with
       | (t1, aq) -> (check_no_aq aq; FStarC_Syntax_Syntax.Check t1))
let rec desugar_effect (env : FStarC_Syntax_DsEnv.env)
  (d : FStarC_Parser_AST.decl)
  (d_attrs : FStarC_Syntax_Syntax.term Prims.list)
  (quals : FStarC_Parser_AST.qualifiers) (is_layered : Prims.bool)
  (eff_name : FStarC_Ident.ident)
  (eff_binders : FStarC_Parser_AST.binder Prims.list)
  (eff_typ : FStarC_Parser_AST.term)
  (eff_decls : FStarC_Parser_AST.decl Prims.list) :
  (FStarC_Syntax_DsEnv.env * FStarC_Syntax_Syntax.sigelt Prims.list)=
  let env0 = env in
  let monad_env = FStarC_Syntax_DsEnv.enter_monad_scope env eff_name in
  let uu___ = desugar_binders monad_env eff_binders in
  match uu___ with
  | (env1, binders) ->
      let eff_t = desugar_term env1 eff_typ in
      let num_indices =
        let uu___1 =
          let uu___2 = FStarC_Syntax_Util.arrow_formals eff_t in
          FStar_Pervasives_Native.fst uu___2 in
        FStarC_List.length uu___1 in
      let for_free =
        (num_indices = Prims.int_one) && (Prims.op_Negation is_layered) in
      (if for_free
       then
         (let uu___2 =
            let uu___3 = FStarC_Ident.string_of_id eff_name in
            FStarC_Format.fmt1
              "DM4Free feature is deprecated and will be removed soon, use layered effects to define %s"
              uu___3 in
          FStarC_Errors.log_issue FStarC_Parser_AST.hasRange_decl d
            FStarC_Errors_Codes.Warning_DeprecatedGeneric ()
            (Obj.magic FStarC_Errors_Msg.is_error_message_string)
            (Obj.magic uu___2))
       else ();
       (let mandatory_members =
          let rr_members = ["repr"; "return"; "bind"] in
          if for_free
          then rr_members
          else
            if is_layered
            then
              FStarC_List.op_At rr_members
                ["subcomp"; "if_then_else"; "close"]
            else
              FStarC_List.op_At rr_members
                ["return_wp";
                "bind_wp";
                "if_then_else";
                "ite_wp";
                "stronger";
                "close_wp";
                "trivial"] in
        let name_of_eff_decl decl =
          match decl.FStarC_Parser_AST.d with
          | FStarC_Parser_AST.Tycon
              (uu___2, uu___3, (FStarC_Parser_AST.TyconAbbrev
               (name, uu___4, uu___5, uu___6))::[])
              -> FStarC_Ident.string_of_id name
          | uu___2 -> failwith "Malformed effect member declaration." in
        let uu___2 =
          FStarC_List.partition
            (fun decl ->
               let uu___3 = name_of_eff_decl decl in
               FStarC_List.mem uu___3 mandatory_members) eff_decls in
        match uu___2 with
        | (mandatory_members_decls, actions) ->
            let uu___3 =
              FStarC_List.fold_left
                (fun uu___4 decl ->
                   match uu___4 with
                   | (env2, out) ->
                       let uu___5 = desugar_decl env2 decl in
                       (match uu___5 with
                        | (env3, ses) ->
                            let uu___6 =
                              let uu___7 = FStarC_List.hd ses in uu___7 ::
                                out in
                            (env3, uu___6))) (env1, [])
                mandatory_members_decls in
            (match uu___3 with
             | (env2, decls) ->
                 let binders1 = FStarC_Syntax_Subst.close_binders binders in
                 let actions1 =
                   FStarC_List.map
                     (fun d1 ->
                        match d1.FStarC_Parser_AST.d with
                        | FStarC_Parser_AST.Tycon
                            (uu___4, uu___5, (FStarC_Parser_AST.TyconAbbrev
                             (name, action_params, uu___6,
                              {
                                FStarC_Parser_AST.tm =
                                  FStarC_Parser_AST.Construct
                                  (uu___7,
                                   (def, uu___8)::(cps_type, uu___9)::[]);
                                FStarC_Parser_AST.range = uu___10;
                                FStarC_Parser_AST.level = uu___11;_}))::[])
                            when Prims.op_Negation for_free ->
                            let uu___12 = desugar_binders env2 action_params in
                            (match uu___12 with
                             | (env3, action_params1) ->
                                 let action_params2 =
                                   FStarC_Syntax_Subst.close_binders
                                     action_params1 in
                                 let uu___13 =
                                   FStarC_Syntax_DsEnv.qualify env3 name in
                                 let uu___14 =
                                   let uu___15 = desugar_term env3 def in
                                   FStarC_Syntax_Subst.close
                                     (FStarC_List.op_At binders1
                                        action_params2) uu___15 in
                                 let uu___15 =
                                   let uu___16 = desugar_typ env3 cps_type in
                                   FStarC_Syntax_Subst.close
                                     (FStarC_List.op_At binders1
                                        action_params2) uu___16 in
                                 {
                                   FStarC_Syntax_Syntax.action_name = uu___13;
                                   FStarC_Syntax_Syntax.action_unqualified_name
                                     = name;
                                   FStarC_Syntax_Syntax.action_univs = [];
                                   FStarC_Syntax_Syntax.action_params =
                                     action_params2;
                                   FStarC_Syntax_Syntax.action_defn = uu___14;
                                   FStarC_Syntax_Syntax.action_typ = uu___15
                                 })
                        | FStarC_Parser_AST.Tycon
                            (uu___4, uu___5, (FStarC_Parser_AST.TyconAbbrev
                             (name, action_params, uu___6, defn))::[])
                            when for_free || is_layered ->
                            let uu___7 = desugar_binders env2 action_params in
                            (match uu___7 with
                             | (env3, action_params1) ->
                                 let action_params2 =
                                   FStarC_Syntax_Subst.close_binders
                                     action_params1 in
                                 let uu___8 =
                                   FStarC_Syntax_DsEnv.qualify env3 name in
                                 let uu___9 =
                                   let uu___10 = desugar_term env3 defn in
                                   FStarC_Syntax_Subst.close
                                     (FStarC_List.op_At binders1
                                        action_params2) uu___10 in
                                 {
                                   FStarC_Syntax_Syntax.action_name = uu___8;
                                   FStarC_Syntax_Syntax.action_unqualified_name
                                     = name;
                                   FStarC_Syntax_Syntax.action_univs = [];
                                   FStarC_Syntax_Syntax.action_params =
                                     action_params2;
                                   FStarC_Syntax_Syntax.action_defn = uu___9;
                                   FStarC_Syntax_Syntax.action_typ =
                                     FStarC_Syntax_Syntax.tun
                                 })
                        | uu___4 ->
                            FStarC_Errors.raise_error
                              FStarC_Parser_AST.hasRange_decl d1
                              FStarC_Errors_Codes.Fatal_MalformedActionDeclaration
                              ()
                              (Obj.magic
                                 FStarC_Errors_Msg.is_error_message_string)
                              (Obj.magic
                                 "Malformed action declaration; if this is an \"effect for free\", just provide the direct-style declaration. If this is not an \"effect for free\", please provide a pair of the definition and its cps-type with arrows inserted in the right place (see examples)."))
                     actions in
                 let eff_t1 = FStarC_Syntax_Subst.close binders1 eff_t in
                 let lookup s =
                   let l =
                     let uu___4 =
                       FStarC_Ident.mk_ident
                         (s, (d.FStarC_Parser_AST.drange)) in
                     FStarC_Syntax_DsEnv.qualify env2 uu___4 in
                   let uu___4 =
                     let uu___5 =
                       FStarC_Syntax_DsEnv.fail_or env2
                         (FStarC_Syntax_DsEnv.try_lookup_definition env2) l in
                     FStarC_Syntax_Subst.close binders1 uu___5 in
                   ([], uu___4) in
                 let mname = FStarC_Syntax_DsEnv.qualify env0 eff_name in
                 let qualifiers =
                   FStarC_List.map
                     (trans_qual d.FStarC_Parser_AST.drange
                        (FStar_Pervasives_Native.Some mname)) quals in
                 let dummy_tscheme = ([], FStarC_Syntax_Syntax.tun) in
                 let uu___4 =
                   if for_free
                   then
                     let uu___5 =
                       let uu___6 =
                         let uu___7 =
                           let uu___8 = lookup "repr" in
                           FStar_Pervasives_Native.Some uu___8 in
                         let uu___8 =
                           let uu___9 = lookup "return" in
                           FStar_Pervasives_Native.Some uu___9 in
                         let uu___9 =
                           let uu___10 = lookup "bind" in
                           FStar_Pervasives_Native.Some uu___10 in
                         {
                           FStarC_Syntax_Syntax.ret_wp = dummy_tscheme;
                           FStarC_Syntax_Syntax.bind_wp = dummy_tscheme;
                           FStarC_Syntax_Syntax.stronger = dummy_tscheme;
                           FStarC_Syntax_Syntax.if_then_else = dummy_tscheme;
                           FStarC_Syntax_Syntax.ite_wp = dummy_tscheme;
                           FStarC_Syntax_Syntax.close_wp = dummy_tscheme;
                           FStarC_Syntax_Syntax.trivial = dummy_tscheme;
                           FStarC_Syntax_Syntax.repr = uu___7;
                           FStarC_Syntax_Syntax.return_repr = uu___8;
                           FStarC_Syntax_Syntax.bind_repr = uu___9
                         } in
                       FStarC_Syntax_Syntax.DM4F_eff uu___6 in
                     ((FStarC_Syntax_Syntax.WP_eff_sig ([], eff_t1)), uu___5)
                   else
                     if is_layered
                     then
                       (let has_subcomp =
                          FStarC_List.existsb
                            (fun decl ->
                               let uu___6 = name_of_eff_decl decl in
                               uu___6 = "subcomp") eff_decls in
                        let has_if_then_else =
                          FStarC_List.existsb
                            (fun decl ->
                               let uu___6 = name_of_eff_decl decl in
                               uu___6 = "if_then_else") eff_decls in
                        let has_close =
                          FStarC_List.existsb
                            (fun decl ->
                               let uu___6 = name_of_eff_decl decl in
                               uu___6 = "close") eff_decls in
                        let to_comb uu___6 =
                          match uu___6 with
                          | (us, t) ->
                              ((us, t), dummy_tscheme,
                                FStar_Pervasives_Native.None) in
                        let uu___6 =
                          let uu___7 =
                            let uu___8 = FStarC_Syntax_Subst.compress eff_t1 in
                            uu___8.FStarC_Syntax_Syntax.n in
                          match uu___7 with
                          | FStarC_Syntax_Syntax.Tm_arrow
                              { FStarC_Syntax_Syntax.bs1 = bs;
                                FStarC_Syntax_Syntax.comp = c;_}
                              ->
                              let uu___8 = bs in
                              (match uu___8 with
                               | a::bs1 ->
                                   let uu___9 =
                                     FStarC_List.fold_left
                                       (fun uu___10 b ->
                                          match uu___10 with
                                          | (n, allow_param, bs2) ->
                                              let b_attrs =
                                                b.FStarC_Syntax_Syntax.binder_attrs in
                                              let is_param =
                                                FStarC_Syntax_Util.has_attribute
                                                  b_attrs
                                                  FStarC_Parser_Const.effect_parameter_attr in
                                              (if
                                                 is_param &&
                                                   (Prims.op_Negation
                                                      allow_param)
                                               then
                                                 FStarC_Errors.raise_error
                                                   FStarC_Parser_AST.hasRange_decl
                                                   d
                                                   FStarC_Errors_Codes.Fatal_UnexpectedEffect
                                                   ()
                                                   (Obj.magic
                                                      FStarC_Errors_Msg.is_error_message_string)
                                                   (Obj.magic
                                                      "Effect parameters must all be upfront")
                                               else ();
                                               (let b_attrs1 =
                                                  FStarC_Syntax_Util.remove_attr
                                                    FStarC_Parser_Const.effect_parameter_attr
                                                    b_attrs in
                                                ((if is_param
                                                  then n + Prims.int_one
                                                  else n),
                                                  (allow_param && is_param),
                                                  (FStarC_List.op_At bs2
                                                     [{
                                                        FStarC_Syntax_Syntax.binder_bv
                                                          =
                                                          (b.FStarC_Syntax_Syntax.binder_bv);
                                                        FStarC_Syntax_Syntax.binder_qual
                                                          =
                                                          (b.FStarC_Syntax_Syntax.binder_qual);
                                                        FStarC_Syntax_Syntax.binder_positivity
                                                          =
                                                          (b.FStarC_Syntax_Syntax.binder_positivity);
                                                        FStarC_Syntax_Syntax.binder_attrs
                                                          = b_attrs1
                                                      }])))))
                                       (Prims.int_zero, true, []) bs1 in
                                   (match uu___9 with
                                    | (n, uu___10, bs2) ->
                                        ({
                                           FStarC_Syntax_Syntax.n =
                                             (FStarC_Syntax_Syntax.Tm_arrow
                                                {
                                                  FStarC_Syntax_Syntax.bs1 =
                                                    (a :: bs2);
                                                  FStarC_Syntax_Syntax.comp =
                                                    c
                                                });
                                           FStarC_Syntax_Syntax.pos =
                                             (eff_t1.FStarC_Syntax_Syntax.pos);
                                           FStarC_Syntax_Syntax.vars =
                                             (eff_t1.FStarC_Syntax_Syntax.vars);
                                           FStarC_Syntax_Syntax.hash_code =
                                             (eff_t1.FStarC_Syntax_Syntax.hash_code)
                                         }, n)))
                          | uu___8 ->
                              failwith
                                "desugaring indexed effect: effect type not an arrow" in
                        match uu___6 with
                        | (eff_t2, num_effect_params) ->
                            let uu___7 =
                              let uu___8 =
                                let uu___9 =
                                  let uu___10 = lookup "repr" in
                                  (uu___10, dummy_tscheme) in
                                let uu___10 =
                                  let uu___11 = lookup "return" in
                                  (uu___11, dummy_tscheme) in
                                let uu___11 =
                                  let uu___12 = lookup "bind" in
                                  to_comb uu___12 in
                                let uu___12 =
                                  if has_subcomp
                                  then
                                    let uu___13 = lookup "subcomp" in
                                    to_comb uu___13
                                  else
                                    (dummy_tscheme, dummy_tscheme,
                                      FStar_Pervasives_Native.None) in
                                let uu___13 =
                                  if has_if_then_else
                                  then
                                    let uu___14 = lookup "if_then_else" in
                                    to_comb uu___14
                                  else
                                    (dummy_tscheme, dummy_tscheme,
                                      FStar_Pervasives_Native.None) in
                                let uu___14 =
                                  if has_close
                                  then
                                    let uu___15 =
                                      let uu___16 = lookup "close" in
                                      (uu___16, dummy_tscheme) in
                                    FStar_Pervasives_Native.Some uu___15
                                  else FStar_Pervasives_Native.None in
                                {
                                  FStarC_Syntax_Syntax.l_repr = uu___9;
                                  FStarC_Syntax_Syntax.l_return = uu___10;
                                  FStarC_Syntax_Syntax.l_bind = uu___11;
                                  FStarC_Syntax_Syntax.l_subcomp = uu___12;
                                  FStarC_Syntax_Syntax.l_if_then_else =
                                    uu___13;
                                  FStarC_Syntax_Syntax.l_close = uu___14
                                } in
                              FStarC_Syntax_Syntax.Layered_eff uu___8 in
                            ((FStarC_Syntax_Syntax.Layered_eff_sig
                                (num_effect_params, ([], eff_t2))), uu___7))
                     else
                       (let rr =
                          FStarC_Util.for_some
                            (fun uu___7 ->
                               match uu___7 with
                               | FStarC_Syntax_Syntax.Reifiable -> true
                               | FStarC_Syntax_Syntax.Reflectable uu___8 ->
                                   true
                               | uu___8 -> false) qualifiers in
                        let uu___7 =
                          let uu___8 =
                            let uu___9 = lookup "return_wp" in
                            let uu___10 = lookup "bind_wp" in
                            let uu___11 = lookup "stronger" in
                            let uu___12 = lookup "if_then_else" in
                            let uu___13 = lookup "ite_wp" in
                            let uu___14 = lookup "close_wp" in
                            let uu___15 = lookup "trivial" in
                            let uu___16 =
                              if rr
                              then
                                let uu___17 = lookup "repr" in
                                FStar_Pervasives_Native.Some uu___17
                              else FStar_Pervasives_Native.None in
                            let uu___17 =
                              if rr
                              then
                                let uu___18 = lookup "return" in
                                FStar_Pervasives_Native.Some uu___18
                              else FStar_Pervasives_Native.None in
                            let uu___18 =
                              if rr
                              then
                                let uu___19 = lookup "bind" in
                                FStar_Pervasives_Native.Some uu___19
                              else FStar_Pervasives_Native.None in
                            {
                              FStarC_Syntax_Syntax.ret_wp = uu___9;
                              FStarC_Syntax_Syntax.bind_wp = uu___10;
                              FStarC_Syntax_Syntax.stronger = uu___11;
                              FStarC_Syntax_Syntax.if_then_else = uu___12;
                              FStarC_Syntax_Syntax.ite_wp = uu___13;
                              FStarC_Syntax_Syntax.close_wp = uu___14;
                              FStarC_Syntax_Syntax.trivial = uu___15;
                              FStarC_Syntax_Syntax.repr = uu___16;
                              FStarC_Syntax_Syntax.return_repr = uu___17;
                              FStarC_Syntax_Syntax.bind_repr = uu___18
                            } in
                          FStarC_Syntax_Syntax.Primitive_eff uu___8 in
                        ((FStarC_Syntax_Syntax.WP_eff_sig ([], eff_t1)),
                          uu___7)) in
                 (match uu___4 with
                  | (eff_sig, combinators) ->
                      let extraction_mode =
                        if is_layered
                        then FStarC_Syntax_Syntax.Extract_none ""
                        else
                          if for_free
                          then
                            (let uu___6 =
                               FStarC_Util.for_some
                                 (fun uu___7 ->
                                    match uu___7 with
                                    | FStarC_Syntax_Syntax.Reifiable -> true
                                    | uu___8 -> false) qualifiers in
                             if uu___6
                             then FStarC_Syntax_Syntax.Extract_reify
                             else FStarC_Syntax_Syntax.Extract_primitive)
                          else FStarC_Syntax_Syntax.Extract_primitive in
                      let sigel =
                        FStarC_Syntax_Syntax.Sig_new_effect
                          {
                            FStarC_Syntax_Syntax.mname = mname;
                            FStarC_Syntax_Syntax.cattributes = [];
                            FStarC_Syntax_Syntax.univs = [];
                            FStarC_Syntax_Syntax.binders = binders1;
                            FStarC_Syntax_Syntax.signature = eff_sig;
                            FStarC_Syntax_Syntax.combinators = combinators;
                            FStarC_Syntax_Syntax.actions = actions1;
                            FStarC_Syntax_Syntax.eff_attrs = d_attrs;
                            FStarC_Syntax_Syntax.extraction_mode =
                              extraction_mode
                          } in
                      let se =
                        let uu___5 =
                          FStarC_Syntax_DsEnv.opens_and_abbrevs env2 in
                        {
                          FStarC_Syntax_Syntax.sigel = sigel;
                          FStarC_Syntax_Syntax.sigrng =
                            (d.FStarC_Parser_AST.drange);
                          FStarC_Syntax_Syntax.sigquals = qualifiers;
                          FStarC_Syntax_Syntax.sigmeta =
                            FStarC_Syntax_Syntax.default_sigmeta;
                          FStarC_Syntax_Syntax.sigattrs = d_attrs;
                          FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___5;
                          FStarC_Syntax_Syntax.sigopts =
                            FStar_Pervasives_Native.None
                        } in
                      let env3 = FStarC_Syntax_DsEnv.push_sigelt env0 se in
                      let env4 =
                        FStarC_List.fold_left
                          (fun env5 a ->
                             let uu___5 =
                               FStarC_Syntax_Util.action_as_lb mname a
                                 (a.FStarC_Syntax_Syntax.action_defn).FStarC_Syntax_Syntax.pos in
                             FStarC_Syntax_DsEnv.push_sigelt env5 uu___5)
                          env3 actions1 in
                      let env5 =
                        push_reflect_effect env4 qualifiers mname
                          d.FStarC_Parser_AST.drange in
                      (env5, [se])))))
and desugar_redefine_effect (env : FStarC_Syntax_DsEnv.env)
  (d : FStarC_Parser_AST.decl)
  (d_attrs : FStarC_Syntax_Syntax.attribute Prims.list)
  (trans_qual1 :
    FStarC_Ident.lident FStar_Pervasives_Native.option ->
      FStarC_Parser_AST.qualifier -> FStarC_Syntax_Syntax.qualifier)
  (quals : FStarC_Parser_AST.qualifier Prims.list)
  (eff_name : FStarC_Ident.ident)
  (eff_binders : FStarC_Parser_AST.binder Prims.list)
  (defn : FStarC_Parser_AST.term) :
  (FStarC_Syntax_DsEnv.env * FStarC_Syntax_Syntax.sigelt Prims.list)=
  let env0 = env in
  let env1 = FStarC_Syntax_DsEnv.enter_monad_scope env eff_name in
  let uu___ = desugar_binders env1 eff_binders in
  match uu___ with
  | (env2, binders) ->
      let uu___1 =
        let uu___2 = head_and_args defn in
        match uu___2 with
        | (head, args) ->
            let lid =
              match head.FStarC_Parser_AST.tm with
              | FStarC_Parser_AST.Name l -> l
              | uu___3 ->
                  let uu___4 =
                    let uu___5 =
                      let uu___6 = FStarC_Parser_AST.term_to_string head in
                      Prims.strcat uu___6 " not found" in
                    Prims.strcat "Effect " uu___5 in
                  FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_decl d
                    FStarC_Errors_Codes.Fatal_EffectNotFound ()
                    (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                    (Obj.magic uu___4) in
            let ed =
              FStarC_Syntax_DsEnv.fail_or env2
                (FStarC_Syntax_DsEnv.try_lookup_effect_defn env2) lid in
            let uu___3 =
              match FStarC_List.rev args with
              | (last_arg, uu___4)::args_rev ->
                  let uu___5 =
                    let uu___6 = unparen last_arg in
                    uu___6.FStarC_Parser_AST.tm in
                  (match uu___5 with
                   | FStarC_Parser_AST.Attributes ts ->
                       (ts, (FStarC_List.rev args_rev))
                   | uu___6 -> ([], args))
              | uu___4 -> ([], args) in
            (match uu___3 with
             | (cattributes, args1) ->
                 let uu___4 = desugar_args env2 args1 in
                 let uu___5 = desugar_attributes env2 cattributes in
                 (lid, ed, uu___4, uu___5)) in
      (match uu___1 with
       | (ed_lid, ed, args, cattributes) ->
           let binders1 = FStarC_Syntax_Subst.close_binders binders in
           (if
              (FStarC_List.length args) <>
                (FStarC_List.length ed.FStarC_Syntax_Syntax.binders)
            then
              FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_term defn
                FStarC_Errors_Codes.Fatal_ArgumentLengthMismatch ()
                (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                (Obj.magic
                   "Unexpected number of arguments to effect constructor")
            else ();
            (let uu___3 =
               FStarC_Syntax_Subst.open_term' ed.FStarC_Syntax_Syntax.binders
                 FStarC_Syntax_Syntax.t_unit in
             match uu___3 with
             | (ed_binders, uu___4, ed_binders_opening) ->
                 let sub' shift_n uu___5 =
                   match uu___5 with
                   | (us, x) ->
                       let x1 =
                         let uu___6 =
                           FStarC_Syntax_Subst.shift_subst
                             (shift_n + (FStarC_List.length us))
                             ed_binders_opening in
                         FStarC_Syntax_Subst.subst uu___6 x in
                       let s =
                         FStarC_Syntax_Util.subst_of_list ed_binders args in
                       let uu___6 =
                         let uu___7 = FStarC_Syntax_Subst.subst s x1 in
                         (us, uu___7) in
                       FStarC_Syntax_Subst.close_tscheme binders1 uu___6 in
                 let sub = sub' Prims.int_zero in
                 let mname = FStarC_Syntax_DsEnv.qualify env0 eff_name in
                 let ed1 =
                   let uu___5 =
                     FStarC_Syntax_Util.apply_eff_sig sub
                       ed.FStarC_Syntax_Syntax.signature in
                   let uu___6 =
                     FStarC_Syntax_Util.apply_eff_combinators sub
                       ed.FStarC_Syntax_Syntax.combinators in
                   let uu___7 =
                     FStarC_List.map
                       (fun action ->
                          let nparam =
                            FStarC_List.length
                              action.FStarC_Syntax_Syntax.action_params in
                          let uu___8 =
                            FStarC_Syntax_DsEnv.qualify env2
                              action.FStarC_Syntax_Syntax.action_unqualified_name in
                          let uu___9 =
                            let uu___10 =
                              sub' nparam
                                ([],
                                  (action.FStarC_Syntax_Syntax.action_defn)) in
                            FStar_Pervasives_Native.snd uu___10 in
                          let uu___10 =
                            let uu___11 =
                              sub' nparam
                                ([],
                                  (action.FStarC_Syntax_Syntax.action_typ)) in
                            FStar_Pervasives_Native.snd uu___11 in
                          {
                            FStarC_Syntax_Syntax.action_name = uu___8;
                            FStarC_Syntax_Syntax.action_unqualified_name =
                              (action.FStarC_Syntax_Syntax.action_unqualified_name);
                            FStarC_Syntax_Syntax.action_univs =
                              (action.FStarC_Syntax_Syntax.action_univs);
                            FStarC_Syntax_Syntax.action_params =
                              (action.FStarC_Syntax_Syntax.action_params);
                            FStarC_Syntax_Syntax.action_defn = uu___9;
                            FStarC_Syntax_Syntax.action_typ = uu___10
                          }) ed.FStarC_Syntax_Syntax.actions in
                   {
                     FStarC_Syntax_Syntax.mname = mname;
                     FStarC_Syntax_Syntax.cattributes = cattributes;
                     FStarC_Syntax_Syntax.univs =
                       (ed.FStarC_Syntax_Syntax.univs);
                     FStarC_Syntax_Syntax.binders = binders1;
                     FStarC_Syntax_Syntax.signature = uu___5;
                     FStarC_Syntax_Syntax.combinators = uu___6;
                     FStarC_Syntax_Syntax.actions = uu___7;
                     FStarC_Syntax_Syntax.eff_attrs =
                       (ed.FStarC_Syntax_Syntax.eff_attrs);
                     FStarC_Syntax_Syntax.extraction_mode =
                       (ed.FStarC_Syntax_Syntax.extraction_mode)
                   } in
                 let se =
                   let uu___5 =
                     let uu___6 =
                       trans_qual1 (FStar_Pervasives_Native.Some mname) in
                     FStarC_List.map uu___6 quals in
                   let uu___6 = FStarC_Syntax_DsEnv.opens_and_abbrevs env2 in
                   {
                     FStarC_Syntax_Syntax.sigel =
                       (FStarC_Syntax_Syntax.Sig_new_effect ed1);
                     FStarC_Syntax_Syntax.sigrng =
                       (d.FStarC_Parser_AST.drange);
                     FStarC_Syntax_Syntax.sigquals = uu___5;
                     FStarC_Syntax_Syntax.sigmeta =
                       FStarC_Syntax_Syntax.default_sigmeta;
                     FStarC_Syntax_Syntax.sigattrs = d_attrs;
                     FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___6;
                     FStarC_Syntax_Syntax.sigopts =
                       FStar_Pervasives_Native.None
                   } in
                 let monad_env = env2 in
                 let env3 = FStarC_Syntax_DsEnv.push_sigelt env0 se in
                 let env4 =
                   FStarC_List.fold_left
                     (fun env5 a ->
                        let uu___5 =
                          FStarC_Syntax_Util.action_as_lb mname a
                            (a.FStarC_Syntax_Syntax.action_defn).FStarC_Syntax_Syntax.pos in
                        FStarC_Syntax_DsEnv.push_sigelt env5 uu___5) env3
                     ed1.FStarC_Syntax_Syntax.actions in
                 let env5 =
                   if
                     FStarC_List.contains FStarC_Parser_AST.Reflectable quals
                   then
                     let reflect_lid =
                       let uu___5 = FStarC_Ident.id_of_text "reflect" in
                       FStarC_Syntax_DsEnv.qualify monad_env uu___5 in
                     let quals1 =
                       [FStarC_Syntax_Syntax.Assumption;
                       FStarC_Syntax_Syntax.Reflectable mname] in
                     let refl_decl =
                       let uu___5 =
                         FStarC_Syntax_DsEnv.opens_and_abbrevs env4 in
                       {
                         FStarC_Syntax_Syntax.sigel =
                           (FStarC_Syntax_Syntax.Sig_declare_typ
                              {
                                FStarC_Syntax_Syntax.lid2 = reflect_lid;
                                FStarC_Syntax_Syntax.us2 = [];
                                FStarC_Syntax_Syntax.t2 =
                                  FStarC_Syntax_Syntax.tun
                              });
                         FStarC_Syntax_Syntax.sigrng =
                           (d.FStarC_Parser_AST.drange);
                         FStarC_Syntax_Syntax.sigquals = quals1;
                         FStarC_Syntax_Syntax.sigmeta =
                           FStarC_Syntax_Syntax.default_sigmeta;
                         FStarC_Syntax_Syntax.sigattrs = [];
                         FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___5;
                         FStarC_Syntax_Syntax.sigopts =
                           FStar_Pervasives_Native.None
                       } in
                     FStarC_Syntax_DsEnv.push_sigelt env4 refl_decl
                   else env4 in
                 (env5, [se]))))
and desugar_decl_maybe_fail_attr (env : FStarC_Syntax_DsEnv.env)
  (d : FStarC_Parser_AST.decl) (attrs : FStarC_Syntax_Syntax.term Prims.list)
  : (env_t * FStarC_Syntax_Syntax.sigelts)=
  let no_fail_attrs ats =
    FStarC_List.filter
      (fun at ->
         let uu___ = get_fail_attr1 false at in
         FStar_Pervasives_Native.uu___is_None uu___) ats in
  let uu___ =
    let uu___1 = get_fail_attr false attrs in
    match uu___1 with
    | FStar_Pervasives_Native.Some (expected_errs, err_rng, lax) ->
        let env0 =
          let uu___2 = FStarC_Syntax_DsEnv.snapshot env in
          FStar_Pervasives_Native.snd uu___2 in
        let d1 =
          {
            FStarC_Parser_AST.d = (d.FStarC_Parser_AST.d);
            FStarC_Parser_AST.drange = (d.FStarC_Parser_AST.drange);
            FStarC_Parser_AST.quals = (d.FStarC_Parser_AST.quals);
            FStarC_Parser_AST.attrs = [];
            FStarC_Parser_AST.interleaved = (d.FStarC_Parser_AST.interleaved)
          } in
        let uu___2 =
          FStarC_Errors.catch_errors
            (fun uu___3 ->
               FStarC_Options.with_saved_options
                 (fun uu___4 -> desugar_decl_core env attrs d1)) in
        (match uu___2 with
         | (errs, r) ->
             (match (errs, r) with
              | ([], FStar_Pervasives_Native.Some (env1, ses)) ->
                  let ses1 =
                    FStarC_List.map
                      (fun se ->
                         let uu___3 = no_fail_attrs attrs in
                         {
                           FStarC_Syntax_Syntax.sigel =
                             (se.FStarC_Syntax_Syntax.sigel);
                           FStarC_Syntax_Syntax.sigrng =
                             (se.FStarC_Syntax_Syntax.sigrng);
                           FStarC_Syntax_Syntax.sigquals =
                             (se.FStarC_Syntax_Syntax.sigquals);
                           FStarC_Syntax_Syntax.sigmeta =
                             (se.FStarC_Syntax_Syntax.sigmeta);
                           FStarC_Syntax_Syntax.sigattrs = uu___3;
                           FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                             (se.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
                           FStarC_Syntax_Syntax.sigopts =
                             (se.FStarC_Syntax_Syntax.sigopts)
                         }) ses in
                  let se =
                    let uu___3 = FStarC_Syntax_DsEnv.opens_and_abbrevs env1 in
                    {
                      FStarC_Syntax_Syntax.sigel =
                        (FStarC_Syntax_Syntax.Sig_fail
                           {
                             FStarC_Syntax_Syntax.errs = expected_errs;
                             FStarC_Syntax_Syntax.rng1 = err_rng;
                             FStarC_Syntax_Syntax.fail_in_lax = lax;
                             FStarC_Syntax_Syntax.ses1 = ses1
                           });
                      FStarC_Syntax_Syntax.sigrng =
                        (d1.FStarC_Parser_AST.drange);
                      FStarC_Syntax_Syntax.sigquals = [];
                      FStarC_Syntax_Syntax.sigmeta =
                        FStarC_Syntax_Syntax.default_sigmeta;
                      FStarC_Syntax_Syntax.sigattrs = attrs;
                      FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___3;
                      FStarC_Syntax_Syntax.sigopts =
                        FStar_Pervasives_Native.None
                    } in
                  (env0, [se])
              | (errs1, ropt) ->
                  let errnos =
                    FStarC_List.concatMap
                      (fun i ->
                         FStarC_Common.list_of_option
                           i.FStarC_Errors.issue_number) errs1 in
                  ((let uu___4 = FStarC_Options.print_expected_failures () in
                    if uu___4
                    then FStarC_Errors.print_expected_failures errs1
                    else ());
                   if expected_errs = []
                   then (env0, [])
                   else
                     (let uu___5 =
                        FStarC_Errors.find_multiset_discrepancy expected_errs
                          errnos in
                      match uu___5 with
                      | FStar_Pervasives_Native.None -> (env0, [])
                      | FStar_Pervasives_Native.Some (e, n1, n2) ->
                          (FStarC_List.iter FStarC_Errors.print_issue errs1;
                           (let uu___8 =
                              let uu___9 =
                                let uu___10 =
                                  let uu___11 =
                                    FStarC_Errors_Msg.text
                                      "This top-level definition was expected to raise error codes" in
                                  let uu___12 =
                                    let uu___13 =
                                      FStarC_Class_Ord.sort
                                        FStarC_Class_Ord.ord_int
                                        expected_errs in
                                    FStarC_Class_PP.pp
                                      (FStarC_Class_PP.pp_list
                                         FStarC_Class_PP.pp_int) uu___13 in
                                  FStar_Pprint.prefix (Prims.of_int (2))
                                    Prims.int_one uu___11 uu___12 in
                                let uu___11 =
                                  let uu___12 =
                                    let uu___13 =
                                      FStarC_Errors_Msg.text "but it raised" in
                                    let uu___14 =
                                      let uu___15 =
                                        FStarC_Class_Ord.sort
                                          FStarC_Class_Ord.ord_int errnos in
                                      FStarC_Class_PP.pp
                                        (FStarC_Class_PP.pp_list
                                           FStarC_Class_PP.pp_int) uu___15 in
                                    FStar_Pprint.prefix (Prims.of_int (2))
                                      Prims.int_one uu___13 uu___14 in
                                  let uu___13 =
                                    let uu___14 =
                                      FStarC_Errors_Msg.text
                                        "(at desugaring time)" in
                                    FStar_Pprint.op_Hat_Hat uu___14
                                      FStar_Pprint.dot in
                                  FStar_Pprint.op_Hat_Slash_Hat uu___12
                                    uu___13 in
                                FStar_Pprint.op_Hat_Slash_Hat uu___10 uu___11 in
                              let uu___10 =
                                let uu___11 =
                                  let uu___12 =
                                    let uu___13 =
                                      FStarC_Class_Show.show
                                        FStarC_Class_Show.showable_int e in
                                    let uu___14 =
                                      FStarC_Class_Show.show
                                        FStarC_Class_Show.showable_int n2 in
                                    let uu___15 =
                                      FStarC_Class_Show.show
                                        FStarC_Class_Show.showable_int n1 in
                                    FStarC_Format.fmt3
                                      "Error #%s was raised %s times, instead of %s."
                                      uu___13 uu___14 uu___15 in
                                  FStarC_Errors_Msg.text uu___12 in
                                [uu___11] in
                              uu___9 :: uu___10 in
                            FStarC_Errors.log_issue
                              FStarC_Class_HasRange.hasRange_range err_rng
                              FStarC_Errors_Codes.Error_DidNotFail ()
                              (Obj.magic
                                 FStarC_Errors_Msg.is_error_message_list_doc)
                              (Obj.magic uu___8));
                           (env0, []))))))
    | FStar_Pervasives_Native.None -> desugar_decl_core env attrs d in
  match uu___ with | (env1, sigelts) -> (env1, sigelts)
and desugar_decl (env : env_t) (d : FStarC_Parser_AST.decl) :
  (env_t * FStarC_Syntax_Syntax.sigelts)=
  FStarC_GenSym.reset_gensym ();
  (let attrs = FStarC_List.map (desugar_term env) d.FStarC_Parser_AST.attrs in
   let attrs1 = FStarC_Syntax_Util.deduplicate_terms attrs in
   let uu___1 = desugar_decl_maybe_fail_attr env d attrs1 in
   match uu___1 with
   | (env1, ses) ->
       let ses1 =
         let uu___2 =
           FStarC_Syntax_Util.has_attribute attrs1
             FStarC_Parser_Const.admitted_lid in
         if uu___2
         then
           FStarC_List.map
             (fun se ->
                {
                  FStarC_Syntax_Syntax.sigel =
                    (se.FStarC_Syntax_Syntax.sigel);
                  FStarC_Syntax_Syntax.sigrng =
                    (se.FStarC_Syntax_Syntax.sigrng);
                  FStarC_Syntax_Syntax.sigquals =
                    (se.FStarC_Syntax_Syntax.sigquals);
                  FStarC_Syntax_Syntax.sigmeta =
                    (let uu___3 = se.FStarC_Syntax_Syntax.sigmeta in
                     {
                       FStarC_Syntax_Syntax.sigmeta_active =
                         (uu___3.FStarC_Syntax_Syntax.sigmeta_active);
                       FStarC_Syntax_Syntax.sigmeta_fact_db_ids =
                         (uu___3.FStarC_Syntax_Syntax.sigmeta_fact_db_ids);
                       FStarC_Syntax_Syntax.sigmeta_admit = true;
                       FStarC_Syntax_Syntax.sigmeta_spliced =
                         (uu___3.FStarC_Syntax_Syntax.sigmeta_spliced);
                       FStarC_Syntax_Syntax.sigmeta_already_checked =
                         (uu___3.FStarC_Syntax_Syntax.sigmeta_already_checked);
                       FStarC_Syntax_Syntax.sigmeta_extension_data =
                         (uu___3.FStarC_Syntax_Syntax.sigmeta_extension_data)
                     });
                  FStarC_Syntax_Syntax.sigattrs =
                    (se.FStarC_Syntax_Syntax.sigattrs);
                  FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                    (se.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
                  FStarC_Syntax_Syntax.sigopts =
                    (se.FStarC_Syntax_Syntax.sigopts)
                }) ses
         else ses in
       let uu___2 = FStarC_List.map generalize_annotated_univs ses1 in
       (env1, uu___2))
and desugar_decl_core (env : FStarC_Syntax_DsEnv.env)
  (d_attrs : FStarC_Syntax_Syntax.term Prims.list)
  (d : FStarC_Parser_AST.decl) : (env_t * FStarC_Syntax_Syntax.sigelts)=
  let trans_qual1 = trans_qual d.FStarC_Parser_AST.drange in
  match d.FStarC_Parser_AST.d with
  | FStarC_Parser_AST.Pragma p ->
      let p1 = trans_pragma env p in
      (FStarC_Syntax_Util.process_pragma p1 d.FStarC_Parser_AST.drange;
       (let se =
          let uu___1 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
          {
            FStarC_Syntax_Syntax.sigel = (FStarC_Syntax_Syntax.Sig_pragma p1);
            FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
            FStarC_Syntax_Syntax.sigquals = [];
            FStarC_Syntax_Syntax.sigmeta =
              FStarC_Syntax_Syntax.default_sigmeta;
            FStarC_Syntax_Syntax.sigattrs = d_attrs;
            FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___1;
            FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
          } in
        (env, [se])))
  | FStarC_Parser_AST.TopLevelModule id -> (env, [])
  | FStarC_Parser_AST.Open (lid, restriction) ->
      let env1 = FStarC_Syntax_DsEnv.push_namespace env lid restriction in
      (env1, [])
  | FStarC_Parser_AST.Friend lid ->
      ((let uu___1 = FStarC_Syntax_DsEnv.iface env in
        if uu___1
        then
          let uu___2 =
            let uu___3 =
              FStarC_Errors_Msg.text
                "'friend' declarations are not allowed in interfaces." in
            [uu___3] in
          FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_decl d
            FStarC_Errors_Codes.Fatal_FriendInterface ()
            (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
            (Obj.magic uu___2)
        else ());
       (let uu___2 =
          let uu___3 =
            let uu___4 = FStarC_Syntax_DsEnv.dep_graph env in
            let uu___5 = FStarC_Syntax_DsEnv.current_module env in
            FStarC_Parser_Dep.module_has_interface uu___4 uu___5 in
          Prims.op_Negation uu___3 in
        if uu___2
        then
          let uu___3 =
            let uu___4 =
              FStarC_Errors_Msg.text
                "'friend' declarations are not allowed in modules that lack interfaces." in
            let uu___5 =
              let uu___6 =
                let uu___7 =
                  FStarC_Errors_Msg.text
                    "Suggestion: add an interface for module" in
                let uu___8 =
                  let uu___9 = FStarC_Syntax_DsEnv.current_module env in
                  FStarC_Class_PP.pp FStarC_Ident.pretty_lident uu___9 in
                FStar_Pprint.op_Hat_Slash_Hat uu___7 uu___8 in
              [uu___6] in
            uu___4 :: uu___5 in
          FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_decl d
            FStarC_Errors_Codes.Fatal_FriendInterface ()
            (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
            (Obj.magic uu___3)
        else ());
       (let uu___3 =
          let uu___4 =
            let uu___5 = FStarC_Syntax_DsEnv.dep_graph env in
            FStarC_Parser_Dep.deps_has_implementation uu___5 lid in
          Prims.op_Negation uu___4 in
        if uu___3
        then
          let uu___4 =
            let uu___5 =
              let uu___6 = FStarC_Errors_Msg.text "'friend' module" in
              let uu___7 =
                let uu___8 =
                  FStarC_Class_PP.pp FStarC_Ident.pretty_lident lid in
                let uu___9 = FStarC_Errors_Msg.text "not found" in
                FStar_Pprint.op_Hat_Slash_Hat uu___8 uu___9 in
              FStar_Pprint.op_Hat_Slash_Hat uu___6 uu___7 in
            let uu___6 =
              let uu___7 =
                FStarC_Errors_Msg.text
                  "Suggestion: recompute dependences (C-c C-r) if in interactive mode." in
              [uu___7] in
            uu___5 :: uu___6 in
          FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_decl d
            FStarC_Errors_Codes.Fatal_FriendInterface ()
            (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
            (Obj.magic uu___4)
        else ());
       (let uu___4 =
          let uu___5 =
            let uu___6 = FStarC_Syntax_DsEnv.dep_graph env in
            FStarC_Parser_Dep.module_has_interface uu___6 lid in
          Prims.op_Negation uu___5 in
        if uu___4
        then
          let uu___5 =
            let uu___6 =
              FStarC_Errors_Msg.text
                "'friend' declarations cannot refer to modules that lack interfaces." in
            let uu___7 =
              let uu___8 =
                let uu___9 =
                  FStarC_Errors_Msg.text
                    "Suggestion: add an interfce for module" in
                let uu___10 =
                  FStarC_Class_PP.pp FStarC_Ident.pretty_lident lid in
                FStar_Pprint.op_Hat_Slash_Hat uu___9 uu___10 in
              [uu___8] in
            uu___6 :: uu___7 in
          FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_decl d
            FStarC_Errors_Codes.Fatal_FriendInterface ()
            (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
            (Obj.magic uu___5)
        else ());
       (env, []))
  | FStarC_Parser_AST.Include (lid, restriction) ->
      let env1 = FStarC_Syntax_DsEnv.push_include env lid restriction in
      (env1, [])
  | FStarC_Parser_AST.ModuleAbbrev (x, l) ->
      let uu___ = FStarC_Syntax_DsEnv.push_module_abbrev env x l in
      (uu___, [])
  | FStarC_Parser_AST.Tycon (is_effect, typeclass, tcs) ->
      let quals = d.FStarC_Parser_AST.quals in
      let quals1 =
        if is_effect then FStarC_Parser_AST.Effect_qual :: quals else quals in
      let quals2 =
        if typeclass
        then
          match tcs with
          | (FStarC_Parser_AST.TyconRecord uu___)::[] ->
              FStarC_Parser_AST.Noeq :: quals1
          | uu___ ->
              FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_decl d
                FStarC_Errors_Codes.Error_BadClassDecl ()
                (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                (Obj.magic
                   "Ill-formed `class` declaration: definition must be a record type")
        else quals1 in
      let uu___ =
        let uu___1 =
          FStarC_List.map (trans_qual1 FStar_Pervasives_Native.None) quals2 in
        desugar_tycon env d d_attrs uu___1 tcs in
      (match uu___ with
       | (env1, ses) ->
           ((let uu___2 = FStarC_Effect.op_Bang dbg_attrs in
             if uu___2
             then
               let uu___3 =
                 FStarC_Class_Show.show FStarC_Parser_AST.showable_decl d in
               let uu___4 =
                 FStarC_Class_Show.show
                   (FStarC_Class_Show.show_list
                      FStarC_Syntax_Print.showable_sigelt) ses in
               FStarC_Format.print2 "Desugared tycon from {%s} to {%s}\n"
                 uu___3 uu___4
             else ());
            (let mkclass lid =
               let r = FStarC_Ident.range_of_lid lid in
               let body =
                 let uu___2 =
                   FStarC_Syntax_Util.has_attribute d_attrs
                     FStarC_Parser_Const.meta_projectors_attr in
                 if uu___2
                 then
                   let uu___3 =
                     FStarC_Syntax_Syntax.tabbrev
                       FStarC_Parser_Const.mk_projs_lid in
                   let uu___4 =
                     let uu___5 =
                       let uu___6 = FStarC_Syntax_Util.exp_bool true in
                       FStarC_Syntax_Syntax.as_arg uu___6 in
                     let uu___6 =
                       let uu___7 =
                         let uu___8 =
                           let uu___9 = FStarC_Ident.string_of_lid lid in
                           FStarC_Syntax_Util.exp_string uu___9 in
                         FStarC_Syntax_Syntax.as_arg uu___8 in
                       [uu___7] in
                     uu___5 :: uu___6 in
                   FStarC_Syntax_Util.mk_app uu___3 uu___4
                 else
                   (let uu___4 =
                      FStarC_Syntax_Syntax.tabbrev
                        FStarC_Parser_Const.mk_class_lid in
                    let uu___5 =
                      let uu___6 =
                        let uu___7 =
                          let uu___8 = FStarC_Ident.string_of_lid lid in
                          FStarC_Syntax_Util.exp_string uu___8 in
                        FStarC_Syntax_Syntax.as_arg uu___7 in
                      [uu___6] in
                    FStarC_Syntax_Util.mk_app uu___4 uu___5) in
               let uu___2 =
                 let uu___3 =
                   let uu___4 =
                     let uu___5 = tun_r r in
                     FStarC_Syntax_Syntax.new_bv
                       (FStar_Pervasives_Native.Some r) uu___5 in
                   FStarC_Syntax_Syntax.mk_binder uu___4 in
                 [uu___3] in
               FStarC_Syntax_Util.abs uu___2 body
                 FStar_Pervasives_Native.None in
             let rec get_meths se =
               match se.FStarC_Syntax_Syntax.sigel with
               | FStarC_Syntax_Syntax.Sig_bundle
                   { FStarC_Syntax_Syntax.ses = ses1;
                     FStarC_Syntax_Syntax.lids = uu___2;_}
                   -> FStarC_List.concatMap get_meths ses1
               | FStarC_Syntax_Syntax.Sig_datacon
                   { FStarC_Syntax_Syntax.lid1 = uu___2;
                     FStarC_Syntax_Syntax.us1 = uu___3;
                     FStarC_Syntax_Syntax.t1 = t;
                     FStarC_Syntax_Syntax.ty_lid = uu___4;
                     FStarC_Syntax_Syntax.num_ty_params = num_ty_params;
                     FStarC_Syntax_Syntax.mutuals1 = uu___5;
                     FStarC_Syntax_Syntax.injective_type_params1 = uu___6;
                     FStarC_Syntax_Syntax.proj_disc_lids = uu___7;_}
                   ->
                   let uu___8 = FStarC_Syntax_Util.arrow_formals t in
                   (match uu___8 with
                    | (bs, uu___9) ->
                        let uu___10 = FStarC_List.splitAt num_ty_params bs in
                        (match uu___10 with
                         | (uu___11, bs1) ->
                             let bs2 = FStarC_Syntax_Util.name_binders bs1 in
                             FStarC_List.concatMap
                               (fun b ->
                                  let id =
                                    (b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.ppname in
                                  let uu___12 =
                                    FStarC_Syntax_DsEnv.qualify env1 id in
                                  [uu___12]) bs2))
               | uu___2 -> [] in
             let formals =
               let bndl =
                 FStarC_Util.try_find
                   (fun uu___2 ->
                      match uu___2 with
                      | {
                          FStarC_Syntax_Syntax.sigel =
                            FStarC_Syntax_Syntax.Sig_bundle uu___3;
                          FStarC_Syntax_Syntax.sigrng = uu___4;
                          FStarC_Syntax_Syntax.sigquals = uu___5;
                          FStarC_Syntax_Syntax.sigmeta = uu___6;
                          FStarC_Syntax_Syntax.sigattrs = uu___7;
                          FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___8;
                          FStarC_Syntax_Syntax.sigopts = uu___9;_} -> true
                      | uu___3 -> false) ses in
               match bndl with
               | FStar_Pervasives_Native.None -> FStar_Pervasives_Native.None
               | FStar_Pervasives_Native.Some bndl1 ->
                   (match bndl1.FStarC_Syntax_Syntax.sigel with
                    | FStarC_Syntax_Syntax.Sig_bundle
                        { FStarC_Syntax_Syntax.ses = ses1;
                          FStarC_Syntax_Syntax.lids = uu___2;_}
                        ->
                        FStarC_Util.find_map ses1
                          (fun se ->
                             match se.FStarC_Syntax_Syntax.sigel with
                             | FStarC_Syntax_Syntax.Sig_datacon
                                 { FStarC_Syntax_Syntax.lid1 = uu___3;
                                   FStarC_Syntax_Syntax.us1 = uu___4;
                                   FStarC_Syntax_Syntax.t1 = t;
                                   FStarC_Syntax_Syntax.ty_lid = uu___5;
                                   FStarC_Syntax_Syntax.num_ty_params =
                                     uu___6;
                                   FStarC_Syntax_Syntax.mutuals1 = uu___7;
                                   FStarC_Syntax_Syntax.injective_type_params1
                                     = uu___8;
                                   FStarC_Syntax_Syntax.proj_disc_lids =
                                     uu___9;_}
                                 ->
                                 let uu___10 =
                                   FStarC_Syntax_Util.arrow_formals t in
                                 (match uu___10 with
                                  | (formals1, uu___11) ->
                                      FStar_Pervasives_Native.Some formals1)
                             | uu___3 -> FStar_Pervasives_Native.None)
                    | uu___2 -> FStar_Pervasives_Native.None) in
             let rec splice_decl meths se =
               match se.FStarC_Syntax_Syntax.sigel with
               | FStarC_Syntax_Syntax.Sig_bundle
                   { FStarC_Syntax_Syntax.ses = ses1;
                     FStarC_Syntax_Syntax.lids = uu___2;_}
                   -> FStarC_List.concatMap (splice_decl meths) ses1
               | FStarC_Syntax_Syntax.Sig_inductive_typ
                   { FStarC_Syntax_Syntax.lid = lid;
                     FStarC_Syntax_Syntax.us = uu___2;
                     FStarC_Syntax_Syntax.params = uu___3;
                     FStarC_Syntax_Syntax.num_uniform_params = uu___4;
                     FStarC_Syntax_Syntax.t = ty;
                     FStarC_Syntax_Syntax.mutuals = uu___5;
                     FStarC_Syntax_Syntax.ds = uu___6;
                     FStarC_Syntax_Syntax.injective_type_params = uu___7;_}
                   ->
                   let formals1 =
                     match formals with
                     | FStar_Pervasives_Native.None -> []
                     | FStar_Pervasives_Native.Some formals2 -> formals2 in
                   let has_no_method_attr meth =
                     let i = FStarC_Ident.ident_of_lid meth in
                     FStarC_Util.for_some
                       (fun formal ->
                          let uu___8 =
                            FStarC_Ident.ident_equals i
                              (formal.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.ppname in
                          if uu___8
                          then
                            FStarC_Util.for_some
                              (fun attr ->
                                 let uu___9 =
                                   let uu___10 =
                                     FStarC_Syntax_Subst.compress attr in
                                   uu___10.FStarC_Syntax_Syntax.n in
                                 match uu___9 with
                                 | FStarC_Syntax_Syntax.Tm_fvar fv ->
                                     FStarC_Syntax_Syntax.fv_eq_lid fv
                                       FStarC_Parser_Const.no_method_lid
                                 | uu___10 -> false)
                              formal.FStarC_Syntax_Syntax.binder_attrs
                          else false) formals1 in
                   let meths1 =
                     FStarC_List.filter
                       (fun x ->
                          (let uu___8 =
                             let uu___9 =
                               let uu___10 =
                                 let uu___11 = FStarC_Ident.ident_of_lid x in
                                 FStarC_Ident.string_of_id uu___11 in
                               FStarC_String.index uu___10 Prims.int_zero in
                             uu___9 = 95 in
                           Prims.op_Negation uu___8) &&
                            (let uu___8 = has_no_method_attr x in
                             Prims.op_Negation uu___8)) meths in
                   let is_typed = false in
                   let uu___8 =
                     let uu___9 =
                       let uu___10 =
                         let uu___11 = mkclass lid in
                         {
                           FStarC_Syntax_Syntax.is_typed = is_typed;
                           FStarC_Syntax_Syntax.lids2 = meths1;
                           FStarC_Syntax_Syntax.tac = uu___11
                         } in
                       FStarC_Syntax_Syntax.Sig_splice uu___10 in
                     let uu___10 = FStarC_Syntax_DsEnv.opens_and_abbrevs env1 in
                     {
                       FStarC_Syntax_Syntax.sigel = uu___9;
                       FStarC_Syntax_Syntax.sigrng =
                         (d.FStarC_Parser_AST.drange);
                       FStarC_Syntax_Syntax.sigquals = [];
                       FStarC_Syntax_Syntax.sigmeta =
                         FStarC_Syntax_Syntax.default_sigmeta;
                       FStarC_Syntax_Syntax.sigattrs = [];
                       FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___10;
                       FStarC_Syntax_Syntax.sigopts =
                         FStar_Pervasives_Native.None
                     } in
                   [uu___8]
               | uu___2 -> [] in
             let uu___2 =
               if typeclass
               then
                 let meths = FStarC_List.concatMap get_meths ses in
                 let rec add_class_attr se =
                   match se.FStarC_Syntax_Syntax.sigel with
                   | FStarC_Syntax_Syntax.Sig_bundle
                       { FStarC_Syntax_Syntax.ses = ses1;
                         FStarC_Syntax_Syntax.lids = lids;_}
                       ->
                       let ses2 = FStarC_List.map add_class_attr ses1 in
                       let uu___3 =
                         let uu___4 =
                           let uu___5 =
                             FStarC_Syntax_Syntax.fvar_with_dd
                               FStarC_Parser_Const.tcclass_lid
                               FStar_Pervasives_Native.None in
                           uu___5 :: (se.FStarC_Syntax_Syntax.sigattrs) in
                         FStarC_Syntax_Util.deduplicate_terms uu___4 in
                       {
                         FStarC_Syntax_Syntax.sigel =
                           (FStarC_Syntax_Syntax.Sig_bundle
                              {
                                FStarC_Syntax_Syntax.ses = ses2;
                                FStarC_Syntax_Syntax.lids = lids
                              });
                         FStarC_Syntax_Syntax.sigrng =
                           (se.FStarC_Syntax_Syntax.sigrng);
                         FStarC_Syntax_Syntax.sigquals =
                           (se.FStarC_Syntax_Syntax.sigquals);
                         FStarC_Syntax_Syntax.sigmeta =
                           (se.FStarC_Syntax_Syntax.sigmeta);
                         FStarC_Syntax_Syntax.sigattrs = uu___3;
                         FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                           (se.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
                         FStarC_Syntax_Syntax.sigopts =
                           (se.FStarC_Syntax_Syntax.sigopts)
                       }
                   | FStarC_Syntax_Syntax.Sig_inductive_typ uu___3 ->
                       let uu___4 =
                         let uu___5 =
                           let uu___6 =
                             FStarC_Syntax_Syntax.fvar_with_dd
                               FStarC_Parser_Const.tcclass_lid
                               FStar_Pervasives_Native.None in
                           uu___6 :: (se.FStarC_Syntax_Syntax.sigattrs) in
                         FStarC_Syntax_Util.deduplicate_terms uu___5 in
                       {
                         FStarC_Syntax_Syntax.sigel =
                           (se.FStarC_Syntax_Syntax.sigel);
                         FStarC_Syntax_Syntax.sigrng =
                           (se.FStarC_Syntax_Syntax.sigrng);
                         FStarC_Syntax_Syntax.sigquals =
                           (se.FStarC_Syntax_Syntax.sigquals);
                         FStarC_Syntax_Syntax.sigmeta =
                           (se.FStarC_Syntax_Syntax.sigmeta);
                         FStarC_Syntax_Syntax.sigattrs = uu___4;
                         FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                           (se.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
                         FStarC_Syntax_Syntax.sigopts =
                           (se.FStarC_Syntax_Syntax.sigopts)
                       }
                   | uu___3 -> se in
                 let uu___3 = FStarC_List.map add_class_attr ses in
                 let uu___4 = FStarC_List.concatMap (splice_decl meths) ses in
                 (uu___3, uu___4)
               else (ses, []) in
             match uu___2 with
             | (ses1, extra) ->
                 let env2 =
                   FStarC_List.fold_left FStarC_Syntax_DsEnv.push_sigelt env1
                     extra in
                 (env2, (FStarC_List.op_At ses1 extra)))))
  | FStarC_Parser_AST.TopLevelLet (isrec, lets) ->
      let quals = d.FStarC_Parser_AST.quals in
      let expand_toplevel_pattern =
        (isrec = FStarC_Parser_AST.NoLetQualifier) &&
          (match lets with
           | ({ FStarC_Parser_AST.pat = FStarC_Parser_AST.PatOp uu___;
                FStarC_Parser_AST.prange = uu___1;_},
              uu___2)::[] -> false
           | ({ FStarC_Parser_AST.pat = FStarC_Parser_AST.PatVar uu___;
                FStarC_Parser_AST.prange = uu___1;_},
              uu___2)::[] -> false
           | ({
                FStarC_Parser_AST.pat = FStarC_Parser_AST.PatAscribed
                  ({ FStarC_Parser_AST.pat = FStarC_Parser_AST.PatOp uu___;
                     FStarC_Parser_AST.prange = uu___1;_},
                   uu___2);
                FStarC_Parser_AST.prange = uu___3;_},
              uu___4)::[] -> false
           | ({
                FStarC_Parser_AST.pat = FStarC_Parser_AST.PatAscribed
                  ({ FStarC_Parser_AST.pat = FStarC_Parser_AST.PatVar uu___;
                     FStarC_Parser_AST.prange = uu___1;_},
                   uu___2);
                FStarC_Parser_AST.prange = uu___3;_},
              uu___4)::[] -> false
           | (p, uu___)::[] ->
               let uu___1 = is_app_pattern p in Prims.op_Negation uu___1
           | uu___ -> false) in
      if Prims.op_Negation expand_toplevel_pattern
      then
        let lets1 =
          FStarC_List.map (fun x -> (FStar_Pervasives_Native.None, x)) lets in
        let qual =
          match isrec with
          | FStarC_Parser_AST.NoLetQualifier ->
              FStarC_Parser_AST.LocalNoLetQualifier
          | FStarC_Parser_AST.Rec -> FStarC_Parser_AST.LocalRec in
        let as_inner_let =
          let uu___ =
            let uu___1 =
              let uu___2 =
                FStarC_Parser_AST.mk_term
                  (FStarC_Parser_AST.Const FStarC_Const.Const_unit)
                  d.FStarC_Parser_AST.drange FStarC_Parser_AST.Expr in
              (qual, lets1, uu___2) in
            FStarC_Parser_AST.Let uu___1 in
          FStarC_Parser_AST.mk_term uu___ d.FStarC_Parser_AST.drange
            FStarC_Parser_AST.Expr in
        let uu___ = desugar_term_maybe_top true env as_inner_let in
        (match uu___ with
         | (ds_lets, aq) ->
             (check_no_aq aq;
              (let uu___2 =
                 let uu___3 = FStarC_Syntax_Subst.compress ds_lets in
                 uu___3.FStarC_Syntax_Syntax.n in
               match uu___2 with
               | FStarC_Syntax_Syntax.Tm_let
                   { FStarC_Syntax_Syntax.lbs = lbs;
                     FStarC_Syntax_Syntax.body1 = uu___3;_}
                   ->
                   let fvs =
                     FStarC_List.map
                       (fun lb ->
                          FStar_Pervasives.__proj__Inr__item__v
                            lb.FStarC_Syntax_Syntax.lbname)
                       (FStar_Pervasives_Native.snd lbs) in
                   let uu___4 =
                     FStarC_List.fold_right
                       (fun fv uu___5 ->
                          match uu___5 with
                          | (qs, ats) ->
                              let uu___6 =
                                FStarC_Syntax_DsEnv.lookup_letbinding_quals_and_attrs
                                  env fv.FStarC_Syntax_Syntax.fv_name in
                              (match uu___6 with
                               | (qs', ats') ->
                                   ((FStarC_List.rev_append qs' qs),
                                     (FStarC_List.rev_append ats' ats)))) fvs
                       ([], []) in
                   (match uu___4 with
                    | (val_quals, val_attrs) ->
                        let top_attrs =
                          FStarC_Syntax_Util.deduplicate_terms
                            (FStarC_List.rev_append val_attrs d_attrs) in
                        let lbs1 =
                          let uu___5 = lbs in
                          match uu___5 with
                          | (isrec1, lbs0) ->
                              let lbs01 =
                                FStarC_List.map
                                  (fun lb ->
                                     let uu___6 =
                                       FStarC_Syntax_Util.deduplicate_terms
                                         (FStarC_List.rev_append
                                            lb.FStarC_Syntax_Syntax.lbattrs
                                            top_attrs) in
                                     {
                                       FStarC_Syntax_Syntax.lbname =
                                         (lb.FStarC_Syntax_Syntax.lbname);
                                       FStarC_Syntax_Syntax.lbunivs =
                                         (lb.FStarC_Syntax_Syntax.lbunivs);
                                       FStarC_Syntax_Syntax.lbtyp =
                                         (lb.FStarC_Syntax_Syntax.lbtyp);
                                       FStarC_Syntax_Syntax.lbeff =
                                         (lb.FStarC_Syntax_Syntax.lbeff);
                                       FStarC_Syntax_Syntax.lbdef =
                                         (lb.FStarC_Syntax_Syntax.lbdef);
                                       FStarC_Syntax_Syntax.lbattrs = uu___6;
                                       FStarC_Syntax_Syntax.lbpos =
                                         (lb.FStarC_Syntax_Syntax.lbpos)
                                     }) lbs0 in
                              (isrec1, lbs01) in
                        let quals1 =
                          match quals with
                          | uu___5::uu___6 ->
                              FStarC_List.map
                                (trans_qual1 FStar_Pervasives_Native.None)
                                quals
                          | uu___5 -> val_quals in
                        let quals2 =
                          let uu___5 =
                            FStarC_Util.for_some
                              (fun uu___6 ->
                                 match uu___6 with
                                 | (uu___7, (uu___8, t)) ->
                                     t.FStarC_Parser_AST.level =
                                       FStarC_Parser_AST.Formula) lets1 in
                          if uu___5
                          then FStarC_Syntax_Syntax.Logic :: quals1
                          else quals1 in
                        let names =
                          FStarC_List.map
                            (fun fv -> fv.FStarC_Syntax_Syntax.fv_name) fvs in
                        let s =
                          let uu___5 =
                            FStarC_Syntax_DsEnv.opens_and_abbrevs env in
                          {
                            FStarC_Syntax_Syntax.sigel =
                              (FStarC_Syntax_Syntax.Sig_let
                                 {
                                   FStarC_Syntax_Syntax.lbs1 = lbs1;
                                   FStarC_Syntax_Syntax.lids1 = names
                                 });
                            FStarC_Syntax_Syntax.sigrng =
                              (d.FStarC_Parser_AST.drange);
                            FStarC_Syntax_Syntax.sigquals = quals2;
                            FStarC_Syntax_Syntax.sigmeta =
                              FStarC_Syntax_Syntax.default_sigmeta;
                            FStarC_Syntax_Syntax.sigattrs = top_attrs;
                            FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                              uu___5;
                            FStarC_Syntax_Syntax.sigopts =
                              FStar_Pervasives_Native.None
                          } in
                        let env1 = FStarC_Syntax_DsEnv.push_sigelt env s in
                        (env1, [s]))
               | uu___3 -> failwith "Desugaring a let did not produce a let")))
      else
        (let uu___1 =
           match lets with
           | (pat, body)::[] -> (pat, body)
           | uu___2 ->
               failwith
                 "expand_toplevel_pattern should only allow single definition lets" in
         match uu___1 with
         | (pat, body) ->
             let rec gen_fresh_toplevel_name uu___2 =
               let nm = FStarC_Ident.gen FStarC_Range_Type.dummyRange in
               let uu___3 =
                 let uu___4 =
                   let uu___5 = FStarC_Ident.lid_of_ids [nm] in
                   FStarC_Syntax_DsEnv.resolve_name env uu___5 in
                 FStar_Pervasives_Native.uu___is_Some uu___4 in
               if uu___3 then gen_fresh_toplevel_name () else nm in
             let fresh_toplevel_name = gen_fresh_toplevel_name () in
             let fresh_pat =
               let var_pat =
                 FStarC_Parser_AST.mk_pattern
                   (FStarC_Parser_AST.PatVar
                      (fresh_toplevel_name, FStar_Pervasives_Native.None, []))
                   FStarC_Range_Type.dummyRange in
               match pat.FStarC_Parser_AST.pat with
               | FStarC_Parser_AST.PatAscribed (pat1, ty) ->
                   {
                     FStarC_Parser_AST.pat =
                       (FStarC_Parser_AST.PatAscribed (var_pat, ty));
                     FStarC_Parser_AST.prange =
                       (pat1.FStarC_Parser_AST.prange)
                   }
               | uu___2 -> var_pat in
             let main_let =
               let quals1 =
                 if
                   FStarC_List.mem FStarC_Parser_AST.Private
                     d.FStarC_Parser_AST.quals
                 then d.FStarC_Parser_AST.quals
                 else FStarC_Parser_AST.Private ::
                   (d.FStarC_Parser_AST.quals) in
               desugar_decl env
                 {
                   FStarC_Parser_AST.d =
                     (FStarC_Parser_AST.TopLevelLet
                        (isrec, [(fresh_pat, body)]));
                   FStarC_Parser_AST.drange = (d.FStarC_Parser_AST.drange);
                   FStarC_Parser_AST.quals = quals1;
                   FStarC_Parser_AST.attrs = (d.FStarC_Parser_AST.attrs);
                   FStarC_Parser_AST.interleaved =
                     (d.FStarC_Parser_AST.interleaved)
                 } in
             let main =
               let uu___2 =
                 let uu___3 = FStarC_Ident.lid_of_ids [fresh_toplevel_name] in
                 FStarC_Parser_AST.Var uu___3 in
               FStarC_Parser_AST.mk_term uu___2 pat.FStarC_Parser_AST.prange
                 FStarC_Parser_AST.Expr in
             let build_generic_projection uu___2 id_opt =
               match uu___2 with
               | (env1, ses) ->
                   let uu___3 =
                     match id_opt with
                     | FStar_Pervasives_Native.Some id ->
                         let lid = FStarC_Ident.lid_of_ids [id] in
                         let branch =
                           let uu___4 = FStarC_Ident.range_of_lid lid in
                           FStarC_Parser_AST.mk_term
                             (FStarC_Parser_AST.Var lid) uu___4
                             FStarC_Parser_AST.Expr in
                         let bv_pat =
                           let uu___4 = FStarC_Ident.range_of_id id in
                           FStarC_Parser_AST.mk_pattern
                             (FStarC_Parser_AST.PatVar
                                (id, FStar_Pervasives_Native.None, []))
                             uu___4 in
                         (bv_pat, branch)
                     | FStar_Pervasives_Native.None ->
                         let id = gen_fresh_toplevel_name () in
                         let branch =
                           FStarC_Parser_AST.mk_term
                             (FStarC_Parser_AST.Const FStarC_Const.Const_unit)
                             FStarC_Range_Type.dummyRange
                             FStarC_Parser_AST.Expr in
                         let bv_pat =
                           let uu___4 = FStarC_Ident.range_of_id id in
                           FStarC_Parser_AST.mk_pattern
                             (FStarC_Parser_AST.PatVar
                                (id, FStar_Pervasives_Native.None, []))
                             uu___4 in
                         let bv_pat1 =
                           let uu___4 =
                             let uu___5 =
                               let uu___6 =
                                 let uu___7 =
                                   let uu___8 = FStarC_Ident.range_of_id id in
                                   unit_ty uu___8 in
                                 (uu___7, FStar_Pervasives_Native.None) in
                               (bv_pat, uu___6) in
                             FStarC_Parser_AST.PatAscribed uu___5 in
                           let uu___5 = FStarC_Ident.range_of_id id in
                           FStarC_Parser_AST.mk_pattern uu___4 uu___5 in
                         (bv_pat1, branch) in
                   (match uu___3 with
                    | (bv_pat, branch) ->
                        let body1 =
                          FStarC_Parser_AST.mk_term
                            (FStarC_Parser_AST.Match
                               (main, FStar_Pervasives_Native.None,
                                 FStar_Pervasives_Native.None,
                                 [(pat, FStar_Pervasives_Native.None, branch)]))
                            main.FStarC_Parser_AST.range
                            FStarC_Parser_AST.Expr in
                        let id_decl =
                          FStarC_Parser_AST.mk_decl
                            (FStarC_Parser_AST.TopLevelLet
                               (FStarC_Parser_AST.NoLetQualifier,
                                 [(bv_pat, body1)]))
                            FStarC_Range_Type.dummyRange [] in
                        let id_decl1 =
                          {
                            FStarC_Parser_AST.d =
                              (id_decl.FStarC_Parser_AST.d);
                            FStarC_Parser_AST.drange =
                              (id_decl.FStarC_Parser_AST.drange);
                            FStarC_Parser_AST.quals =
                              (d.FStarC_Parser_AST.quals);
                            FStarC_Parser_AST.attrs =
                              (id_decl.FStarC_Parser_AST.attrs);
                            FStarC_Parser_AST.interleaved =
                              (id_decl.FStarC_Parser_AST.interleaved)
                          } in
                        let uu___4 = desugar_decl env1 id_decl1 in
                        (match uu___4 with
                         | (env2, ses') ->
                             (env2, (FStarC_List.op_At ses ses')))) in
             let build_projection uu___2 id =
               match uu___2 with
               | (env1, ses) ->
                   build_generic_projection (env1, ses)
                     (FStar_Pervasives_Native.Some id) in
             let build_coverage_check uu___2 =
               match uu___2 with
               | (env1, ses) ->
                   build_generic_projection (env1, ses)
                     FStar_Pervasives_Native.None in
             let bvs =
               let uu___2 = gather_pattern_bound_vars pat in
               FStarC_Class_Setlike.elems ()
                 (Obj.magic
                    (FStarC_FlatSet.setlike_flat_set
                       FStarC_Syntax_Syntax.ord_ident)) (Obj.magic uu___2) in
             let uu___2 =
               (FStarC_List.isEmpty bvs) &&
                 (let uu___3 = is_var_pattern pat in Prims.op_Negation uu___3) in
             if uu___2
             then build_coverage_check main_let
             else FStarC_List.fold_left build_projection main_let bvs)
  | FStarC_Parser_AST.Assume (id, t) ->
      let f = desugar_formula env t in
      let lid = FStarC_Syntax_DsEnv.qualify env id in
      let uu___ =
        let uu___1 =
          let uu___2 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
          {
            FStarC_Syntax_Syntax.sigel =
              (FStarC_Syntax_Syntax.Sig_assume
                 {
                   FStarC_Syntax_Syntax.lid3 = lid;
                   FStarC_Syntax_Syntax.us3 = [];
                   FStarC_Syntax_Syntax.phi1 = f
                 });
            FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
            FStarC_Syntax_Syntax.sigquals = [FStarC_Syntax_Syntax.Assumption];
            FStarC_Syntax_Syntax.sigmeta =
              FStarC_Syntax_Syntax.default_sigmeta;
            FStarC_Syntax_Syntax.sigattrs = d_attrs;
            FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___2;
            FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
          } in
        [uu___1] in
      (env, uu___)
  | FStarC_Parser_AST.Val (id, t) ->
      let quals = d.FStarC_Parser_AST.quals in
      let t1 =
        let uu___ = FStarC_ToSyntax_TickedVars.close_fun env t in
        desugar_term env uu___ in
      let quals1 =
        let uu___ =
          (FStarC_Syntax_DsEnv.iface env) &&
            (FStarC_Syntax_DsEnv.admitted_iface env) in
        if uu___ then FStarC_Parser_AST.Assumption :: quals else quals in
      let lid = FStarC_Syntax_DsEnv.qualify env id in
      let se =
        let uu___ =
          FStarC_List.map (trans_qual1 FStar_Pervasives_Native.None) quals1 in
        let uu___1 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
        {
          FStarC_Syntax_Syntax.sigel =
            (FStarC_Syntax_Syntax.Sig_declare_typ
               {
                 FStarC_Syntax_Syntax.lid2 = lid;
                 FStarC_Syntax_Syntax.us2 = [];
                 FStarC_Syntax_Syntax.t2 = t1
               });
          FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
          FStarC_Syntax_Syntax.sigquals = uu___;
          FStarC_Syntax_Syntax.sigmeta = FStarC_Syntax_Syntax.default_sigmeta;
          FStarC_Syntax_Syntax.sigattrs = d_attrs;
          FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___1;
          FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
        } in
      let env1 = FStarC_Syntax_DsEnv.push_sigelt env se in (env1, [se])
  | FStarC_Parser_AST.Exception (id, t_opt) ->
      let t =
        match t_opt with
        | FStar_Pervasives_Native.None ->
            FStarC_Syntax_DsEnv.fail_or env
              (FStarC_Syntax_DsEnv.try_lookup_lid env)
              FStarC_Parser_Const.exn_lid
        | FStar_Pervasives_Native.Some term ->
            let t1 = desugar_term env term in
            let uu___ =
              let uu___1 = FStarC_Syntax_Syntax.null_binder t1 in [uu___1] in
            let uu___1 =
              let uu___2 =
                FStarC_Syntax_DsEnv.fail_or env
                  (FStarC_Syntax_DsEnv.try_lookup_lid env)
                  FStarC_Parser_Const.exn_lid in
              FStarC_Syntax_Syntax.mk_Total uu___2 in
            FStarC_Syntax_Util.arrow uu___ uu___1 in
      let l = FStarC_Syntax_DsEnv.qualify env id in
      let qual = [FStarC_Syntax_Syntax.ExceptionConstructor] in
      let top_attrs = d_attrs in
      let se =
        let uu___ = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
        {
          FStarC_Syntax_Syntax.sigel =
            (FStarC_Syntax_Syntax.Sig_datacon
               {
                 FStarC_Syntax_Syntax.lid1 = l;
                 FStarC_Syntax_Syntax.us1 = [];
                 FStarC_Syntax_Syntax.t1 = t;
                 FStarC_Syntax_Syntax.ty_lid = FStarC_Parser_Const.exn_lid;
                 FStarC_Syntax_Syntax.num_ty_params = Prims.int_zero;
                 FStarC_Syntax_Syntax.mutuals1 =
                   [FStarC_Parser_Const.exn_lid];
                 FStarC_Syntax_Syntax.injective_type_params1 = false;
                 FStarC_Syntax_Syntax.proj_disc_lids = []
               });
          FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
          FStarC_Syntax_Syntax.sigquals = qual;
          FStarC_Syntax_Syntax.sigmeta = FStarC_Syntax_Syntax.default_sigmeta;
          FStarC_Syntax_Syntax.sigattrs = top_attrs;
          FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___;
          FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
        } in
      let se' =
        let uu___ = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
        {
          FStarC_Syntax_Syntax.sigel =
            (FStarC_Syntax_Syntax.Sig_bundle
               {
                 FStarC_Syntax_Syntax.ses = [se];
                 FStarC_Syntax_Syntax.lids = [l]
               });
          FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
          FStarC_Syntax_Syntax.sigquals = qual;
          FStarC_Syntax_Syntax.sigmeta = FStarC_Syntax_Syntax.default_sigmeta;
          FStarC_Syntax_Syntax.sigattrs = top_attrs;
          FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___;
          FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
        } in
      let env1 = FStarC_Syntax_DsEnv.push_sigelt env se' in (env1, [se'])
  | FStarC_Parser_AST.NewEffect (FStarC_Parser_AST.RedefineEffect
      (eff_name, eff_binders, defn)) ->
      let quals = d.FStarC_Parser_AST.quals in
      desugar_redefine_effect env d d_attrs trans_qual1 quals eff_name
        eff_binders defn
  | FStarC_Parser_AST.NewEffect (FStarC_Parser_AST.DefineEffect
      (eff_name, eff_binders, eff_typ, eff_decls)) ->
      let quals = d.FStarC_Parser_AST.quals in
      desugar_effect env d d_attrs quals false eff_name eff_binders eff_typ
        eff_decls
  | FStarC_Parser_AST.LayeredEffect (FStarC_Parser_AST.DefineEffect
      (eff_name, eff_binders, eff_typ, eff_decls)) ->
      let quals = d.FStarC_Parser_AST.quals in
      desugar_effect env d d_attrs quals true eff_name eff_binders eff_typ
        eff_decls
  | FStarC_Parser_AST.LayeredEffect (FStarC_Parser_AST.RedefineEffect uu___)
      ->
      failwith
        "Impossible: LayeredEffect (RedefineEffect _) (should not be parseable)"
  | FStarC_Parser_AST.SubEffect l ->
      let src_ed =
        lookup_effect_lid env l.FStarC_Parser_AST.msource
          d.FStarC_Parser_AST.drange in
      let dst_ed =
        lookup_effect_lid env l.FStarC_Parser_AST.mdest
          d.FStarC_Parser_AST.drange in
      let top_attrs = d_attrs in
      let uu___ =
        let uu___1 =
          (FStarC_Syntax_Util.is_layered src_ed) ||
            (FStarC_Syntax_Util.is_layered dst_ed) in
        Prims.op_Negation uu___1 in
      if uu___
      then
        let uu___1 =
          match l.FStarC_Parser_AST.lift_op with
          | FStarC_Parser_AST.NonReifiableLift t ->
              let uu___2 =
                let uu___3 = let uu___4 = desugar_term env t in ([], uu___4) in
                FStar_Pervasives_Native.Some uu___3 in
              (uu___2, FStar_Pervasives_Native.None)
          | FStarC_Parser_AST.ReifiableLift (wp, t) ->
              let uu___2 =
                let uu___3 = let uu___4 = desugar_term env wp in ([], uu___4) in
                FStar_Pervasives_Native.Some uu___3 in
              let uu___3 =
                let uu___4 = let uu___5 = desugar_term env t in ([], uu___5) in
                FStar_Pervasives_Native.Some uu___4 in
              (uu___2, uu___3)
          | FStarC_Parser_AST.LiftForFree t ->
              let uu___2 =
                let uu___3 = let uu___4 = desugar_term env t in ([], uu___4) in
                FStar_Pervasives_Native.Some uu___3 in
              (FStar_Pervasives_Native.None, uu___2) in
        (match uu___1 with
         | (lift_wp, lift) ->
             let se =
               let uu___2 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
               {
                 FStarC_Syntax_Syntax.sigel =
                   (FStarC_Syntax_Syntax.Sig_sub_effect
                      {
                        FStarC_Syntax_Syntax.source =
                          (src_ed.FStarC_Syntax_Syntax.mname);
                        FStarC_Syntax_Syntax.target =
                          (dst_ed.FStarC_Syntax_Syntax.mname);
                        FStarC_Syntax_Syntax.lift_wp = lift_wp;
                        FStarC_Syntax_Syntax.lift = lift;
                        FStarC_Syntax_Syntax.kind =
                          FStar_Pervasives_Native.None
                      });
                 FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
                 FStarC_Syntax_Syntax.sigquals = [];
                 FStarC_Syntax_Syntax.sigmeta =
                   FStarC_Syntax_Syntax.default_sigmeta;
                 FStarC_Syntax_Syntax.sigattrs = top_attrs;
                 FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___2;
                 FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
               } in
             (env, [se]))
      else
        (match l.FStarC_Parser_AST.lift_op with
         | FStarC_Parser_AST.NonReifiableLift t ->
             let sub_eff =
               let uu___2 =
                 let uu___3 = let uu___4 = desugar_term env t in ([], uu___4) in
                 FStar_Pervasives_Native.Some uu___3 in
               {
                 FStarC_Syntax_Syntax.source =
                   (src_ed.FStarC_Syntax_Syntax.mname);
                 FStarC_Syntax_Syntax.target =
                   (dst_ed.FStarC_Syntax_Syntax.mname);
                 FStarC_Syntax_Syntax.lift_wp = FStar_Pervasives_Native.None;
                 FStarC_Syntax_Syntax.lift = uu___2;
                 FStarC_Syntax_Syntax.kind = FStar_Pervasives_Native.None
               } in
             let uu___2 =
               let uu___3 =
                 let uu___4 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
                 {
                   FStarC_Syntax_Syntax.sigel =
                     (FStarC_Syntax_Syntax.Sig_sub_effect sub_eff);
                   FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
                   FStarC_Syntax_Syntax.sigquals = [];
                   FStarC_Syntax_Syntax.sigmeta =
                     FStarC_Syntax_Syntax.default_sigmeta;
                   FStarC_Syntax_Syntax.sigattrs = top_attrs;
                   FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___4;
                   FStarC_Syntax_Syntax.sigopts =
                     FStar_Pervasives_Native.None
                 } in
               [uu___3] in
             (env, uu___2)
         | uu___2 ->
             failwith
               "Impossible! unexpected lift_op for lift to a layered effect")
  | FStarC_Parser_AST.Polymonadic_bind (m_eff, n_eff, p_eff, bind) ->
      let m = lookup_effect_lid env m_eff d.FStarC_Parser_AST.drange in
      let n = lookup_effect_lid env n_eff d.FStarC_Parser_AST.drange in
      let p = lookup_effect_lid env p_eff d.FStarC_Parser_AST.drange in
      let top_attrs = d_attrs in
      let uu___ =
        let uu___1 =
          let uu___2 =
            let uu___3 =
              let uu___4 = let uu___5 = desugar_term env bind in ([], uu___5) in
              {
                FStarC_Syntax_Syntax.m_lid = (m.FStarC_Syntax_Syntax.mname);
                FStarC_Syntax_Syntax.n_lid = (n.FStarC_Syntax_Syntax.mname);
                FStarC_Syntax_Syntax.p_lid = (p.FStarC_Syntax_Syntax.mname);
                FStarC_Syntax_Syntax.tm3 = uu___4;
                FStarC_Syntax_Syntax.typ = ([], FStarC_Syntax_Syntax.tun);
                FStarC_Syntax_Syntax.kind1 = FStar_Pervasives_Native.None
              } in
            FStarC_Syntax_Syntax.Sig_polymonadic_bind uu___3 in
          let uu___3 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
          {
            FStarC_Syntax_Syntax.sigel = uu___2;
            FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
            FStarC_Syntax_Syntax.sigquals = [];
            FStarC_Syntax_Syntax.sigmeta =
              FStarC_Syntax_Syntax.default_sigmeta;
            FStarC_Syntax_Syntax.sigattrs = top_attrs;
            FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___3;
            FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
          } in
        [uu___1] in
      (env, uu___)
  | FStarC_Parser_AST.Polymonadic_subcomp (m_eff, n_eff, subcomp) ->
      let m = lookup_effect_lid env m_eff d.FStarC_Parser_AST.drange in
      let n = lookup_effect_lid env n_eff d.FStarC_Parser_AST.drange in
      let top_attrs = d_attrs in
      let uu___ =
        let uu___1 =
          let uu___2 =
            let uu___3 =
              let uu___4 =
                let uu___5 = desugar_term env subcomp in ([], uu___5) in
              {
                FStarC_Syntax_Syntax.m_lid1 = (m.FStarC_Syntax_Syntax.mname);
                FStarC_Syntax_Syntax.n_lid1 = (n.FStarC_Syntax_Syntax.mname);
                FStarC_Syntax_Syntax.tm4 = uu___4;
                FStarC_Syntax_Syntax.typ1 = ([], FStarC_Syntax_Syntax.tun);
                FStarC_Syntax_Syntax.kind2 = FStar_Pervasives_Native.None
              } in
            FStarC_Syntax_Syntax.Sig_polymonadic_subcomp uu___3 in
          let uu___3 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
          {
            FStarC_Syntax_Syntax.sigel = uu___2;
            FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
            FStarC_Syntax_Syntax.sigquals = [];
            FStarC_Syntax_Syntax.sigmeta =
              FStarC_Syntax_Syntax.default_sigmeta;
            FStarC_Syntax_Syntax.sigattrs = top_attrs;
            FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___3;
            FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
          } in
        [uu___1] in
      (env, uu___)
  | FStarC_Parser_AST.Splice (is_typed, ids, t) ->
      let ids1 = if d.FStarC_Parser_AST.interleaved then [] else ids in
      let t1 = desugar_term env t in
      let top_attrs = d_attrs in
      let se =
        let uu___ =
          let uu___1 =
            let uu___2 =
              FStarC_List.map (FStarC_Syntax_DsEnv.qualify env) ids1 in
            {
              FStarC_Syntax_Syntax.is_typed = is_typed;
              FStarC_Syntax_Syntax.lids2 = uu___2;
              FStarC_Syntax_Syntax.tac = t1
            } in
          FStarC_Syntax_Syntax.Sig_splice uu___1 in
        let uu___1 =
          FStarC_List.map (trans_qual1 FStar_Pervasives_Native.None)
            d.FStarC_Parser_AST.quals in
        let uu___2 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
        {
          FStarC_Syntax_Syntax.sigel = uu___;
          FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
          FStarC_Syntax_Syntax.sigquals = uu___1;
          FStarC_Syntax_Syntax.sigmeta = FStarC_Syntax_Syntax.default_sigmeta;
          FStarC_Syntax_Syntax.sigattrs = top_attrs;
          FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___2;
          FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
        } in
      let env1 = FStarC_Syntax_DsEnv.push_sigelt env se in (env1, [se])
  | FStarC_Parser_AST.UseLangDecls uu___ -> (env, [])
  | FStarC_Parser_AST.Unparseable ->
      FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_decl d
        FStarC_Errors_Codes.Fatal_SyntaxError ()
        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
        (Obj.magic "Syntax error")
  | FStarC_Parser_AST.DeclSyntaxExtension
      (extension_name, code, uu___, range) ->
      let extension_parser =
        FStarC_Parser_AST_Util.lookup_extension_parser extension_name in
      (match extension_parser with
       | FStar_Pervasives_Native.None ->
           let uu___1 =
             FStarC_Format.fmt1 "Unknown syntax extension %s" extension_name in
           FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range
             range FStarC_Errors_Codes.Fatal_SyntaxError ()
             (Obj.magic FStarC_Errors_Msg.is_error_message_string)
             (Obj.magic uu___1)
       | FStar_Pervasives_Native.Some parser ->
           let opens =
             let uu___1 = FStarC_Syntax_DsEnv.open_modules_and_namespaces env in
             let uu___2 = FStarC_Syntax_DsEnv.module_abbrevs env in
             {
               FStarC_Parser_AST_Util.open_namespaces = uu___1;
               FStarC_Parser_AST_Util.module_abbreviations = uu___2
             } in
           let uu___1 =
             parser.FStarC_Parser_AST_Util.parse_decl opens code range in
           (match uu___1 with
            | FStar_Pervasives.Inl error ->
                FStarC_Errors.raise_error
                  FStarC_Class_HasRange.hasRange_range
                  error.FStarC_Parser_AST_Util.range
                  FStarC_Errors_Codes.Fatal_SyntaxError ()
                  (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
                  (Obj.magic error.FStarC_Parser_AST_Util.message)
            | FStar_Pervasives.Inr d' ->
                let quals =
                  FStarC_List.op_At d'.FStarC_Parser_AST.quals
                    d.FStarC_Parser_AST.quals in
                let attrs =
                  FStarC_List.op_At d'.FStarC_Parser_AST.attrs
                    d.FStarC_Parser_AST.attrs in
                let uu___2 =
                  let uu___3 = FStarC_List.map (desugar_term env) attrs in
                  FStarC_Syntax_Util.deduplicate_terms uu___3 in
                desugar_decl_maybe_fail_attr env
                  {
                    FStarC_Parser_AST.d = (d'.FStarC_Parser_AST.d);
                    FStarC_Parser_AST.drange = (d.FStarC_Parser_AST.drange);
                    FStarC_Parser_AST.quals = quals;
                    FStarC_Parser_AST.attrs = attrs;
                    FStarC_Parser_AST.interleaved =
                      (d.FStarC_Parser_AST.interleaved)
                  } uu___2))
  | FStarC_Parser_AST.DeclToBeDesugared tbs ->
      let uu___ = lookup_extension_tosyntax tbs.FStarC_Parser_AST.lang_name in
      (match uu___ with
       | FStar_Pervasives_Native.None ->
           let uu___1 =
             FStarC_Format.fmt1
               "Could not find desugaring callback for extension %s"
               tbs.FStarC_Parser_AST.lang_name in
           FStarC_Errors.raise_error FStarC_Parser_AST.hasRange_decl d
             FStarC_Errors_Codes.Fatal_SyntaxError ()
             (Obj.magic FStarC_Errors_Msg.is_error_message_string)
             (Obj.magic uu___1)
       | FStar_Pervasives_Native.Some desugar ->
           let mk_sig sigel =
             let top_attrs = d_attrs in
             let sigel1 =
               if d.FStarC_Parser_AST.interleaved
               then
                 match sigel with
                 | FStarC_Syntax_Syntax.Sig_splice s ->
                     FStarC_Syntax_Syntax.Sig_splice
                       {
                         FStarC_Syntax_Syntax.is_typed =
                           (s.FStarC_Syntax_Syntax.is_typed);
                         FStarC_Syntax_Syntax.lids2 = [];
                         FStarC_Syntax_Syntax.tac =
                           (s.FStarC_Syntax_Syntax.tac)
                       }
                 | uu___1 -> sigel
               else sigel in
             let se =
               let uu___1 =
                 FStarC_List.map (trans_qual1 FStar_Pervasives_Native.None)
                   d.FStarC_Parser_AST.quals in
               let uu___2 = FStarC_Syntax_DsEnv.opens_and_abbrevs env in
               {
                 FStarC_Syntax_Syntax.sigel = sigel1;
                 FStarC_Syntax_Syntax.sigrng = (d.FStarC_Parser_AST.drange);
                 FStarC_Syntax_Syntax.sigquals = uu___1;
                 FStarC_Syntax_Syntax.sigmeta =
                   FStarC_Syntax_Syntax.default_sigmeta;
                 FStarC_Syntax_Syntax.sigattrs = top_attrs;
                 FStarC_Syntax_Syntax.sigopens_and_abbrevs = uu___2;
                 FStarC_Syntax_Syntax.sigopts = FStar_Pervasives_Native.None
               } in
             se in
           let lids =
             FStarC_List.map (FStarC_Syntax_DsEnv.qualify env)
               tbs.FStarC_Parser_AST.idents in
           let sigelts' =
             desugar env tbs.FStarC_Parser_AST.blob lids
               d.FStarC_Parser_AST.drange in
           let sigelts = FStarC_List.map mk_sig sigelts' in
           let env1 =
             FStarC_List.fold_left FStarC_Syntax_DsEnv.push_sigelt env
               sigelts in
           (env1, sigelts))
let desugar_decls (env : env_t) (decls : FStarC_Parser_AST.decl Prims.list) :
  (env_t * FStarC_Syntax_Syntax.sigelt Prims.list)=
  FStarC_Stats.record "desugar_decls"
    (fun uu___ ->
       let uu___1 =
         FStarC_List.fold_left
           (fun uu___2 d ->
              match uu___2 with
              | (env1, sigelts) ->
                  let uu___3 = desugar_decl env1 d in
                  (match uu___3 with
                   | (env2, se) ->
                       (env2, (FStarC_List.rev_append se sigelts))))
           (env, []) decls in
       match uu___1 with
       | (env1, sigelts) -> (env1, (FStarC_List.rev sigelts)))
let desugar_modul_common
  (curmod : FStarC_Syntax_Syntax.modul FStar_Pervasives_Native.option)
  (env : FStarC_Syntax_DsEnv.env) (m : FStarC_Parser_AST.modul) :
  (env_t * FStarC_Syntax_Syntax.modul * Prims.bool)=
  let env1 =
    match (curmod, m) with
    | (FStar_Pervasives_Native.None, uu___) -> env
    | (FStar_Pervasives_Native.Some
       { FStarC_Syntax_Syntax.name = prev_lid;
         FStarC_Syntax_Syntax.declarations = uu___;
         FStarC_Syntax_Syntax.is_interface = uu___1;_},
       FStarC_Parser_AST.Module
       { FStarC_Parser_AST.no_prelude = uu___2;
         FStarC_Parser_AST.mname = current_lid;
         FStarC_Parser_AST.decls = uu___3;_})
        when
        (FStarC_Ident.lid_equals prev_lid current_lid) &&
          (FStarC_Options.interactive ())
        -> env
    | (FStar_Pervasives_Native.Some prev_mod, uu___) ->
        let uu___1 =
          FStarC_Syntax_DsEnv.finish_module_or_interface env prev_mod in
        FStar_Pervasives_Native.fst uu___1 in
  let uu___ =
    match m with
    | FStarC_Parser_AST.Interface
        { FStarC_Parser_AST.no_prelude1 = no_prelude;
          FStarC_Parser_AST.mname1 = mname; FStarC_Parser_AST.decls1 = decls;
          FStarC_Parser_AST.admitted = admitted;_}
        ->
        let uu___1 =
          FStarC_Syntax_DsEnv.prepare_module_or_interface no_prelude true
            admitted env1 mname FStarC_Syntax_DsEnv.default_mii in
        (uu___1, mname, decls, true)
    | FStarC_Parser_AST.Module
        { FStarC_Parser_AST.no_prelude = no_prelude;
          FStarC_Parser_AST.mname = mname; FStarC_Parser_AST.decls = decls;_}
        ->
        let uu___1 =
          FStarC_Syntax_DsEnv.prepare_module_or_interface no_prelude false
            false env1 mname FStarC_Syntax_DsEnv.default_mii in
        (uu___1, mname, decls, false) in
  match uu___ with
  | ((env2, pop_when_done), mname, decls, intf) ->
      let uu___1 = desugar_decls env2 decls in
      (match uu___1 with
       | (env3, sigelts) ->
           let modul =
             {
               FStarC_Syntax_Syntax.name = mname;
               FStarC_Syntax_Syntax.declarations = sigelts;
               FStarC_Syntax_Syntax.is_interface = intf
             } in
           (env3, modul, pop_when_done))
let desugar_partial_modul
  (curmod : FStarC_Syntax_Syntax.modul FStar_Pervasives_Native.option)
  (env : env_t) (m : FStarC_Parser_AST.modul) :
  (env_t * FStarC_Syntax_Syntax.modul)=
  let uu___ = desugar_modul_common curmod env m in
  match uu___ with
  | (env1, modul, pop_when_done) ->
      if pop_when_done
      then let uu___1 = FStarC_Syntax_DsEnv.pop () in (uu___1, modul)
      else (env1, modul)
let desugar_modul (env : FStarC_Syntax_DsEnv.env)
  (m : FStarC_Parser_AST.modul) : (env_t * FStarC_Syntax_Syntax.modul)=
  let uu___ =
    let uu___1 =
      let uu___2 = FStarC_Parser_AST.lid_of_modul m in
      FStarC_Class_Show.show FStarC_Ident.showable_lident uu___2 in
    Prims.strcat "While desugaring module " uu___1 in
  FStarC_Errors.with_ctx uu___
    (fun uu___1 ->
       let uu___2 = desugar_modul_common FStar_Pervasives_Native.None env m in
       match uu___2 with
       | (env1, modul, pop_when_done) ->
           let uu___3 =
             FStarC_Syntax_DsEnv.finish_module_or_interface env1 modul in
           (match uu___3 with
            | (env2, modul1) ->
                ((let uu___5 =
                    let uu___6 =
                      FStarC_Ident.string_of_lid
                        modul1.FStarC_Syntax_Syntax.name in
                    FStarC_Options.dump_module uu___6 in
                  if uu___5
                  then
                    let uu___6 =
                      FStarC_Class_Show.show
                        FStarC_Syntax_Print.showable_modul modul1 in
                    FStarC_Format.print1 "Module after desugaring:\n%s\n"
                      uu___6
                  else ());
                 (let uu___5 =
                    if pop_when_done
                    then
                      FStarC_Syntax_DsEnv.export_interface
                        modul1.FStarC_Syntax_Syntax.name env2
                    else env2 in
                  (uu___5, modul1)))))
let with_options (f : unit -> 'a) : 'a=
  let uu___ =
    FStarC_Options.with_saved_options
      (fun uu___1 ->
         let r = f () in let light = FStarC_Options.ml_ish () in (light, r)) in
  match uu___ with
  | (light, r) -> (if light then FStarC_Options.set_ml_ish () else (); r)
let ast_modul_to_modul (modul : FStarC_Parser_AST.modul) :
  FStarC_Syntax_Syntax.modul FStarC_Syntax_DsEnv.withenv=
  fun env ->
    with_options
      (fun uu___ ->
         let uu___1 = desugar_modul env modul in
         match uu___1 with | (e, m) -> (m, e))
let decls_to_sigelts (decls : FStarC_Parser_AST.decl Prims.list) :
  FStarC_Syntax_Syntax.sigelts FStarC_Syntax_DsEnv.withenv=
  fun env ->
    with_options
      (fun uu___ ->
         let uu___1 = desugar_decls env decls in
         match uu___1 with | (env1, sigelts) -> (sigelts, env1))
let partial_ast_modul_to_modul
  (modul : FStarC_Syntax_Syntax.modul FStar_Pervasives_Native.option)
  (a_modul : FStarC_Parser_AST.modul) :
  FStarC_Syntax_Syntax.modul FStarC_Syntax_DsEnv.withenv=
  fun env ->
    with_options
      (fun uu___ ->
         let uu___1 = desugar_partial_modul modul env a_modul in
         match uu___1 with | (env1, modul1) -> (modul1, env1))
let add_modul_to_env_core (finish : Prims.bool)
  (m : FStarC_Syntax_Syntax.modul)
  (mii : FStarC_Syntax_DsEnv.module_inclusion_info)
  (erase_univs : FStarC_Syntax_Syntax.term -> FStarC_Syntax_Syntax.term) :
  unit FStarC_Syntax_DsEnv.withenv=
  fun en ->
    let erase_univs_ed ed =
      let erase_binders bs =
        match bs with
        | [] -> []
        | uu___ ->
            let t =
              let uu___1 =
                FStarC_Syntax_Syntax.mk
                  (FStarC_Syntax_Syntax.Tm_abs
                     {
                       FStarC_Syntax_Syntax.bs = bs;
                       FStarC_Syntax_Syntax.body =
                         FStarC_Syntax_Syntax.t_unit;
                       FStarC_Syntax_Syntax.rc_opt =
                         FStar_Pervasives_Native.None
                     }) FStarC_Range_Type.dummyRange in
              erase_univs uu___1 in
            let uu___1 =
              let uu___2 = FStarC_Syntax_Subst.compress t in
              uu___2.FStarC_Syntax_Syntax.n in
            (match uu___1 with
             | FStarC_Syntax_Syntax.Tm_abs
                 { FStarC_Syntax_Syntax.bs = bs1;
                   FStarC_Syntax_Syntax.body = uu___2;
                   FStarC_Syntax_Syntax.rc_opt = uu___3;_}
                 -> bs1
             | uu___2 -> failwith "Impossible") in
      let uu___ =
        let uu___1 = erase_binders ed.FStarC_Syntax_Syntax.binders in
        FStarC_Syntax_Subst.open_term' uu___1 FStarC_Syntax_Syntax.t_unit in
      match uu___ with
      | (binders, uu___1, binders_opening) ->
          let erase_term t =
            let uu___2 =
              let uu___3 = FStarC_Syntax_Subst.subst binders_opening t in
              erase_univs uu___3 in
            FStarC_Syntax_Subst.close binders uu___2 in
          let erase_tscheme uu___2 =
            match uu___2 with
            | (us, t) ->
                let t1 =
                  let uu___3 =
                    FStarC_Syntax_Subst.shift_subst (FStarC_List.length us)
                      binders_opening in
                  FStarC_Syntax_Subst.subst uu___3 t in
                let uu___3 =
                  let uu___4 = erase_univs t1 in
                  FStarC_Syntax_Subst.close binders uu___4 in
                ([], uu___3) in
          let erase_action action =
            let opening =
              FStarC_Syntax_Subst.shift_subst
                (FStarC_List.length action.FStarC_Syntax_Syntax.action_univs)
                binders_opening in
            let erased_action_params =
              match action.FStarC_Syntax_Syntax.action_params with
              | [] -> []
              | uu___2 ->
                  let bs =
                    let uu___3 =
                      FStarC_Syntax_Subst.subst_binders opening
                        action.FStarC_Syntax_Syntax.action_params in
                    erase_binders uu___3 in
                  let t =
                    FStarC_Syntax_Syntax.mk
                      (FStarC_Syntax_Syntax.Tm_abs
                         {
                           FStarC_Syntax_Syntax.bs = bs;
                           FStarC_Syntax_Syntax.body =
                             FStarC_Syntax_Syntax.t_unit;
                           FStarC_Syntax_Syntax.rc_opt =
                             FStar_Pervasives_Native.None
                         }) FStarC_Range_Type.dummyRange in
                  let uu___3 =
                    let uu___4 =
                      let uu___5 = FStarC_Syntax_Subst.close binders t in
                      FStarC_Syntax_Subst.compress uu___5 in
                    uu___4.FStarC_Syntax_Syntax.n in
                  (match uu___3 with
                   | FStarC_Syntax_Syntax.Tm_abs
                       { FStarC_Syntax_Syntax.bs = bs1;
                         FStarC_Syntax_Syntax.body = uu___4;
                         FStarC_Syntax_Syntax.rc_opt = uu___5;_}
                       -> bs1
                   | uu___4 -> failwith "Impossible") in
            let erase_term1 t =
              let uu___2 =
                let uu___3 = FStarC_Syntax_Subst.subst opening t in
                erase_univs uu___3 in
              FStarC_Syntax_Subst.close binders uu___2 in
            let uu___2 = erase_term1 action.FStarC_Syntax_Syntax.action_defn in
            let uu___3 = erase_term1 action.FStarC_Syntax_Syntax.action_typ in
            {
              FStarC_Syntax_Syntax.action_name =
                (action.FStarC_Syntax_Syntax.action_name);
              FStarC_Syntax_Syntax.action_unqualified_name =
                (action.FStarC_Syntax_Syntax.action_unqualified_name);
              FStarC_Syntax_Syntax.action_univs = [];
              FStarC_Syntax_Syntax.action_params = erased_action_params;
              FStarC_Syntax_Syntax.action_defn = uu___2;
              FStarC_Syntax_Syntax.action_typ = uu___3
            } in
          let uu___2 = FStarC_Syntax_Subst.close_binders binders in
          let uu___3 =
            FStarC_Syntax_Util.apply_eff_sig erase_tscheme
              ed.FStarC_Syntax_Syntax.signature in
          let uu___4 =
            FStarC_Syntax_Util.apply_eff_combinators erase_tscheme
              ed.FStarC_Syntax_Syntax.combinators in
          let uu___5 =
            FStarC_List.map erase_action ed.FStarC_Syntax_Syntax.actions in
          {
            FStarC_Syntax_Syntax.mname = (ed.FStarC_Syntax_Syntax.mname);
            FStarC_Syntax_Syntax.cattributes =
              (ed.FStarC_Syntax_Syntax.cattributes);
            FStarC_Syntax_Syntax.univs = [];
            FStarC_Syntax_Syntax.binders = uu___2;
            FStarC_Syntax_Syntax.signature = uu___3;
            FStarC_Syntax_Syntax.combinators = uu___4;
            FStarC_Syntax_Syntax.actions = uu___5;
            FStarC_Syntax_Syntax.eff_attrs =
              (ed.FStarC_Syntax_Syntax.eff_attrs);
            FStarC_Syntax_Syntax.extraction_mode =
              (ed.FStarC_Syntax_Syntax.extraction_mode)
          } in
    let push_sigelt env se =
      match se.FStarC_Syntax_Syntax.sigel with
      | FStarC_Syntax_Syntax.Sig_new_effect ed ->
          let se' =
            let uu___ =
              let uu___1 = erase_univs_ed ed in
              FStarC_Syntax_Syntax.Sig_new_effect uu___1 in
            {
              FStarC_Syntax_Syntax.sigel = uu___;
              FStarC_Syntax_Syntax.sigrng = (se.FStarC_Syntax_Syntax.sigrng);
              FStarC_Syntax_Syntax.sigquals =
                (se.FStarC_Syntax_Syntax.sigquals);
              FStarC_Syntax_Syntax.sigmeta =
                (se.FStarC_Syntax_Syntax.sigmeta);
              FStarC_Syntax_Syntax.sigattrs =
                (se.FStarC_Syntax_Syntax.sigattrs);
              FStarC_Syntax_Syntax.sigopens_and_abbrevs =
                (se.FStarC_Syntax_Syntax.sigopens_and_abbrevs);
              FStarC_Syntax_Syntax.sigopts =
                (se.FStarC_Syntax_Syntax.sigopts)
            } in
          let env1 = FStarC_Syntax_DsEnv.push_sigelt env se' in
          push_reflect_effect env1 se.FStarC_Syntax_Syntax.sigquals
            ed.FStarC_Syntax_Syntax.mname se.FStarC_Syntax_Syntax.sigrng
      | uu___ -> FStarC_Syntax_DsEnv.push_sigelt env se in
    let uu___ =
      FStarC_Syntax_DsEnv.prepare_module_or_interface false false false en
        m.FStarC_Syntax_Syntax.name mii in
    match uu___ with
    | (en1, pop_when_done) ->
        let en2 =
          let uu___1 =
            FStarC_Syntax_DsEnv.set_current_module en1
              m.FStarC_Syntax_Syntax.name in
          FStarC_List.fold_left push_sigelt uu___1
            m.FStarC_Syntax_Syntax.declarations in
        let en3 = if finish then FStarC_Syntax_DsEnv.finish en2 m else en2 in
        let uu___1 =
          if pop_when_done
          then
            FStarC_Syntax_DsEnv.export_interface m.FStarC_Syntax_Syntax.name
              en3
          else en3 in
        ((), uu___1)
let add_partial_modul_to_env :
  FStarC_Syntax_Syntax.modul ->
    FStarC_Syntax_DsEnv.module_inclusion_info ->
      (FStarC_Syntax_Syntax.term -> FStarC_Syntax_Syntax.term) ->
        unit FStarC_Syntax_DsEnv.withenv=
  add_modul_to_env_core false
let add_modul_to_env :
  FStarC_Syntax_Syntax.modul ->
    FStarC_Syntax_DsEnv.module_inclusion_info ->
      (FStarC_Syntax_Syntax.term -> FStarC_Syntax_Syntax.term) ->
        unit FStarC_Syntax_DsEnv.withenv=
  add_modul_to_env_core true
