fix: case splitting on data
diff --git a/src/Lean/Meta/Tactic/Grind/Cases.lean b/src/Lean/Meta/Tactic/Grind/Cases.lean
index 6124bbe..8b4d472 100644
--- a/src/Lean/Meta/Tactic/Grind/Cases.lean
+++ b/src/Lean/Meta/Tactic/Grind/Cases.lean
@@ -85,6 +85,20 @@
   let s ← s.eraseDecl declName
   modifyEnv fun env => casesExt.modifyState env fun _ => s
 
+/--
+We say a free variable is "simple" to be processed by the cases tactic IF:
+- It is the latest and consequently there are no forward dependencies, OR
+- It is not a proposion.
+-/
+private def isSimpleFVar (e : Expr) : MetaM Bool := do
+  let .fvar fvarId := e | return false
+  let decl ← fvarId.getDecl
+  if decl.index == (← getLCtx).numIndices - 1 then
+    -- It is the latest free variable, so there are no forward dependencies
+    return true
+  else
+    -- It is pointless to add an auxiliary equality if `e`s type is a proposition
+    isProp decl.type
 
 /--
 The `grind` tactic includes an auxiliary `cases` tactic that is not intended for direct use by users.
@@ -132,12 +146,17 @@
     let s ← generalizeIndices' mvarId e
     s.mvarId.withContext do
       k s.mvarId s.fvarId s.indicesFVarIds
-  else if let .fvar fvarId := e then
-    k mvarId fvarId #[]
+  else if (← isSimpleFVar e) then
+    -- We don't need to revert anything.
+    k mvarId e.fvarId! #[]
   else
-    let mvarId ← mvarId.assert (← mkFreshUserName `x) type e
+    let mvarId ← if (← isProof e) then
+      mvarId.assert (← mkFreshUserName `x) type e
+    else
+      mvarId.assertExt (← mkFreshUserName `x) type e
     let (fvarId, mvarId) ← mvarId.intro1
     mvarId.withContext do k mvarId fvarId #[]
+
 where
   throwInductiveExpected {α} (type : Expr) : MetaM α := do
     throwTacticEx `grind.cases mvarId m!"(non-recursive) inductive type expected at {e}{indentExpr type}"
diff --git a/src/Lean/Meta/Tactic/Grind/Split.lean b/src/Lean/Meta/Tactic/Grind/Split.lean
index dce9503..564284b 100644
--- a/src/Lean/Meta/Tactic/Grind/Split.lean
+++ b/src/Lean/Meta/Tactic/Grind/Split.lean
@@ -97,16 +97,19 @@
       return .resolved
     if let some info := isMatcherAppCore? (← getEnv) e then
       return .ready info.numAlts
-    let .const declName .. := e.getAppFn | unreachable!
-    if let some info ← isInductivePredicate? declName then
-      if (← isEqTrue e) then
-        return .ready info.ctors.length info.isRec
+    if let .const declName .. := e.getAppFn then
+      if let some info ← isInductivePredicate? declName then
+        if (← isEqTrue e) then
+          return .ready info.ctors.length info.isRec
     if e.isFVar then
       let type ← whnfD (← inferType e)
+      trace[Meta.debug] "1. {e}"
       let report : GoalM Unit := do
         reportIssue "cannot perform case-split on {e}, unexpected type{indentExpr type}"
       let .const declName _ := type.getAppFn | report; return .resolved
+      trace[Meta.debug] "2. {e}"
       let .inductInfo info ← getConstInfo declName | report; return .resolved
+      trace[Meta.debug] "3. {e}"
       return .ready info.ctors.length info.isRec
     return .notReady
 
@@ -162,7 +165,11 @@
       return mkApp3 (mkConst ``Grind.of_eq_eq_true) a b (← mkEqTrueProof c)
     else
       return mkApp3 (mkConst ``Grind.of_eq_eq_false) a b (← mkEqFalseProof c)
-  | _ => return mkOfEqTrueCore c (← mkEqTrueProof c)
+  | _ =>
+    if (← isEqTrue c) then
+      return mkOfEqTrueCore c (← mkEqTrueProof c)
+    else
+      return c
 
 /-- Introduces new hypotheses in each goal. -/
 private def introNewHyp (goals : List Goal) (acc : List Goal) (generation : Nat) : GrindM (List Goal) := do
diff --git a/tests/lean/run/grind_split_data.lean b/tests/lean/run/grind_split_data.lean
new file mode 100644
index 0000000..168e093
--- /dev/null
+++ b/tests/lean/run/grind_split_data.lean
@@ -0,0 +1,13 @@
+inductive C where
+  | a | b | c
+
+def f : C → Nat
+  | .a => 2
+  | .b => 3
+  | .c => 4
+
+example : f .a > 1 := by
+  grind [f]
+
+example : f x > 1 := by
+  grind [f, C]