File: .lake/packages/lean4/src/lean/Lean/Elab/App.lean

full_name: Lean.Elab.Term.initFn._@..lake.packages.lean4.src.lean.Lean.Elab.App._hyg.5
code: builtin_initialize elabWithoutExpectedTypeAttr : TagAttribute ←
  registerTagAttribute `elab_without_expected_type "mark that applications of the given declaration should be elaborated without the expected type"
goal: IO Lean.TagAttribute

full_name: Lean.Elab.Term.elabWithoutExpectedTypeAttr
code: builtin_initialize elabWithoutExpectedTypeAttr : TagAttribute ←
  registerTagAttribute `elab_without_expected_type "mark that applications of the given declaration should be elaborated without the expected type"
goal: Lean.TagAttribute

full_name: Lean.Elab.Term.hasElabWithoutExpectedType
code: def hasElabWithoutExpectedType (env : Environment) (declName : Name) : Bool 
goal: Bool

full_name: Lean.Elab.Term.«instToStringArg_.lake»
code: instance : ToString Arg 
goal: ToString Lean.Elab.Term.Arg

full_name: Lean.Elab.Term.«instToStringNamedArg_.lake»
code: instance : ToString NamedArg 
goal: ToString Lean.Elab.Term.NamedArg

full_name: Lean.Elab.Term.throwInvalidNamedArg
code: def throwInvalidNamedArg (namedArg : NamedArg) (fn? : Option Name) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ensureArgType
code: private def ensureArgType (f : Expr) (arg : Expr) (expectedType : Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.mkProjAndCheck
code: private def mkProjAndCheck (structName : Name) (idx : Nat) (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Elab.Term.synthesizeAppInstMVars
code: def synthesizeAppInstMVars (instMVars : Array MVarId) (app : Expr) : TermElabM Unit 
goal: Lean.Elab.TermElabM Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.findBinderName?
code: /-- Return `some namedArg` if `namedArgs` contains an entry for `binderName`. -/
private def findBinderName? (namedArgs : List NamedArg) (binderName : Name) : Option NamedArg 
goal: Option Lean.Elab.Term.NamedArg

full_name: Lean.Elab.Term.eraseNamedArg
code: /-- Erase entry for `binderName` from `namedArgs`. -/
def eraseNamedArg (namedArgs : List NamedArg) (binderName : Name) : List NamedArg 
goal: List Lean.Elab.Term.NamedArg

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.hasOptAutoParams
code: /-- Return true if the given type contains `OptParam` or `AutoParams` -/
private def hasOptAutoParams (type : Expr) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: Lean.Elab.Term.ElabAppArgs.Context.explicit
code: structure Context where
  /--
   `true` if `..` was used
  -/
  ellipsis      : Bool  --
  /--
   `true` if `@` modifier was used
  -/
  explicit      : Bool
  /--
    If the result type of an application is the `outParam` of some local instance, then special support may be needed
    because type class resolution interacts poorly with coercions in this kind of situation.
    This flag enables the special support.

    The idea is quite simple, if the result type is the `outParam` of some local instance, we simply
    execute `synthesizeSyntheticMVarsUsingDefault`. We added this feature to make sure examples as follows
    are correctly elaborated.
    ```lean
    class GetElem (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
      getElem (xs : Cont) (i : Idx) : Elem

    export GetElem (getElem)

    instance : GetElem (Array α) Nat α where
      getElem xs i := xs.get ⟨i, sorry⟩

    opaque f : Option Bool → Bool
    opaque g : Bool → Bool

    def bad (xs : Array Bool) : Bool :=
      let x := getElem xs 0
      f x && g x
    ```
    Without the special support, Lean fails at `g x` saying `x` has type `Option Bool` but is expected to have type `Bool`.
    From the user's point of view this is a bug, since `let x := getElem xs 0` clearly constrains `x` to be `Bool`, but
    we only obtain this information after we apply the `OfNat` default instance for `0`.

    Before converging to this solution, we have tried to create a "coercion placeholder" when `resultIsOutParamSupport = true`,
    but it did not work well in practice. For example, it failed in the example above.
  -/
  resultIsOutParamSupport : Bool
goal: Bool

full_name: Lean.Elab.Term.ElabAppArgs.Context.resultIsOutParamSupport
code: structure Context where
  /--
   `true` if `..` was used
  -/
  ellipsis      : Bool  --
  /--
   `true` if `@` modifier was used
  -/
  explicit      : Bool
  /--
    If the result type of an application is the `outParam` of some local instance, then special support may be needed
    because type class resolution interacts poorly with coercions in this kind of situation.
    This flag enables the special support.

    The idea is quite simple, if the result type is the `outParam` of some local instance, we simply
    execute `synthesizeSyntheticMVarsUsingDefault`. We added this feature to make sure examples as follows
    are correctly elaborated.
    ```lean
    class GetElem (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
      getElem (xs : Cont) (i : Idx) : Elem

    export GetElem (getElem)

    instance : GetElem (Array α) Nat α where
      getElem xs i := xs.get ⟨i, sorry⟩

    opaque f : Option Bool → Bool
    opaque g : Bool → Bool

    def bad (xs : Array Bool) : Bool :=
      let x := getElem xs 0
      f x && g x
    ```
    Without the special support, Lean fails at `g x` saying `x` has type `Option Bool` but is expected to have type `Bool`.
    From the user's point of view this is a bug, since `let x := getElem xs 0` clearly constrains `x` to be `Bool`, but
    we only obtain this information after we apply the `OfNat` default instance for `0`.

    Before converging to this solution, we have tried to create a "coercion placeholder" when `resultIsOutParamSupport = true`,
    but it did not work well in practice. For example, it failed in the example above.
  -/
  resultIsOutParamSupport : Bool
goal: Bool

full_name: Lean.Elab.Term.ElabAppArgs.Context
code: structure Context where
  /--
   `true` if `..` was used
  -/
  ellipsis      : Bool  --
  /--
   `true` if `@` modifier was used
  -/
  explicit      : Bool
  /--
    If the result type of an application is the `outParam` of some local instance, then special support may be needed
    because type class resolution interacts poorly with coercions in this kind of situation.
    This flag enables the special support.

    The idea is quite simple, if the result type is the `outParam` of some local instance, we simply
    execute `synthesizeSyntheticMVarsUsingDefault`. We added this feature to make sure examples as follows
    are correctly elaborated.
    ```lean
    class GetElem (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
      getElem (xs : Cont) (i : Idx) : Elem

    export GetElem (getElem)

    instance : GetElem (Array α) Nat α where
      getElem xs i := xs.get ⟨i, sorry⟩

    opaque f : Option Bool → Bool
    opaque g : Bool → Bool

    def bad (xs : Array Bool) : Bool :=
      let x := getElem xs 0
      f x && g x
    ```
    Without the special support, Lean fails at `g x` saying `x` has type `Option Bool` but is expected to have type `Bool`.
    From the user's point of view this is a bug, since `let x := getElem xs 0` clearly constrains `x` to be `Bool`, but
    we only obtain this information after we apply the `OfNat` default instance for `0`.

    Before converging to this solution, we have tried to create a "coercion placeholder" when `resultIsOutParamSupport = true`,
    but it did not work well in practice. For example, it failed in the example above.
  -/
  resultIsOutParamSupport : Bool
goal: Type

full_name: Lean.Elab.Term.ElabAppArgs.Context.ellipsis
code: structure Context where
  /--
   `true` if `..` was used
  -/
  ellipsis      : Bool  --
  /--
   `true` if `@` modifier was used
  -/
  explicit      : Bool
  /--
    If the result type of an application is the `outParam` of some local instance, then special support may be needed
    because type class resolution interacts poorly with coercions in this kind of situation.
    This flag enables the special support.

    The idea is quite simple, if the result type is the `outParam` of some local instance, we simply
    execute `synthesizeSyntheticMVarsUsingDefault`. We added this feature to make sure examples as follows
    are correctly elaborated.
    ```lean
    class GetElem (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
      getElem (xs : Cont) (i : Idx) : Elem

    export GetElem (getElem)

    instance : GetElem (Array α) Nat α where
      getElem xs i := xs.get ⟨i, sorry⟩

    opaque f : Option Bool → Bool
    opaque g : Bool → Bool

    def bad (xs : Array Bool) : Bool :=
      let x := getElem xs 0
      f x && g x
    ```
    Without the special support, Lean fails at `g x` saying `x` has type `Option Bool` but is expected to have type `Bool`.
    From the user's point of view this is a bug, since `let x := getElem xs 0` clearly constrains `x` to be `Bool`, but
    we only obtain this information after we apply the `OfNat` default instance for `0`.

    Before converging to this solution, we have tried to create a "coercion placeholder" when `resultIsOutParamSupport = true`,
    but it did not work well in practice. For example, it failed in the example above.
  -/
  resultIsOutParamSupport : Bool
goal: Bool

full_name: Lean.Elab.Term.ElabAppArgs.State.args
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: List Lean.Elab.Term.Arg

full_name: Lean.Elab.Term.ElabAppArgs.State.etaArgs
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Array Lean.Expr

full_name: Lean.Elab.Term.ElabAppArgs.State.f
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Lean.Expr

full_name: Lean.Elab.Term.ElabAppArgs.State.fType
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Lean.Expr

full_name: Lean.Elab.Term.ElabAppArgs.State.instMVars
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Array Lean.MVarId

full_name: Lean.Elab.Term.ElabAppArgs.State.resultTypeOutParam?
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Option Lean.MVarId

full_name: Lean.Elab.Term.ElabAppArgs.State.expectedType?
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Option Lean.Expr

full_name: Lean.Elab.Term.ElabAppArgs.State.toSetErrorCtx
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Array Lean.MVarId

full_name: Lean.Elab.Term.ElabAppArgs.State
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Type

full_name: Lean.Elab.Term.ElabAppArgs.State.propagateExpected
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: Bool

full_name: Lean.Elab.Term.ElabAppArgs.State.namedArgs
code: /-- Auxiliary structure for elaborating the application `f args namedArgs`. -/
structure State where
  f                    : Expr
  fType                : Expr
  /-- Remaining regular arguments. -/
  args                 : List Arg
  /-- remaining named arguments to be processed. -/
  namedArgs            : List NamedArg
  expectedType?        : Option Expr
  /--
    When named arguments are provided and explicit arguments occurring before them are missing,
    the elaborator eta-expands the declaration. For example,
    ```
    def f (x y : Nat) := x + y
    #check f (y := 5)
    -- fun x => f x 5
    ```
    `etaArgs` stores the fresh free variables for implementing the eta-expansion.
    When `..` is used, eta-expansion is disabled, and missing arguments are treated as `_`.
  -/
  etaArgs              : Array Expr   := #[]
  /-- Metavariables that we need to set the error context using the application being built. -/
  toSetErrorCtx        : Array MVarId := #[]
  /-- Metavariables for the instance implicit arguments that have already been processed. -/
  instMVars            : Array MVarId := #[]
  /--
    The following field is used to implement the `propagateExpectedType` heuristic.
    It is set to `true` true when `expectedType` still has to be propagated.
  -/
  propagateExpected    : Bool
  /--
    If the result type may be the `outParam` of some local instance.
    See comment at `Context.resultIsOutParamSupport`
   -/
  resultTypeOutParam?  : Option MVarId := none
goal: List Lean.Elab.Term.NamedArg

full_name: Lean.Elab.Term.ElabAppArgs.M
code: abbrev M 
goal: Type

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.addInstMVar
code: /-- Add the given metavariable to the collection of metavariables associated with instance-implicit arguments. -/
private def addInstMVar (mvarId : MVarId) : M Unit 
goal: Lean.Elab.Term.ElabAppArgs.M Unit

full_name: Lean.Elab.Term.ElabAppArgs.trySynthesizeAppInstMVars
code: /--
  Try to synthesize metavariables are `instMVars` using type class resolution.
  The ones that cannot be synthesized yet stay in the `instMVars` list.
  Remark: we use this method
    - before trying to apply coercions to function,
    - before unifying the expected type.
-/
def trySynthesizeAppInstMVars : M Unit 
goal: Lean.Elab.Term.ElabAppArgs.M Unit

full_name: Lean.Elab.Term.ElabAppArgs.synthesizeAppInstMVars
code: /--
  Try to synthesize metavariables are `instMVars` using type class resolution.
  The ones that cannot be synthesized yet are registered.
-/
def synthesizeAppInstMVars : M Unit 
goal: Lean.Elab.Term.ElabAppArgs.M Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.synthesizePendingAndNormalizeFunType
code: /-- fType may become a forallE after we synthesize pending metavariables. -/
private def synthesizePendingAndNormalizeFunType : M Unit 
goal: Lean.Elab.Term.ElabAppArgs.M Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.normalizeFunType
code: /-- Normalize and return the function type. -/
private def normalizeFunType : M Expr 
goal: Lean.Elab.Term.ElabAppArgs.M Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.getBindingName
code: /-- Return the binder name at `fType`. This method assumes `fType` is a function type. -/
private def getBindingName : M Name 
goal: Lean.Elab.Term.ElabAppArgs.M Lean.Name

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.getArgExpectedType
code: /-- Return the next argument expected type. This method assumes `fType` is a function type. -/
private def getArgExpectedType : M Expr 
goal: Lean.Elab.Term.ElabAppArgs.M Lean.Expr

full_name: Lean.Elab.Term.ElabAppArgs.eraseNamedArg
code: /-- Remove named argument with name `binderName` from `namedArgs`. -/
def eraseNamedArg (binderName : Name) : M Unit 
goal: Lean.Elab.Term.ElabAppArgs.M Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.addNewArg
code: /--
  Add a new argument to the result. That is, `f := f arg`, update `fType`.
  This method assumes `fType` is a function type. -/
private def addNewArg (argName : Name) (arg : Expr) : M Unit 
goal: Lean.Elab.Term.ElabAppArgs.M Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.elabAndAddNewArg
code: /--
  Elaborate the given `Arg` and add it to the result. See `addNewArg`.
  Recall that, `Arg` may be wrapping an already elaborated `Expr`. -/
private def elabAndAddNewArg (argName : Name) (arg : Arg) : M Unit 
goal: Lean.Elab.Term.ElabAppArgs.M Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.fTypeHasOptAutoParams
code: /-- Return true if `fType` contains `OptParam` or `AutoParams` -/
private def fTypeHasOptAutoParams : M Bool 
goal: Lean.Elab.Term.ElabAppArgs.M Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.getForallBody
code: /--
   Auxiliary function for retrieving the resulting type of a function application.
   See `propagateExpectedType`.
   Remark: `(explicit : Bool) == true` when `@` modifier is used. -/
private partial def getForallBody (explicit : Bool) : Nat → List NamedArg → Expr → Option Expr
  
goal: Nat → List Lean.Elab.Term.NamedArg → Lean.Expr → Option Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.shouldPropagateExpectedTypeFor
code: private def shouldPropagateExpectedTypeFor (nextArg : Arg) : Bool 
goal: Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.propagateExpectedType
code: /--
  Auxiliary method for propagating the expected type. We call it as soon as we find the first explicit
  argument. The goal is to propagate the expected type in applications of functions such as
  ```lean
  Add.add {α : Type u} : α → α → α
  List.cons {α : Type u} : α → List α → List α
  ```
  This is particularly useful when there applicable coercions. For example,
  assume we have a coercion from `Nat` to `Int`, and we have
  `(x : Nat)` and the expected type is `List Int`. Then, if we don't use this function,
  the elaborator will fail to elaborate
  ```
  List.cons x []
  ```
  First, the elaborator creates a new metavariable `?α` for the implicit argument `{α : Type u}`.
  Then, when it processes `x`, it assigns `?α := Nat`, and then obtains the
  resultant type `List Nat` which is **not** definitionally equal to `List Int`.
  We solve the problem by executing this method before we elaborate the first explicit argument (`x` in this example).
  This method infers that the resultant type is `List ?α` and unifies it with `List Int`.
  Then, when we elaborate `x`, the elaborate realizes the coercion from `Nat` to `Int` must be used, and the
  term
  ```
  @List.cons Int (coe x) (@List.nil Int)
  ```
  is produced.

  The method will do nothing if
  1- The resultant type depends on the remaining arguments (i.e., `!eTypeBody.hasLooseBVars`).
  2- The resultant type contains optional/auto params.

  We have considered adding the following extra conditions
    a) The resultant type does not contain any type metavariable.
    b) The resultant type contains a nontype metavariable.

  These two conditions would restrict the method to simple functions that are "morally" in
  the Hindley&Milner fragment.
  If users need to disable expected type propagation, we can add an attribute `[elab_without_expected_type]`.
-/
private def propagateExpectedType (arg : Arg) : M Unit 
goal: Lean.Elab.Term.ElabAppArgs.M Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.finalize
code: /-- This method executes after all application arguments have been processed. -/
private def finalize : M Expr 
goal: Lean.Elab.Term.ElabAppArgs.M Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.anyNamedArgDependsOnCurrent
code: /-- Return `true` if there is a named argument that depends on the next argument. -/
private def anyNamedArgDependsOnCurrent : M Bool 
goal: Lean.Elab.Term.ElabAppArgs.M Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.hasArgsToProcess
code: /-- Return `true` if there are regular or named arguments to be processed. -/
private def hasArgsToProcess : M Bool 
goal: Lean.Elab.Term.ElabAppArgs.M Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.isNextArgHole
code: /-- Return `true` if the next argument at `args` is of the form `_` -/
private def isNextArgHole : M Bool 
goal: Lean.Elab.Term.ElabAppArgs.M Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.isNextOutParamOfLocalInstanceAndResult
code: /--
  Return `true` if the next argument to be processed is the outparam of a local instance, and it the result type
  of the function.

  For example, suppose we have the class
  ```lean
  class Get (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
    get (xs : Cont) (i : Idx) : Elem
  ```
  And the current value of `fType` is
  ```
  {Cont : Type u_1} → {Idx : Type u_2} → {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then the result returned by this method is `false` since `Cont` is not the output param of any local instance.
  Now assume `fType` is
  ```
  {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then, the method returns `true` because `Elem` is an output parameter for the local instance `[self : Get Cont Idx Elem]`.

  Remark: if `resultIsOutParamSupport` is `false`, this method returns `false`.
-/
private partial def isNextOutParamOfLocalInstanceAndResult : M Bool 
goal: Lean.Elab.Term.ElabAppArgs.M Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.isNextOutParamOfLocalInstanceAndResult.isOutParamOf
code: /--
  Return `true` if the next argument to be processed is the outparam of a local instance, and it the result type
  of the function.

  For example, suppose we have the class
  ```lean
  class Get (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
    get (xs : Cont) (i : Idx) : Elem
  ```
  And the current value of `fType` is
  ```
  {Cont : Type u_1} → {Idx : Type u_2} → {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then the result returned by this method is `false` since `Cont` is not the output param of any local instance.
  Now assume `fType` is
  ```
  {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then, the method returns `true` because `Elem` is an output parameter for the local instance `[self : Get Cont Idx Elem]`.

  Remark: if `resultIsOutParamSupport` is `false`, this method returns `false`.
-/
private partial def isNextOutParamOfLocalInstanceAndResult : M Bool 
goal: Lean.MetaM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.isNextOutParamOfLocalInstanceAndResult.hasLocalInstaceWithOutParams
code: /--
  Return `true` if the next argument to be processed is the outparam of a local instance, and it the result type
  of the function.

  For example, suppose we have the class
  ```lean
  class Get (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
    get (xs : Cont) (i : Idx) : Elem
  ```
  And the current value of `fType` is
  ```
  {Cont : Type u_1} → {Idx : Type u_2} → {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then the result returned by this method is `false` since `Cont` is not the output param of any local instance.
  Now assume `fType` is
  ```
  {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then, the method returns `true` because `Elem` is an output parameter for the local instance `[self : Get Cont Idx Elem]`.

  Remark: if `resultIsOutParamSupport` is `false`, this method returns `false`.
-/
private partial def isNextOutParamOfLocalInstanceAndResult : M Bool 
goal: Lean.CoreM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.isNextOutParamOfLocalInstanceAndResult.isResultType
code: /--
  Return `true` if the next argument to be processed is the outparam of a local instance, and it the result type
  of the function.

  For example, suppose we have the class
  ```lean
  class Get (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
    get (xs : Cont) (i : Idx) : Elem
  ```
  And the current value of `fType` is
  ```
  {Cont : Type u_1} → {Idx : Type u_2} → {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then the result returned by this method is `false` since `Cont` is not the output param of any local instance.
  Now assume `fType` is
  ```
  {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then, the method returns `true` because `Elem` is an output parameter for the local instance `[self : Get Cont Idx Elem]`.

  Remark: if `resultIsOutParamSupport` is `false`, this method returns `false`.
-/
private partial def isNextOutParamOfLocalInstanceAndResult : M Bool 
goal: Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabAppArgs.isNextOutParamOfLocalInstanceAndResult.isOutParamOfLocalInstance
code: /--
  Return `true` if the next argument to be processed is the outparam of a local instance, and it the result type
  of the function.

  For example, suppose we have the class
  ```lean
  class Get (Cont : Type u) (Idx : Type v) (Elem : outParam (Type w)) where
    get (xs : Cont) (i : Idx) : Elem
  ```
  And the current value of `fType` is
  ```
  {Cont : Type u_1} → {Idx : Type u_2} → {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then the result returned by this method is `false` since `Cont` is not the output param of any local instance.
  Now assume `fType` is
  ```
  {Elem : Type u_3} → [self : Get Cont Idx Elem] → Cont → Idx → Elem
  ```
  then, the method returns `true` because `Elem` is an output parameter for the local instance `[self : Get Cont Idx Elem]`.

  Remark: if `resultIsOutParamSupport` is `false`, this method returns `false`.
-/
private partial def isNextOutParamOfLocalInstanceAndResult : M Bool 
goal: Lean.MetaM Bool

full_name: Lean.Elab.Term.initFn._@..lake.packages.lean4.src.lean.Lean.Elab.App._hyg.6695
code: builtin_initialize elabAsElim : TagAttribute ←
  registerTagAttribute `elab_as_elim
    "instructs elaborator that the arguments of the function application should be elaborated as were an eliminator"
    /-
    We apply `elab_as_elim` after compilation because this kind of attribute is not applied to auxiliary declarations
    created by the `WF` and `Structural` modules. This is an "indirect" fix for issue #1900. We should consider
    having an explicit flag in attributes to indicate whether they should be copied to auxiliary declarations or not.
    -/
    (applicationTime := .afterCompilation)
    fun declName => do
      let go : MetaM Unit := do
        let info ← getConstInfo declName
        if (← hasOptAutoParams info.type) then
          throwError "[elab_as_elim] attribute cannot be used in declarations containing optional and auto parameters"
        discard <| getElimInfo declName
      go.run' {} {}
goal: IO Lean.TagAttribute

full_name: Lean.Elab.Term.elabAsElim
code: builtin_initialize elabAsElim : TagAttribute ←
  registerTagAttribute `elab_as_elim
    "instructs elaborator that the arguments of the function application should be elaborated as were an eliminator"
    /-
    We apply `elab_as_elim` after compilation because this kind of attribute is not applied to auxiliary declarations
    created by the `WF` and `Structural` modules. This is an "indirect" fix for issue #1900. We should consider
    having an explicit flag in attributes to indicate whether they should be copied to auxiliary declarations or not.
    -/
    (applicationTime := .afterCompilation)
    fun declName => do
      let go : MetaM Unit := do
        let info ← getConstInfo declName
        if (← hasOptAutoParams info.type) then
          throwError "[elab_as_elim] attribute cannot be used in declarations containing optional and auto parameters"
        discard <| getElimInfo declName
      go.run' {} {}
goal: Lean.TagAttribute

full_name: Lean.Elab.Term.ElabElim.Context.elimInfo
code: /-- Context of the `elab_as_elim` elaboration procedure. -/
structure Context where
  elimInfo : ElimInfo
  expectedType : Expr
  /--
  Position of additional arguments that should be elaborated eagerly
  because they can contribute to the motive inference procedure.
  For example, in the following theorem the argument `h : a = b`
  should be elaborated eagerly because it contains `b` which occurs
  in `motive b`.
  ```
  theorem Eq.subst' {α} {motive : α → Prop} {a b : α} (h : a = b) : motive a → motive b
  ```
  -/
  extraArgsPos : Array Nat
goal: Lean.Meta.ElimInfo

full_name: Lean.Elab.Term.ElabElim.Context.extraArgsPos
code: /-- Context of the `elab_as_elim` elaboration procedure. -/
structure Context where
  elimInfo : ElimInfo
  expectedType : Expr
  /--
  Position of additional arguments that should be elaborated eagerly
  because they can contribute to the motive inference procedure.
  For example, in the following theorem the argument `h : a = b`
  should be elaborated eagerly because it contains `b` which occurs
  in `motive b`.
  ```
  theorem Eq.subst' {α} {motive : α → Prop} {a b : α} (h : a = b) : motive a → motive b
  ```
  -/
  extraArgsPos : Array Nat
goal: Array Nat

full_name: Lean.Elab.Term.ElabElim.Context
code: /-- Context of the `elab_as_elim` elaboration procedure. -/
structure Context where
  elimInfo : ElimInfo
  expectedType : Expr
  /--
  Position of additional arguments that should be elaborated eagerly
  because they can contribute to the motive inference procedure.
  For example, in the following theorem the argument `h : a = b`
  should be elaborated eagerly because it contains `b` which occurs
  in `motive b`.
  ```
  theorem Eq.subst' {α} {motive : α → Prop} {a b : α} (h : a = b) : motive a → motive b
  ```
  -/
  extraArgsPos : Array Nat
goal: Type

full_name: Lean.Elab.Term.ElabElim.Context.expectedType
code: /-- Context of the `elab_as_elim` elaboration procedure. -/
structure Context where
  elimInfo : ElimInfo
  expectedType : Expr
  /--
  Position of additional arguments that should be elaborated eagerly
  because they can contribute to the motive inference procedure.
  For example, in the following theorem the argument `h : a = b`
  should be elaborated eagerly because it contains `b` which occurs
  in `motive b`.
  ```
  theorem Eq.subst' {α} {motive : α → Prop} {a b : α} (h : a = b) : motive a → motive b
  ```
  -/
  extraArgsPos : Array Nat
goal: Lean.Expr

full_name: Lean.Elab.Term.ElabElim.State
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: Type

full_name: Lean.Elab.Term.ElabElim.State.instMVars
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: Array Lean.MVarId

full_name: Lean.Elab.Term.ElabElim.State.fType
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: Lean.Expr

full_name: Lean.Elab.Term.ElabElim.State.motive?
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: Option Lean.Expr

full_name: Lean.Elab.Term.ElabElim.State.f
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: Lean.Expr

full_name: Lean.Elab.Term.ElabElim.State.idx
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: Nat

full_name: Lean.Elab.Term.ElabElim.State.discrs
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: Array Lean.Expr

full_name: Lean.Elab.Term.ElabElim.State.args
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: List Lean.Elab.Term.Arg

full_name: Lean.Elab.Term.ElabElim.State.namedArgs
code: /-- State of the `elab_as_elim` elaboration procedure. -/
structure State where
  /-- The resultant expression being built. -/
  f            : Expr
  /-- `f : fType -/
  fType        : Expr
  /-- User-provided named arguments that still have to be processed. -/
  namedArgs    : List NamedArg
  /-- User-provided arguments that still have to be processed. -/
  args         : List Arg
  /-- Discriminants processed so far. -/
  discrs       : Array Expr := #[]
  /-- Instance implicit arguments collected so far. -/
  instMVars    : Array MVarId := #[]
  /-- Position of the next argument to be processed. We use it to decide whether the argument is the motive or a discriminant. -/
  idx          : Nat := 0
  /-- Store the metavariable used to represent the motive that will be computed at `finalize`. -/
  motive?      : Option Expr := none
goal: List Lean.Elab.Term.NamedArg

full_name: Lean.Elab.Term.ElabElim.M
code: abbrev M 
goal: Type

full_name: Lean.Elab.Term.ElabElim.mkMotive
code: /-- Infer the `motive` using the expected type by `kabstract`ing the discriminants. -/
def mkMotive (discrs : Array Expr) (expectedType : Expr): MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Elab.Term.ElabElim.revertArgs
code: /-- If the eliminator is over-applied, we "revert" the extra arguments. -/
def revertArgs (args : List Arg) (f : Expr) (expectedType : Expr) : TermElabM (Expr × Expr) 
goal: Lean.Elab.TermElabM (Lean.Expr × Lean.Expr)

full_name: Lean.Elab.Term.ElabElim.finalize
code: /--
Construct the resulting application after all discriminants have bee elaborated, and we have
consumed as many given arguments as possible.
-/
def finalize : M Expr 
goal: Lean.Elab.Term.ElabElim.M Lean.Expr

full_name: Lean.Elab.Term.ElabElim.getNextArg?
code: /--
Return the next argument to be processed.
The result is `.none` if it is an implicit argument which was not provided using a named argument.
The result is `.undef` if `args` is empty and `namedArgs` does contain an entry for `binderName`.
-/
def getNextArg? (binderName : Name) (binderInfo : BinderInfo) : M (LOption Arg) 
goal: Lean.Elab.Term.ElabElim.M (Lean.LOption Lean.Elab.Term.Arg)

full_name: Lean.Elab.Term.ElabElim.setMotive
code: /-- Set the `motive` field in the state. -/
def setMotive (motive : Expr) : M Unit 
goal: Lean.Elab.Term.ElabElim.M Unit

full_name: Lean.Elab.Term.ElabElim.addDiscr
code: /-- Push the given expression into the `discrs` field in the state. -/
def addDiscr (discr : Expr) : M Unit 
goal: Lean.Elab.Term.ElabElim.M Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.ElabElim.elabArg
code: /-- Elaborate the given argument with the given expected type. -/
private def elabArg (arg : Arg) (argExpectedType : Expr) : M Expr 
goal: Lean.Elab.Term.ElabElim.M Lean.Expr

full_name: Lean.Elab.Term.ElabElim.saveArgInfo
code: /-- Save information for producing error messages. -/
def saveArgInfo (arg : Expr) (binderName : Name) : M Unit 
goal: Lean.Elab.Term.ElabElim.M Unit

full_name: Lean.Elab.Term.ElabElim.mkImplicitArg
code: /-- Create an implicit argument using the given `BinderInfo`. -/
def mkImplicitArg (argExpectedType : Expr) (bi : BinderInfo) : M Expr 
goal: Lean.Elab.Term.ElabElim.M Lean.Expr

full_name: Lean.Elab.Term.ElabElim.main
code: /-- Main loop of the `elimAsElab` procedure. -/
partial def main : M Expr 
goal: Lean.Elab.Term.ElabElim.M Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.shouldElabAsElim
code: /-- Return `true` if `declName` is a candidate for `ElabElim.main` elaboration. -/
private def shouldElabAsElim (declName : Name) : CoreM Bool 
goal: Lean.CoreM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.propagateExpectedTypeFor
code: private def propagateExpectedTypeFor (f : Expr) : TermElabM Bool 
goal: Lean.Elab.TermElabM Bool

full_name: Lean.Elab.Term.elabAppArgs.isFirstOrder
code: /--
Elaborate a `f`-application using `namedArgs` and `args` as the arguments.
- `expectedType?` the expected type if available. It is used to propagate typing information only. This method does **not** ensure the result has this type.
- `explicit = true` when notation `@` is used, and implicit arguments are assumed to be provided at `namedArgs` and `args`.
- `ellipsis = true` when notation `..` is used. That is, we add `_` for missing arguments.
- `resultIsOutParamSupport` is used to control whether special support is used when processing applications of functions that return
   output parameter of some local instance. Example:
   ```
   GetElem.getElem : {Cont : Type u_1} → {Idx : Type u_2} → {elem : Type u_3} → {dom : cont → idx → Prop} → [self : GetElem cont idx elem dom] → (xs : cont) → (i : idx) → dom xs i → elem
   ```
   The result type `elem` is the output parameter of the local instance `self`.
   When this parameter is set to `true`, we execute `synthesizeSyntheticMVarsUsingDefault`. For additional details, see comment at
   `ElabAppArgs.resultIsOutParam`.
-/
def elabAppArgs (f : Expr) (namedArgs : Array NamedArg) (args : Array Arg)
    (expectedType? : Option Expr) (explicit ellipsis : Bool) (resultIsOutParamSupport := true) : TermElabM Expr 
goal: Bool

full_name: Lean.Elab.Term.elabAppArgs
code: /--
Elaborate a `f`-application using `namedArgs` and `args` as the arguments.
- `expectedType?` the expected type if available. It is used to propagate typing information only. This method does **not** ensure the result has this type.
- `explicit = true` when notation `@` is used, and implicit arguments are assumed to be provided at `namedArgs` and `args`.
- `ellipsis = true` when notation `..` is used. That is, we add `_` for missing arguments.
- `resultIsOutParamSupport` is used to control whether special support is used when processing applications of functions that return
   output parameter of some local instance. Example:
   ```
   GetElem.getElem : {Cont : Type u_1} → {Idx : Type u_2} → {elem : Type u_3} → {dom : cont → idx → Prop} → [self : GetElem cont idx elem dom] → (xs : cont) → (i : idx) → dom xs i → elem
   ```
   The result type `elem` is the output parameter of the local instance `self`.
   When this parameter is set to `true`, we execute `synthesizeSyntheticMVarsUsingDefault`. For additional details, see comment at
   `ElabAppArgs.resultIsOutParam`.
-/
def elabAppArgs (f : Expr) (namedArgs : Array NamedArg) (args : Array Arg)
    (expectedType? : Option Expr) (explicit ellipsis : Bool) (resultIsOutParamSupport := true) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: Lean.Elab.Term.elabAppArgs.elabAsElim?
code: /--
Elaborate a `f`-application using `namedArgs` and `args` as the arguments.
- `expectedType?` the expected type if available. It is used to propagate typing information only. This method does **not** ensure the result has this type.
- `explicit = true` when notation `@` is used, and implicit arguments are assumed to be provided at `namedArgs` and `args`.
- `ellipsis = true` when notation `..` is used. That is, we add `_` for missing arguments.
- `resultIsOutParamSupport` is used to control whether special support is used when processing applications of functions that return
   output parameter of some local instance. Example:
   ```
   GetElem.getElem : {Cont : Type u_1} → {Idx : Type u_2} → {elem : Type u_3} → {dom : cont → idx → Prop} → [self : GetElem cont idx elem dom] → (xs : cont) → (i : idx) → dom xs i → elem
   ```
   The result type `elem` is the output parameter of the local instance `self`.
   When this parameter is set to `true`, we execute `synthesizeSyntheticMVarsUsingDefault`. For additional details, see comment at
   `ElabAppArgs.resultIsOutParam`.
-/
def elabAppArgs (f : Expr) (namedArgs : Array NamedArg) (args : Array Arg)
    (expectedType? : Option Expr) (explicit ellipsis : Bool) (resultIsOutParamSupport := true) : TermElabM Expr 
goal: Lean.Elab.TermElabM (Option Lean.Meta.ElimInfo)

full_name: Lean.Elab.Term.elabAppArgs.getElabAsElimExtraArgsPos
code: /--
Elaborate a `f`-application using `namedArgs` and `args` as the arguments.
- `expectedType?` the expected type if available. It is used to propagate typing information only. This method does **not** ensure the result has this type.
- `explicit = true` when notation `@` is used, and implicit arguments are assumed to be provided at `namedArgs` and `args`.
- `ellipsis = true` when notation `..` is used. That is, we add `_` for missing arguments.
- `resultIsOutParamSupport` is used to control whether special support is used when processing applications of functions that return
   output parameter of some local instance. Example:
   ```
   GetElem.getElem : {Cont : Type u_1} → {Idx : Type u_2} → {elem : Type u_3} → {dom : cont → idx → Prop} → [self : GetElem cont idx elem dom] → (xs : cont) → (i : idx) → dom xs i → elem
   ```
   The result type `elem` is the output parameter of the local instance `self`.
   When this parameter is set to `true`, we execute `synthesizeSyntheticMVarsUsingDefault`. For additional details, see comment at
   `ElabAppArgs.resultIsOutParam`.
-/
def elabAppArgs (f : Expr) (namedArgs : Array NamedArg) (args : Array Arg)
    (expectedType? : Option Expr) (explicit ellipsis : Bool) (resultIsOutParamSupport := true) : TermElabM Expr 
goal: Lean.MetaM (Array Nat)

full_name: Lean.Elab.Term.LValResolution.projFn
code: /-- Auxiliary inductive datatype that represents the resolution of an `LVal`. -/
inductive LValResolution where
  | projFn   (baseStructName : Name) (structName : Name) (fieldName : Name)
  | projIdx  (structName : Name) (idx : Nat)
  | const    (baseStructName : Name) (structName : Name) (constName : Name)
  | localRec (baseName : Name) (fullName : Name) (fvar : Expr)
goal: Lean.Elab.Term.LValResolution

full_name: Lean.Elab.Term.LValResolution.projIdx
code: /-- Auxiliary inductive datatype that represents the resolution of an `LVal`. -/
inductive LValResolution where
  | projFn   (baseStructName : Name) (structName : Name) (fieldName : Name)
  | projIdx  (structName : Name) (idx : Nat)
  | const    (baseStructName : Name) (structName : Name) (constName : Name)
  | localRec (baseName : Name) (fullName : Name) (fvar : Expr)
goal: Lean.Elab.Term.LValResolution

full_name: Lean.Elab.Term.LValResolution.localRec
code: /-- Auxiliary inductive datatype that represents the resolution of an `LVal`. -/
inductive LValResolution where
  | projFn   (baseStructName : Name) (structName : Name) (fieldName : Name)
  | projIdx  (structName : Name) (idx : Nat)
  | const    (baseStructName : Name) (structName : Name) (constName : Name)
  | localRec (baseName : Name) (fullName : Name) (fvar : Expr)
goal: Lean.Elab.Term.LValResolution

full_name: Lean.Elab.Term.LValResolution
code: /-- Auxiliary inductive datatype that represents the resolution of an `LVal`. -/
inductive LValResolution where
  | projFn   (baseStructName : Name) (structName : Name) (fieldName : Name)
  | projIdx  (structName : Name) (idx : Nat)
  | const    (baseStructName : Name) (structName : Name) (constName : Name)
  | localRec (baseName : Name) (fullName : Name) (fvar : Expr)
goal: Type

full_name: Lean.Elab.Term.LValResolution.const
code: /-- Auxiliary inductive datatype that represents the resolution of an `LVal`. -/
inductive LValResolution where
  | projFn   (baseStructName : Name) (structName : Name) (fieldName : Name)
  | projIdx  (structName : Name) (idx : Nat)
  | const    (baseStructName : Name) (structName : Name) (constName : Name)
  | localRec (baseName : Name) (fullName : Name) (fvar : Expr)
goal: Lean.Elab.Term.LValResolution

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.throwLValError
code: private def throwLValError (e : Expr) (eType : Expr) (msg : MessageData) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.findMethod?
code: /--
`findMethod? env S fName`.
- If `env` contains `S ++ fName`, return `(S, S++fName)`
- Otherwise if `env` contains private name `prv` for `S ++ fName`, return `(S, prv)`, o
- Otherwise for each parent structure `S'` of  `S`, we try `findMethod? env S' fname`
-/
private partial def findMethod? (env : Environment) (structName fieldName : Name) : Option (Name × Name) 
goal: Option (Lean.Name × Lean.Name)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.findMethodAlias?
code: /--
  Return `some (structName', fullName)` if `structName ++ fieldName` is an alias for `fullName`, and
  `fullName` is of the form `structName' ++ fieldName`.

  TODO: if there is more than one applicable alias, it returns `none`. We should consider throwing an error or
  warning.
-/
private def findMethodAlias? (env : Environment) (structName fieldName : Name) : Option (Name × Name) 
goal: Option (Lean.Name × Lean.Name)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.throwInvalidFieldNotation
code: private def throwInvalidFieldNotation (e eType : Expr) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.resolveLValAux
code: private def resolveLValAux (e : Expr) (eType : Expr) (lval : LVal) : TermElabM LValResolution 
goal: Lean.Elab.TermElabM Lean.Elab.Term.LValResolution

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.consumeImplicits
code: /-- whnfCore + implicit consumption.
   Example: given `e` with `eType := {α : Type} → (fun β => List β) α `, it produces `(e ?m, List ?m)` where `?m` is fresh metavariable. -/
private partial def consumeImplicits (stx : Syntax) (e eType : Expr) (hasArgs : Bool) : TermElabM (Expr × Expr) 
goal: Lean.Elab.TermElabM (Lean.Expr × Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.resolveLValLoop
code: private partial def resolveLValLoop (lval : LVal) (e eType : Expr) (previousExceptions : Array Exception) (hasArgs : Bool) : TermElabM (Expr × LValResolution) 
goal: Lean.Elab.TermElabM (Lean.Expr × Lean.Elab.Term.LValResolution)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.resolveLVal
code: private def resolveLVal (e : Expr) (lval : LVal) (hasArgs : Bool) : TermElabM (Expr × LValResolution) 
goal: Lean.Elab.TermElabM (Lean.Expr × Lean.Elab.Term.LValResolution)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.mkBaseProjections
code: private partial def mkBaseProjections (baseStructName : Name) (structName : Name) (e : Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.typeMatchesBaseName
code: private def typeMatchesBaseName (type : Expr) (baseName : Name) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.addLValArg
code: /-- Auxiliary method for field notation. It tries to add `e` as a new argument to `args` or `namedArgs`.
   This method first finds the parameter with a type of the form `(baseName ...)`.
   When the parameter is found, if it an explicit one and `args` is big enough, we add `e` to `args`.
   Otherwise, if there isn't another parameter with the same name, we add `e` to `namedArgs`.

   Remark: `fullName` is the name of the resolved "field" access function. It is used for reporting errors -/
private def addLValArg (baseName : Name) (fullName : Name) (e : Expr) (args : Array Arg) (namedArgs : Array NamedArg) (fType : Expr)
    : TermElabM (Array Arg × Array NamedArg) 
goal: Lean.Elab.TermElabM (Array Lean.Elab.Term.Arg × Array Lean.Elab.Term.NamedArg)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.addProjTermInfo
code: /-- Adds the `TermInfo` for the field of a projection. See `Lean.Parser.Term.identProjKind`. -/
private def addProjTermInfo
    (stx            : Syntax)
    (e              : Expr)
    (expectedType?  : Option Expr := none)
    (lctx?          : Option LocalContext := none)
    (elaborator     : Name := Name.anonymous)
    (isBinder force : Bool := false)
    : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppLValsAux
code: private def elabAppLValsAux (namedArgs : Array NamedArg) (args : Array Arg) (expectedType? : Option Expr) (explicit ellipsis : Bool)
    (f : Expr) (lvals : List LVal) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppLValsAux.loop
code: private def elabAppLValsAux (namedArgs : Array NamedArg) (args : Array Arg) (expectedType? : Option Expr) (explicit ellipsis : Bool)
    (f : Expr) (lvals : List LVal) : TermElabM Expr 
goal: Lean.Expr → List Lean.Elab.Term.LVal → Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppLVals
code: private def elabAppLVals (f : Expr) (lvals : List LVal) (namedArgs : Array NamedArg) (args : Array Arg)
    (expectedType? : Option Expr) (explicit ellipsis : Bool) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: Lean.Elab.Term.elabExplicitUnivs
code: def elabExplicitUnivs (lvls : Array Syntax) : TermElabM (List Level) 
goal: Lean.Elab.TermElabM (List Lean.Level)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppFnId.toLVals
code: private partial def elabAppFnId (fIdent : Syntax) (fExplicitUnivs : List Level) (lvals : List LVal)
    (namedArgs : Array NamedArg) (args : Array Arg) (expectedType? : Option Expr) (explicit ellipsis overloaded : Bool) (acc : Array (TermElabResult Expr))
    : TermElabM (Array (TermElabResult Expr)) 
goal: List Lean.Syntax → Bool → List Lean.Elab.Term.LVal

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppFnId.toName
code: private partial def elabAppFnId (fIdent : Syntax) (fExplicitUnivs : List Level) (lvals : List LVal)
    (namedArgs : Array NamedArg) (args : Array Arg) (expectedType? : Option Expr) (explicit ellipsis overloaded : Bool) (acc : Array (TermElabResult Expr))
    : TermElabM (Array (TermElabResult Expr)) 
goal: Lean.Name

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppFnId
code: private partial def elabAppFnId (fIdent : Syntax) (fExplicitUnivs : List Level) (lvals : List LVal)
    (namedArgs : Array NamedArg) (args : Array Arg) (expectedType? : Option Expr) (explicit ellipsis overloaded : Bool) (acc : Array (TermElabResult Expr))
    : TermElabM (Array (TermElabResult Expr)) 
goal: Lean.Elab.TermElabM (Array (Lean.Elab.Term.TermElabResult Lean.Expr))

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppFnId.toName.go
code: private partial def elabAppFnId (fIdent : Syntax) (fExplicitUnivs : List Level) (lvals : List LVal)
    (namedArgs : Array NamedArg) (args : Array Arg) (expectedType? : Option Expr) (explicit ellipsis overloaded : Bool) (acc : Array (TermElabResult Expr))
    : TermElabM (Array (TermElabResult Expr)) 
goal: List Lean.Syntax → Lean.Name

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.resolveDotName
code: /-- Resolve `(.$id:ident)` using the expected type to infer namespace. -/
private partial def resolveDotName (id : Syntax) (expectedType? : Option Expr) : TermElabM Name 
goal: Lean.Elab.TermElabM Lean.Name

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.resolveDotName.go
code: /-- Resolve `(.$id:ident)` using the expected type to infer namespace. -/
private partial def resolveDotName (id : Syntax) (expectedType? : Option Expr) : TermElabM Name 
goal: Lean.Elab.TermElabM Lean.Name

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppFn
code: private partial def elabAppFn (f : Syntax) (lvals : List LVal) (namedArgs : Array NamedArg) (args : Array Arg)
    (expectedType? : Option Expr) (explicit ellipsis overloaded : Bool) (acc : Array (TermElabResult Expr)) : TermElabM (Array (TermElabResult Expr)) 
goal: Lean.Elab.TermElabM (Array (Lean.Elab.Term.TermElabResult Lean.Expr))

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.getSuccesses
code: /-- Return the successful candidates. Recall we have Syntax `choice` nodes and overloaded symbols when we open multiple namespaces. -/
private def getSuccesses (candidates : Array (TermElabResult Expr)) : TermElabM (Array (TermElabResult Expr)) 
goal: Lean.Elab.TermElabM (Array (Lean.Elab.Term.TermElabResult Lean.Expr))

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.mergeFailures
code: /--
  Throw an error message that describes why each possible interpretation for the overloaded notation and symbols did not work.
  We use a nested error message to aggregate the exceptions produced by each failure.
-/
private def mergeFailures (failures : Array (TermElabResult Expr)) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAppAux
code: private def elabAppAux (f : Syntax) (namedArgs : Array NamedArg) (args : Array Arg) (ellipsis : Bool) (expectedType? : Option Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.annotateIfRec
code: /--
  We annotate recursive applications with their `Syntax` node to make sure we can produce error messages with
  correct position information at `WF` and `Structural`.
-/
-- TODO: It is overkill to store the whole `Syntax` object, and we have to make sure we erase it later.
-- We should store only the position information in the future.
-- Recall that we will need to have a compact way of storing position information in the future anyway, if we
-- want to support debugging information
private def annotateIfRec (stx : Syntax) (e : Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: Lean.Elab.Term.elabApp
code: @[builtin_term_elab app] def elabApp : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.App.0.Lean.Elab.Term.elabAtom
code: private def elabAtom : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabIdent
code: @[builtin_term_elab ident] def elabIdent : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabNamedPattern
code: @[builtin_term_elab namedPattern] def elabNamedPattern : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabDotIdent
code: @[builtin_term_elab dotIdent] def elabDotIdent : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabExplicitUniv
code: @[builtin_term_elab explicitUniv] def elabExplicitUniv : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabPipeProj
code: @[builtin_term_elab pipeProj] def elabPipeProj : TermElab
  
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabExplicit
code: @[builtin_term_elab explicit] def elabExplicit : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabChoice
code: @[builtin_term_elab choice] def elabChoice : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabProj
code: @[builtin_term_elab proj] def elabProj : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.initFn._@..lake.packages.lean4.src.lean.Lean.Elab.App._hyg.20863
code: builtin_initialize
  registerTraceClass `Elab.app
  registerTraceClass `Elab.app.args (inherited := true)
  registerTraceClass `Elab.app.propagateExpectedType (inherited := true)
  registerTraceClass `Elab.app.finalize (inherited := true)
goal: IO Unit