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

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.expandSimpleMatch
code: private def expandSimpleMatch (stx : Syntax) (discr : Term) (lhsVar : Ident) (rhs : Term) (expectedType? : Option Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.mkUserNameFor
code: private def mkUserNameFor (e : Expr) : TermElabM Name 
goal: Lean.Elab.TermElabM Lean.Name

full_name: Lean.Elab.Term.isAtomicDiscr
code: /--
   Remark: if the discriminat is `Systax.missing`, we abort the elaboration of the `match`-expression.
   This can happen due to error recovery. Example
   ```
   example : (p ∨ p) → p := fun h => match
   ```
   If we don't abort, the elaborator loops because we will keep trying to expand
   ```
   match
   ```
   into
   ```
   let d := <Syntax.missing>; match
   ```
   Recall that `Syntax.setArg stx i arg` is a no-op when `i` is out-of-bounds. -/
def isAtomicDiscr (discr : Syntax) : TermElabM Bool 
goal: Lean.Elab.TermElabM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabAtomicDiscr
code: private def elabAtomicDiscr (discr : Syntax) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: Lean.Elab.Term.Discr.expr
code: structure Discr where
  expr : Expr
  /-- `some h` if discriminant is annotated with the `h : ` notation. -/
  h?  : Option Syntax := none
  deriving Inhabited
goal: Lean.Expr

full_name: Lean.Elab.Term.Discr
code: structure Discr where
  expr : Expr
  /-- `some h` if discriminant is annotated with the `h : ` notation. -/
  h?  : Option Syntax := none
  deriving Inhabited
goal: Type

full_name: Lean.Elab.Term.instInhabitedDiscr
code: structure Discr where
  expr : Expr
  /-- `some h` if discriminant is annotated with the `h : ` notation. -/
  h?  : Option Syntax := none
  deriving Inhabited
goal: Inhabited Lean.Elab.Term.Discr

full_name: Lean.Elab.Term.Discr.h?
code: structure Discr where
  expr : Expr
  /-- `some h` if discriminant is annotated with the `h : ` notation. -/
  h?  : Option Syntax := none
  deriving Inhabited
goal: Option Lean.Syntax

full_name: Lean.Elab.Term.ElabMatchTypeAndDiscrsResult.matchType
code: structure ElabMatchTypeAndDiscrsResult where
  discrs    : Array Discr
  matchType : Expr
  /-- `true` when performing dependent elimination. We use this to decide whether we optimize the "match unit" case.
     See `isMatchUnit?`. -/
  isDep     : Bool
  alts      : Array MatchAltView
goal: Lean.Expr

full_name: Lean.Elab.Term.ElabMatchTypeAndDiscrsResult
code: structure ElabMatchTypeAndDiscrsResult where
  discrs    : Array Discr
  matchType : Expr
  /-- `true` when performing dependent elimination. We use this to decide whether we optimize the "match unit" case.
     See `isMatchUnit?`. -/
  isDep     : Bool
  alts      : Array MatchAltView
goal: Type

full_name: Lean.Elab.Term.ElabMatchTypeAndDiscrsResult.isDep
code: structure ElabMatchTypeAndDiscrsResult where
  discrs    : Array Discr
  matchType : Expr
  /-- `true` when performing dependent elimination. We use this to decide whether we optimize the "match unit" case.
     See `isMatchUnit?`. -/
  isDep     : Bool
  alts      : Array MatchAltView
goal: Bool

full_name: Lean.Elab.Term.ElabMatchTypeAndDiscrsResult.alts
code: structure ElabMatchTypeAndDiscrsResult where
  discrs    : Array Discr
  matchType : Expr
  /-- `true` when performing dependent elimination. We use this to decide whether we optimize the "match unit" case.
     See `isMatchUnit?`. -/
  isDep     : Bool
  alts      : Array MatchAltView
goal: Array Lean.Elab.Term.MatchAltView

full_name: Lean.Elab.Term.ElabMatchTypeAndDiscrsResult.discrs
code: structure ElabMatchTypeAndDiscrsResult where
  discrs    : Array Discr
  matchType : Expr
  /-- `true` when performing dependent elimination. We use this to decide whether we optimize the "match unit" case.
     See `isMatchUnit?`. -/
  isDep     : Bool
  alts      : Array MatchAltView
goal: Array Lean.Elab.Term.Discr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchTypeAndDiscrs.elabDiscrs
code: private partial def elabMatchTypeAndDiscrs (discrStxs : Array Syntax) (matchOptMotive : Syntax) (matchAltViews : Array MatchAltView) (expectedType : Expr)
      : TermElabM ElabMatchTypeAndDiscrsResult 
goal: Lean.Elab.TermElabM Lean.Elab.Term.ElabMatchTypeAndDiscrsResult

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchTypeAndDiscrs.elabDiscrsWitMatchType
code: private partial def elabMatchTypeAndDiscrs (discrStxs : Array Syntax) (matchOptMotive : Syntax) (matchAltViews : Array MatchAltView) (expectedType : Expr)
      : TermElabM ElabMatchTypeAndDiscrsResult 
goal: Lean.Elab.TermElabM (Array Lean.Elab.Term.Discr × Bool)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchTypeAndDiscrs.markIsDep
code: private partial def elabMatchTypeAndDiscrs (discrStxs : Array Syntax) (matchOptMotive : Syntax) (matchAltViews : Array MatchAltView) (expectedType : Expr)
      : TermElabM ElabMatchTypeAndDiscrsResult 
goal: Lean.Elab.Term.ElabMatchTypeAndDiscrsResult

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchTypeAndDiscrs
code: private partial def elabMatchTypeAndDiscrs (discrStxs : Array Syntax) (matchOptMotive : Syntax) (matchAltViews : Array MatchAltView) (expectedType : Expr)
      : TermElabM ElabMatchTypeAndDiscrsResult 
goal: Lean.Elab.TermElabM Lean.Elab.Term.ElabMatchTypeAndDiscrsResult

full_name: Lean.Elab.Term.expandMacrosInPatterns
code: def expandMacrosInPatterns (matchAlts : Array MatchAltView) : MacroM (Array MatchAltView) 
goal: Lean.MacroM (Array Lean.Elab.Term.MatchAltView)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.getMatchGeneralizing?
code: private def getMatchGeneralizing? : Syntax → Option Bool
  
goal: Lean.Syntax → Option Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.getMatchAlts
code: /-- Given `stx` a match-expression, return its alternatives. -/
private def getMatchAlts : Syntax → Array MatchAltView
  
goal: Lean.Syntax → Array Lean.Elab.Term.MatchAltView

full_name: Lean.Elab.Term.elabInaccessible
code: @[builtin_term_elab inaccessible] def elabInaccessible : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.precheckMatch
code: @[builtin_quot_precheck Lean.Parser.Term.match] def precheckMatch : Precheck
  
goal: Lean.Elab.Term.Quotation.Precheck

full_name: Lean.Elab.Term.PatternVarDecl
code: /-- We convert the collected `PatternVar`s intro `PatternVarDecl` -/
structure PatternVarDecl where
  fvarId : FVarId
goal: Type

full_name: Lean.Elab.Term.PatternVarDecl.fvarId
code: /-- We convert the collected `PatternVar`s intro `PatternVarDecl` -/
structure PatternVarDecl where
  fvarId : FVarId
goal: Lean.FVarId

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.withPatternVars
code: private partial def withPatternVars {α} (pVars : Array PatternVar) (k : Array PatternVarDecl → TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.withPatternVars.loop
code: private partial def withPatternVars {α} (pVars : Array PatternVar) (k : Array PatternVarDecl → TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: Lean.Elab.Term.PatternElabException.patternIdx
code: /-- Auxiliary structure for storing an type mismatch exception when processing the
   pattern #`idx` of some alternative. -/
structure PatternElabException where
  ex          : Exception
  patternIdx  : Nat -- Discriminant that sh
  pathToIndex : List Nat
goal: Nat

full_name: Lean.Elab.Term.PatternElabException.pathToIndex
code: /-- Auxiliary structure for storing an type mismatch exception when processing the
   pattern #`idx` of some alternative. -/
structure PatternElabException where
  ex          : Exception
  patternIdx  : Nat -- Discriminant that sh
  pathToIndex : List Nat
goal: List Nat

full_name: Lean.Elab.Term.PatternElabException
code: /-- Auxiliary structure for storing an type mismatch exception when processing the
   pattern #`idx` of some alternative. -/
structure PatternElabException where
  ex          : Exception
  patternIdx  : Nat -- Discriminant that sh
  pathToIndex : List Nat
goal: Type

full_name: Lean.Elab.Term.PatternElabException.ex
code: /-- Auxiliary structure for storing an type mismatch exception when processing the
   pattern #`idx` of some alternative. -/
structure PatternElabException where
  ex          : Exception
  patternIdx  : Nat -- Discriminant that sh
  pathToIndex : List Nat
goal: Lean.Exception

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.findDiscrRefinementPath.checkCompatibleApps
code: /--
  This method is part of the "discriminant refinement" procedure. It in invoked when the
  type of the `pattern` does not match the expected type. The expected type is based on the
  motive computed using the `match` discriminants.
  It tries to compute a path to an index of the discriminant type.
  For example, suppose the user has written
  ```
  inductive Mem (a : α) : List α → Prop where
    | head {as} : Mem a (a::as)
    | tail {as} : Mem a as → Mem a (a'::as)

  infix:50 " ∈ " => Mem

  example (a b : Nat) (h : a ∈ [b]) : b = a :=
  match h with
  | Mem.head => rfl
  ```
  The motive for the match is `a ∈ [b] → b = a`, and get a type mismatch between the type
  of `Mem.head` and `a ∈ [b]`. This procedure return the path `[2, 1]` to the index `b`.
  We use it to produce the following refinement
  ```
  example (a b : Nat) (h : a ∈ [b]) : b = a :=
  match b, h with
  | _, Mem.head => rfl
  ```
  which produces the new motive `(x : Nat) →  a ∈ [x] → x = a`
  After this refinement step, the `match` is elaborated successfully.

  This method relies on the fact that the dependent pattern matcher compiler solves equations
  between indices of indexed inductive families.
  The following kinds of equations are supported by this compiler:
  - `x = t`
  - `t = x`
  - `ctor ... = ctor ...`

  where `x` is a free variable, `t` is an arbitrary term, and `ctor` is constructor.
  Our procedure ensures that "information" is not lost, and will *not* succeed in an
  example such as
  ```
  example (a b : Nat) (f : Nat → Nat) (h : f a ∈ [f b]) : f b = f a :=
    match h with
    | Mem.head => rfl
  ```
  and will not add `f b` as a new discriminant. We may add an option in the future to
  enable this more liberal form of refinement.
-/
private partial def findDiscrRefinementPath (pattern : Expr) (expected : Expr) : OptionT MetaM (List Nat) 
goal: OptionT Lean.MetaM Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.findDiscrRefinementPath
code: /--
  This method is part of the "discriminant refinement" procedure. It in invoked when the
  type of the `pattern` does not match the expected type. The expected type is based on the
  motive computed using the `match` discriminants.
  It tries to compute a path to an index of the discriminant type.
  For example, suppose the user has written
  ```
  inductive Mem (a : α) : List α → Prop where
    | head {as} : Mem a (a::as)
    | tail {as} : Mem a as → Mem a (a'::as)

  infix:50 " ∈ " => Mem

  example (a b : Nat) (h : a ∈ [b]) : b = a :=
  match h with
  | Mem.head => rfl
  ```
  The motive for the match is `a ∈ [b] → b = a`, and get a type mismatch between the type
  of `Mem.head` and `a ∈ [b]`. This procedure return the path `[2, 1]` to the index `b`.
  We use it to produce the following refinement
  ```
  example (a b : Nat) (h : a ∈ [b]) : b = a :=
  match b, h with
  | _, Mem.head => rfl
  ```
  which produces the new motive `(x : Nat) →  a ∈ [x] → x = a`
  After this refinement step, the `match` is elaborated successfully.

  This method relies on the fact that the dependent pattern matcher compiler solves equations
  between indices of indexed inductive families.
  The following kinds of equations are supported by this compiler:
  - `x = t`
  - `t = x`
  - `ctor ... = ctor ...`

  where `x` is a free variable, `t` is an arbitrary term, and `ctor` is constructor.
  Our procedure ensures that "information" is not lost, and will *not* succeed in an
  example such as
  ```
  example (a b : Nat) (f : Nat → Nat) (h : f a ∈ [f b]) : f b = f a :=
    match h with
    | Mem.head => rfl
  ```
  and will not add `f b` as a new discriminant. We may add an option in the future to
  enable this more liberal form of refinement.
-/
private partial def findDiscrRefinementPath (pattern : Expr) (expected : Expr) : OptionT MetaM (List Nat) 
goal: OptionT Lean.MetaM (List Nat)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.findDiscrRefinementPath.goIndex
code: /--
  This method is part of the "discriminant refinement" procedure. It in invoked when the
  type of the `pattern` does not match the expected type. The expected type is based on the
  motive computed using the `match` discriminants.
  It tries to compute a path to an index of the discriminant type.
  For example, suppose the user has written
  ```
  inductive Mem (a : α) : List α → Prop where
    | head {as} : Mem a (a::as)
    | tail {as} : Mem a as → Mem a (a'::as)

  infix:50 " ∈ " => Mem

  example (a b : Nat) (h : a ∈ [b]) : b = a :=
  match h with
  | Mem.head => rfl
  ```
  The motive for the match is `a ∈ [b] → b = a`, and get a type mismatch between the type
  of `Mem.head` and `a ∈ [b]`. This procedure return the path `[2, 1]` to the index `b`.
  We use it to produce the following refinement
  ```
  example (a b : Nat) (h : a ∈ [b]) : b = a :=
  match b, h with
  | _, Mem.head => rfl
  ```
  which produces the new motive `(x : Nat) →  a ∈ [x] → x = a`
  After this refinement step, the `match` is elaborated successfully.

  This method relies on the fact that the dependent pattern matcher compiler solves equations
  between indices of indexed inductive families.
  The following kinds of equations are supported by this compiler:
  - `x = t`
  - `t = x`
  - `ctor ... = ctor ...`

  where `x` is a free variable, `t` is an arbitrary term, and `ctor` is constructor.
  Our procedure ensures that "information" is not lost, and will *not* succeed in an
  example such as
  ```
  example (a b : Nat) (f : Nat → Nat) (h : f a ∈ [f b]) : f b = f a :=
    match h with
    | Mem.head => rfl
  ```
  and will not add `f b` as a new discriminant. We may add an option in the future to
  enable this more liberal form of refinement.
-/
private partial def findDiscrRefinementPath (pattern : Expr) (expected : Expr) : OptionT MetaM (List Nat) 
goal: OptionT Lean.MetaM (List Nat)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.findDiscrRefinementPath.goType
code: /--
  This method is part of the "discriminant refinement" procedure. It in invoked when the
  type of the `pattern` does not match the expected type. The expected type is based on the
  motive computed using the `match` discriminants.
  It tries to compute a path to an index of the discriminant type.
  For example, suppose the user has written
  ```
  inductive Mem (a : α) : List α → Prop where
    | head {as} : Mem a (a::as)
    | tail {as} : Mem a as → Mem a (a'::as)

  infix:50 " ∈ " => Mem

  example (a b : Nat) (h : a ∈ [b]) : b = a :=
  match h with
  | Mem.head => rfl
  ```
  The motive for the match is `a ∈ [b] → b = a`, and get a type mismatch between the type
  of `Mem.head` and `a ∈ [b]`. This procedure return the path `[2, 1]` to the index `b`.
  We use it to produce the following refinement
  ```
  example (a b : Nat) (h : a ∈ [b]) : b = a :=
  match b, h with
  | _, Mem.head => rfl
  ```
  which produces the new motive `(x : Nat) →  a ∈ [x] → x = a`
  After this refinement step, the `match` is elaborated successfully.

  This method relies on the fact that the dependent pattern matcher compiler solves equations
  between indices of indexed inductive families.
  The following kinds of equations are supported by this compiler:
  - `x = t`
  - `t = x`
  - `ctor ... = ctor ...`

  where `x` is a free variable, `t` is an arbitrary term, and `ctor` is constructor.
  Our procedure ensures that "information" is not lost, and will *not* succeed in an
  example such as
  ```
  example (a b : Nat) (f : Nat → Nat) (h : f a ∈ [f b]) : f b = f a :=
    match h with
    | Mem.head => rfl
  ```
  and will not add `f b` as a new discriminant. We may add an option in the future to
  enable this more liberal form of refinement.
-/
private partial def findDiscrRefinementPath (pattern : Expr) (expected : Expr) : OptionT MetaM (List Nat) 
goal: OptionT Lean.MetaM (List Nat)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.eraseIndices
code: private partial def eraseIndices (type : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.withPatternElabConfig
code: private def withPatternElabConfig (x : TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabPatterns
code: private def elabPatterns (patternStxs : Array Syntax) (matchType : Expr) : ExceptT PatternElabException TermElabM (Array Expr × Expr) 
goal: ExceptT Lean.Elab.Term.PatternElabException Lean.Elab.TermElabM (Array Lean.Expr × Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.throwInvalidPattern
code: private def throwInvalidPattern (e : Expr) : MetaM α 
goal: Lean.MetaM α

full_name: Lean.Elab.Term.ToDepElimPattern.State
code: structure State where
  patternVars : Array Expr := #[]
goal: Type

full_name: Lean.Elab.Term.ToDepElimPattern.State.patternVars
code: structure State where
  patternVars : Array Expr := #[]
goal: Array Lean.Expr

full_name: Lean.Elab.Term.ToDepElimPattern.Context.explicitPatternVars
code: structure Context where
  /--
    When visiting an assigned metavariable, if it has an user-name. We save it here.
    We want to preserve these user-names when generating new pattern variables. -/
  userName : Name := Name.anonymous
  /--
    Pattern variables that were explicitly provided by the user.
    Recall that implicit parameters and `_` are elaborated as metavariables, and then converted into pattern variables
    by the `normalize` procedure.
  -/
  explicitPatternVars : Array FVarId := #[]
goal: Array Lean.FVarId

full_name: Lean.Elab.Term.ToDepElimPattern.Context.userName
code: structure Context where
  /--
    When visiting an assigned metavariable, if it has an user-name. We save it here.
    We want to preserve these user-names when generating new pattern variables. -/
  userName : Name := Name.anonymous
  /--
    Pattern variables that were explicitly provided by the user.
    Recall that implicit parameters and `_` are elaborated as metavariables, and then converted into pattern variables
    by the `normalize` procedure.
  -/
  explicitPatternVars : Array FVarId := #[]
goal: Lean.Name

full_name: Lean.Elab.Term.ToDepElimPattern.Context
code: structure Context where
  /--
    When visiting an assigned metavariable, if it has an user-name. We save it here.
    We want to preserve these user-names when generating new pattern variables. -/
  userName : Name := Name.anonymous
  /--
    Pattern variables that were explicitly provided by the user.
    Recall that implicit parameters and `_` are elaborated as metavariables, and then converted into pattern variables
    by the `normalize` procedure.
  -/
  explicitPatternVars : Array FVarId := #[]
goal: Type

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

full_name: Lean.Elab.Term.ToDepElimPattern.isExplicitPatternVar
code: /-- Return true iff `e` is an explicit pattern variable provided by the user. -/
def isExplicitPatternVar (e : Expr) : M Bool 
goal: Lean.Elab.Term.ToDepElimPattern.M Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.withMVar
code: /--
  Helper function for "saving" the user name associated with `mvarId` (if it is not "anonymous") before visiting `x`
  The auto generalization feature will uses synthetic holes to preserve the name of the free variable included during generalization.
  For example, if we are generalizing a free variable `bla`, we add the synthetic hole `?bla` for the pattern. We use synthetic hole
  because we don't know whether `?bla` will become an inaccessible pattern or not.
  The `withMVar` method makes sure we don't "lose" this name when `isDefEq` perform assignments of the form `?bla := ?m` where `?m` has no user name.
  This can happen, for example, when the user provides a `_` pattern, or for implicit fields.
-/
private def withMVar (mvarId : MVarId) (x : M α) : M α 
goal: Lean.Elab.Term.ToDepElimPattern.M α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.mkPatternRefMap.go
code: /--
  Creating a mapping containing `b ↦ e'` where `patternWithRef e' = some (stx, b)`,
  and `e'` is a subterm of `e`.

  This is a helper function for `whnfPreservingPatternRef`. -/
private def mkPatternRefMap (e : Expr) : ExprMap Expr 
goal: ST σ (Lean.ExprMap Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.mkPatternRefMap
code: /--
  Creating a mapping containing `b ↦ e'` where `patternWithRef e' = some (stx, b)`,
  and `e'` is a subterm of `e`.

  This is a helper function for `whnfPreservingPatternRef`. -/
private def mkPatternRefMap (e : Expr) : ExprMap Expr 
goal: Lean.ExprMap Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.applyRefMap
code: /--
  Try to restore `Syntax` ref information stored in `map` after
  applying `whnf` at `whnfPreservingPatternRef`.
  It assumes `map` has been constructed using `mkPatternRefMap`.
-/
private def applyRefMap (e : Expr) (map : ExprMap Expr) : Expr 
goal: Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.whnfPreservingPatternRef
code: /--
  Applies `whnf` but tries to preserve `PatternWithRef` information.
  This is a bit hackish, but it is necessary for providing proper
  jump-to-definition information in examples such as
  ```
  def f (x : Nat) : Nat :=
    match x with
    | 0 => 1
    | y + 1 => y
  ```
  Without this trick, the `PatternWithRef` is lost for the `y` at the pattern `y+1`.
-/
private def whnfPreservingPatternRef (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Elab.Term.ToDepElimPattern.normalize.processInaccessible
code: /--
  Normalize the pattern and collect all patterns variables (explicit and implicit).
  This method is the one that decides where the inaccessible annotations must be inserted.
  The pattern variables are both free variables (for explicit pattern variables) and metavariables (for implicit ones).
  Recall that `mkLambdaFVars` now allows us to abstract both free variables and metavariables.
-/
partial def normalize (e : Expr) : M Expr 
goal: Lean.Elab.Term.ToDepElimPattern.M Lean.Expr

full_name: Lean.Elab.Term.ToDepElimPattern.normalize.addVar
code: /--
  Normalize the pattern and collect all patterns variables (explicit and implicit).
  This method is the one that decides where the inaccessible annotations must be inserted.
  The pattern variables are both free variables (for explicit pattern variables) and metavariables (for implicit ones).
  Recall that `mkLambdaFVars` now allows us to abstract both free variables and metavariables.
-/
partial def normalize (e : Expr) : M Expr 
goal: Lean.Elab.Term.ToDepElimPattern.M Unit

full_name: Lean.Elab.Term.ToDepElimPattern.normalize.processVar
code: /--
  Normalize the pattern and collect all patterns variables (explicit and implicit).
  This method is the one that decides where the inaccessible annotations must be inserted.
  The pattern variables are both free variables (for explicit pattern variables) and metavariables (for implicit ones).
  Recall that `mkLambdaFVars` now allows us to abstract both free variables and metavariables.
-/
partial def normalize (e : Expr) : M Expr 
goal: Lean.Elab.Term.ToDepElimPattern.M Lean.Expr

full_name: Lean.Elab.Term.ToDepElimPattern.normalize
code: /--
  Normalize the pattern and collect all patterns variables (explicit and implicit).
  This method is the one that decides where the inaccessible annotations must be inserted.
  The pattern variables are both free variables (for explicit pattern variables) and metavariables (for implicit ones).
  Recall that `mkLambdaFVars` now allows us to abstract both free variables and metavariables.
-/
partial def normalize (e : Expr) : M Expr 
goal: Lean.Elab.Term.ToDepElimPattern.M Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.packMatchTypePatterns
code: /--
  Auxiliary function for combining the `matchType` and all patterns into a single expression.
  We use it before we abstract all patterns variables. -/
private partial def packMatchTypePatterns (matchType : Expr) (ps : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.unpackMatchTypePatterns
code: /-- The inverse of `packMatchTypePatterns`. -/
private partial def unpackMatchTypePatterns (p : Expr) : Expr × Array Expr 
goal: Lean.Expr × Array Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.toPattern
code: /--
  Convert a (normalized) pattern encoded as an `Expr` into a `Pattern`.
  This method assumes that `e` has been normalized and the explicit and implicit (i.e., metavariables) pattern variables have
  already been abstracted and converted back into new free variables.
 -/
private partial def toPattern (e : Expr) : MetaM Pattern 
goal: Lean.MetaM Lean.Meta.Match.Pattern

full_name: Lean.Elab.Term.ToDepElimPattern.TopSort.State.result
code: structure TopSort.State where
  visitedFVars : FVarIdSet := {}
  visitedMVars : MVarIdSet := {}
  result       : Array Expr := #[]
goal: Array Lean.Expr

full_name: Lean.Elab.Term.ToDepElimPattern.TopSort.State
code: structure TopSort.State where
  visitedFVars : FVarIdSet := {}
  visitedMVars : MVarIdSet := {}
  result       : Array Expr := #[]
goal: Type

full_name: Lean.Elab.Term.ToDepElimPattern.TopSort.State.visitedFVars
code: structure TopSort.State where
  visitedFVars : FVarIdSet := {}
  visitedMVars : MVarIdSet := {}
  result       : Array Expr := #[]
goal: Lean.FVarIdSet

full_name: Lean.Elab.Term.ToDepElimPattern.TopSort.State.visitedMVars
code: structure TopSort.State where
  visitedFVars : FVarIdSet := {}
  visitedMVars : MVarIdSet := {}
  result       : Array Expr := #[]
goal: Lean.MVarIdSet

full_name: Lean.Elab.Term.ToDepElimPattern.TopSortM
code: abbrev TopSortM 
goal: Type

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.topSort
code: /--
  Topological sort. We need it because inaccessible patterns may contain pattern variables that are declared later.
  That is, processing patterns from left to right to do not guarantee that the pattern variables are collected in the
  "right" order. "Right" here means pattern `x` must occur before pattern `y` if `y`s type depends on `x`.
-/
private partial def topSort (patternVars : Array Expr) : TermElabM (Array Expr) 
goal: Lean.Elab.TermElabM (Array Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.ToDepElimPattern.topSort.visit
code: /--
  Topological sort. We need it because inaccessible patterns may contain pattern variables that are declared later.
  That is, processing patterns from left to right to do not guarantee that the pattern variables are collected in the
  "right" order. "Right" here means pattern `x` must occur before pattern `y` if `y`s type depends on `x`.
-/
private partial def topSort (patternVars : Array Expr) : TermElabM (Array Expr) 
goal: Lean.Elab.Term.ToDepElimPattern.TopSortM Unit

full_name: Lean.Elab.Term.ToDepElimPattern.savePatternInfo.go
code: /--
  Save pattern information in the info tree, and remove `patternWithRef?` annotations.
-/
partial def savePatternInfo (p : Expr) : TermElabM Expr 
goal: ReaderT Bool Lean.Elab.TermElabM Lean.Expr

full_name: Lean.Elab.Term.ToDepElimPattern.savePatternInfo
code: /--
  Save pattern information in the info tree, and remove `patternWithRef?` annotations.
-/
partial def savePatternInfo (p : Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: Lean.Elab.Term.ToDepElimPattern.main.pack
code: /--
  Main method for `withDepElimPatterns`.
  - `PatternVarDecls`: are the explicit pattern variables provided by the user.
  - `ps`: are the patterns provided by the user.
  - `matchType`: the expected typ for this branch. It depends on the explicit pattern variables and the implicit ones that are still represented as metavariables,
     and are found by this function.
  - `k` is the continuation that is executed in an updated local context with the all pattern variables (explicit and implicit). Note that, `patternVarDecls` are all
     replaced since they may depend on implicit pattern variables (i.e., metavariables) that are converted into new free variables by this method.
 -/
partial def main (patternVarDecls : Array PatternVarDecl) (ps : Array Expr) (matchType : Expr) (k : Array LocalDecl → Array Pattern → Expr → TermElabM α) : TermElabM α 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Elab.Term.ToDepElimPattern.main.unpack
code: /--
  Main method for `withDepElimPatterns`.
  - `PatternVarDecls`: are the explicit pattern variables provided by the user.
  - `ps`: are the patterns provided by the user.
  - `matchType`: the expected typ for this branch. It depends on the explicit pattern variables and the implicit ones that are still represented as metavariables,
     and are found by this function.
  - `k` is the continuation that is executed in an updated local context with the all pattern variables (explicit and implicit). Note that, `patternVarDecls` are all
     replaced since they may depend on implicit pattern variables (i.e., metavariables) that are converted into new free variables by this method.
 -/
partial def main (patternVarDecls : Array PatternVarDecl) (ps : Array Expr) (matchType : Expr) (k : Array LocalDecl → Array Pattern → Expr → TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: Lean.Elab.Term.ToDepElimPattern.main.unpack.go
code: /--
  Main method for `withDepElimPatterns`.
  - `PatternVarDecls`: are the explicit pattern variables provided by the user.
  - `ps`: are the patterns provided by the user.
  - `matchType`: the expected typ for this branch. It depends on the explicit pattern variables and the implicit ones that are still represented as metavariables,
     and are found by this function.
  - `k` is the continuation that is executed in an updated local context with the all pattern variables (explicit and implicit). Note that, `patternVarDecls` are all
     replaced since they may depend on implicit pattern variables (i.e., metavariables) that are converted into new free variables by this method.
 -/
partial def main (patternVarDecls : Array PatternVarDecl) (ps : Array Expr) (matchType : Expr) (k : Array LocalDecl → Array Pattern → Expr → TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: Lean.Elab.Term.ToDepElimPattern.main
code: /--
  Main method for `withDepElimPatterns`.
  - `PatternVarDecls`: are the explicit pattern variables provided by the user.
  - `ps`: are the patterns provided by the user.
  - `matchType`: the expected typ for this branch. It depends on the explicit pattern variables and the implicit ones that are still represented as metavariables,
     and are found by this function.
  - `k` is the continuation that is executed in an updated local context with the all pattern variables (explicit and implicit). Note that, `patternVarDecls` are all
     replaced since they may depend on implicit pattern variables (i.e., metavariables) that are converted into new free variables by this method.
 -/
partial def main (patternVarDecls : Array PatternVarDecl) (ps : Array Expr) (matchType : Expr) (k : Array LocalDecl → Array Pattern → Expr → TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: Lean.Elab.Term.withDepElimPatterns
code: def withDepElimPatterns (patternVarDecls : Array PatternVarDecl) (ps : Array Expr) (matchType : Expr) (k : Array LocalDecl → Array Pattern → Expr → TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.withElaboratedLHS
code: private def withElaboratedLHS {α} (ref : Syntax) (patternVarDecls : Array PatternVarDecl) (patternStxs : Array Syntax) (matchType : Expr)
    (k : AltLHS → Expr → TermElabM α) : ExceptT PatternElabException TermElabM α 
goal: ExceptT Lean.Elab.Term.PatternElabException Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.withToClear
code: /--
  Try to clear the free variables in `toClear` and auxiliary discriminants, and then execute `k` in the updated local context.
  If `type` or another local variables depends on a free variable in `toClear`, then it is not cleared.
-/
private def withToClear (toClear : Array FVarId) (type : Expr) (k : TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.withEqs
code: /--
  Generate equalities `h : discr = pattern` for discriminants annotated with `h :`.
  We use these equalities to elaborate the right-hand-side of a `match` alternative.
-/
private def withEqs (discrs : Array Discr) (patterns : List Pattern) (k : Array Expr → TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.withEqs.go
code: /--
  Generate equalities `h : discr = pattern` for discriminants annotated with `h :`.
  We use these equalities to elaborate the right-hand-side of a `match` alternative.
-/
private def withEqs (discrs : Array Discr) (patterns : List Pattern) (k : Array Expr → TermElabM α) : TermElabM α 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAltView
code: /--
  Elaborate the `match` alternative `alt` using the given `matchType`.
  The array `toClear` contains variables that must be cleared before elaborating the `rhs` because
  they have been generalized/refined.
-/
private def elabMatchAltView (discrs : Array Discr) (alt : MatchAltView) (matchType : Expr) (toClear : Array FVarId) : ExceptT PatternElabException TermElabM (AltLHS × Expr) 
goal: ExceptT Lean.Elab.Term.PatternElabException Lean.Elab.TermElabM (Lean.Meta.Match.AltLHS × Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.getIndexToInclude?.go
code: /--
  Collect problematic index for the "discriminant refinement feature". This method is invoked
  when we detect a type mismatch at a pattern #`idx` of some alternative. -/
private partial def getIndexToInclude? (discr : Expr) (pathToIndex : List Nat) : TermElabM (Option Expr) 
goal: OptionT Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.getIndexToInclude?
code: /--
  Collect problematic index for the "discriminant refinement feature". This method is invoked
  when we detect a type mismatch at a pattern #`idx` of some alternative. -/
private partial def getIndexToInclude? (discr : Expr) (pathToIndex : List Nat) : TermElabM (Option Expr) 
goal: Lean.Elab.TermElabM (Option Lean.Expr)

full_name: Lean.Elab.Term.GeneralizeResult.discrs
code: structure GeneralizeResult where
  discrs    : Array Discr
  /-- `FVarId`s of the variables that have been generalized. We store them to clear after in each branch. -/
  toClear   : Array FVarId := #[]
  matchType : Expr
  altViews  : Array MatchAltView
  refined   : Bool := false
goal: Array Lean.Elab.Term.Discr

full_name: Lean.Elab.Term.GeneralizeResult.matchType
code: structure GeneralizeResult where
  discrs    : Array Discr
  /-- `FVarId`s of the variables that have been generalized. We store them to clear after in each branch. -/
  toClear   : Array FVarId := #[]
  matchType : Expr
  altViews  : Array MatchAltView
  refined   : Bool := false
goal: Lean.Expr

full_name: Lean.Elab.Term.GeneralizeResult.toClear
code: structure GeneralizeResult where
  discrs    : Array Discr
  /-- `FVarId`s of the variables that have been generalized. We store them to clear after in each branch. -/
  toClear   : Array FVarId := #[]
  matchType : Expr
  altViews  : Array MatchAltView
  refined   : Bool := false
goal: Array Lean.FVarId

full_name: Lean.Elab.Term.GeneralizeResult.altViews
code: structure GeneralizeResult where
  discrs    : Array Discr
  /-- `FVarId`s of the variables that have been generalized. We store them to clear after in each branch. -/
  toClear   : Array FVarId := #[]
  matchType : Expr
  altViews  : Array MatchAltView
  refined   : Bool := false
goal: Array Lean.Elab.Term.MatchAltView

full_name: Lean.Elab.Term.GeneralizeResult.refined
code: structure GeneralizeResult where
  discrs    : Array Discr
  /-- `FVarId`s of the variables that have been generalized. We store them to clear after in each branch. -/
  toClear   : Array FVarId := #[]
  matchType : Expr
  altViews  : Array MatchAltView
  refined   : Bool := false
goal: Bool

full_name: Lean.Elab.Term.GeneralizeResult
code: structure GeneralizeResult where
  discrs    : Array Discr
  /-- `FVarId`s of the variables that have been generalized. We store them to clear after in each branch. -/
  toClear   : Array FVarId := #[]
  matchType : Expr
  altViews  : Array MatchAltView
  refined   : Bool := false
goal: Type

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.generalize
code: /--
  "Generalize" variables that depend on the discriminants.

  Remarks and limitations:
  - We currently do not generalize let-decls.
  - We abort generalization if the new `matchType` is type incorrect.
  - Only discriminants that are free variables are considered during specialization.
  - We "generalize" by adding new discriminants and pattern variables. We do not "clear" the generalized variables,
    but they become inaccessible since they are shadowed by the patterns variables. We assume this is ok since
    this is the exact behavior users would get if they had written it by hand. Recall there is no `clear` in term mode.
-/
private def generalize (discrs : Array Discr) (matchType : Expr) (altViews : Array MatchAltView) (generalizing? : Option Bool) : TermElabM GeneralizeResult 
goal: Lean.Elab.TermElabM Lean.Elab.Term.GeneralizeResult

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAltViews.updateMatchType
code: private partial def elabMatchAltViews (generalizing? : Option Bool) (discrs : Array Discr) (matchType : Expr) (altViews : Array MatchAltView) : TermElabM (Array Discr × Expr × Array (AltLHS × Expr) × Bool) 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAltViews.throwEx
code: private partial def elabMatchAltViews (generalizing? : Option Bool) (discrs : Array Discr) (matchType : Expr) (altViews : Array MatchAltView) : TermElabM (Array Discr × Expr × Array (AltLHS × Expr) × Bool) 
goal: Lean.Elab.TermElabM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAltViews.collectDeps
code: private partial def elabMatchAltViews (generalizing? : Option Bool) (discrs : Array Discr) (matchType : Expr) (altViews : Array MatchAltView) : TermElabM (Array Discr × Expr × Array (AltLHS × Expr) × Bool) 
goal: Lean.Elab.TermElabM (Array Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAltViews.containsFVar
code: private partial def elabMatchAltViews (generalizing? : Option Bool) (discrs : Array Discr) (matchType : Expr) (altViews : Array MatchAltView) : TermElabM (Array Discr × Expr × Array (AltLHS × Expr) × Bool) 
goal: Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAltViews
code: private partial def elabMatchAltViews (generalizing? : Option Bool) (discrs : Array Discr) (matchType : Expr) (altViews : Array MatchAltView) : TermElabM (Array Discr × Expr × Array (AltLHS × Expr) × Bool) 
goal: Lean.Elab.TermElabM (Array Lean.Elab.Term.Discr × Lean.Expr × Array (Lean.Meta.Match.AltLHS × Lean.Expr) × Bool)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAltViews.loop
code: private partial def elabMatchAltViews (generalizing? : Option Bool) (discrs : Array Discr) (matchType : Expr) (altViews : Array MatchAltView) : TermElabM (Array Discr × Expr × Array (AltLHS × Expr) × Bool) 
goal: Lean.Elab.TermElabM (Array Lean.Elab.Term.Discr × Lean.Expr × Array (Lean.Meta.Match.AltLHS × Lean.Expr) × Bool)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAltViews.updateFirst
code: private partial def elabMatchAltViews (generalizing? : Option Bool) (discrs : Array Discr) (matchType : Expr) (altViews : Array MatchAltView) : TermElabM (Array Discr × Expr × Array (AltLHS × Expr) × Bool) 
goal: Lean.Elab.TermElabM (Lean.Elab.Term.SavedState × Lean.Exception)

full_name: Lean.Elab.Term.mkMatcher
code: def mkMatcher (input : Meta.Match.MkMatcherInput) : TermElabM MatcherResult 
goal: Lean.Elab.TermElabM Lean.Meta.Match.MatcherResult

full_name: Lean.Elab.Term.initFn._@..lake.packages.lean4.src.lean.Lean.Elab.Match._hyg.14864
code: register_builtin_option match.ignoreUnusedAlts : Bool := {
  defValue := false
  descr := "if true, do not generate error if an alternative is not used"
}
goal: IO (Lean.Option Bool)

full_name: Lean.Elab.Term.match.ignoreUnusedAlts
code: register_builtin_option match.ignoreUnusedAlts : Bool := {
  defValue := false
  descr := "if true, do not generate error if an alternative is not used"
}
goal: Lean.Option Bool

full_name: Lean.Elab.Term.reportMatcherResultErrors
code: def reportMatcherResultErrors (altLHSS : List AltLHS) (result : MatcherResult) : TermElabM Unit 
goal: Lean.Elab.TermElabM Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.isMatchUnit?
code: /--
  If `altLHSS + rhss` is encoding `| PUnit.unit => rhs[0]`, return `rhs[0]`
  Otherwise, return none.
-/
private def isMatchUnit? (altLHSS : List Match.AltLHS) (rhss : Array Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchAux
code: private def elabMatchAux (generalizing? : Option Bool) (discrStxs : Array Syntax) (altViews : Array MatchAltView) (matchOptMotive : Syntax) (expectedType : Expr)
    : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.getDiscrs
code: private def getDiscrs (matchStx : Syntax) : Array Syntax 
goal: Array Lean.Syntax

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.getMatchOptMotive
code: private def getMatchOptMotive (matchStx : Syntax) : Syntax 
goal: Lean.Syntax

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.expandNonAtomicDiscrs?
code: private def expandNonAtomicDiscrs? (matchStx : Syntax) : TermElabM (Option Syntax) 
goal: Lean.Elab.TermElabM (Option Lean.Syntax)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.expandNonAtomicDiscrs?.loop
code: private def expandNonAtomicDiscrs? (matchStx : Syntax) : TermElabM (Option Syntax) 
goal: Lean.Elab.TermElabM Lean.Syntax

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.waitExpectedType
code: private def waitExpectedType (expectedType? : Option Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.tryPostponeIfDiscrTypeIsMVar
code: private def tryPostponeIfDiscrTypeIsMVar (matchStx : Syntax) : TermElabM Unit 
goal: Lean.Elab.TermElabM Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.waitExpectedTypeAndDiscrs
code: /--
We (try to) elaborate a `match` only when the expected type is available.
If the `matchType` has not been provided by the user, we also try to postpone elaboration if the type
of a discriminant is not available. That is, it is of the form `(?m ...)`.
We use `expandNonAtomicDiscrs?` to make sure all discriminants are metavariables,
so that they are not elaborated twice.
This is a standard trick we use in the elaborator, and it is also used to elaborate structure instances.
Suppose, we are trying to elaborate
```
match g x with
  | ... => ...
```
`expandNonAtomicDiscrs?` converts it intro
```
let_mvar% ?discr := g x
match ?discr with
  | ... => ...
```

This elaboration technique is needed to elaborate terms such as:
```lean
xs.filter fun (a, b) => a > b
```
which are syntax sugar for
```lean
List.filter (fun p => match p with | (a, b) => a > b) xs
```
When we visit `match p with | (a, b) => a > b`, we don't know the type of `p` yet.
-/
private def waitExpectedTypeAndDiscrs (matchStx : Syntax) (expectedType? : Option Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.elabMatchCore
code: /--
```
leading_parser "match " >> optional generalizingParam >> optional motive >> sepBy1 matchDiscr ", " >> " with " >> ppDedent matchAlts
```
Remark the `optIdent` must be `none` at `matchDiscr`. They are expanded by `expandMatchDiscr?`.
-/
private def elabMatchCore (stx : Syntax) (expectedType? : Option Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.isPatternVar.isAtomicIdent
code: private def isPatternVar (stx : Syntax) : TermElabM Bool 
goal: Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Elab.Match.0.Lean.Elab.Term.isPatternVar
code: private def isPatternVar (stx : Syntax) : TermElabM Bool 
goal: Lean.Elab.TermElabM Bool

full_name: Lean.Elab.Term.elabMatch.elabMatchDefault
code: @[builtin_term_elab «match»] def elabMatch : TermElab 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: Lean.Elab.Term.elabMatch
code: @[builtin_term_elab «match»] def elabMatch : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.initFn._@..lake.packages.lean4.src.lean.Lean.Elab.Match._hyg.18698
code: builtin_initialize
  registerTraceClass `Elab.match
goal: IO Unit

full_name: Lean.Elab.Term.elabNoMatch.loop
code: @[builtin_term_elab «nomatch»] def elabNoMatch : TermElab 
goal: Lean.Elab.TermElabM Lean.Term

full_name: Lean.Elab.Term.elabNoMatch
code: @[builtin_term_elab «nomatch»] def elabNoMatch : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.elabNoFun
code: @[builtin_term_elab «nofun»] def elabNoFun : TermElab 
goal: Lean.Elab.Term.TermElab