fix: support user-defined empty inductives at toLCNF
This commit is contained in:
parent
0b4590bd69
commit
4323205185
3 changed files with 32 additions and 16 deletions
|
|
@ -500,24 +500,28 @@ where
|
|||
visitCases (casesInfo : CasesInfo) (e : Expr) : M Expr :=
|
||||
etaIfUnderApplied e casesInfo.arity do
|
||||
let args := e.getAppArgs
|
||||
let mut alts := #[]
|
||||
let typeName := casesInfo.declName.getPrefix
|
||||
let mut resultType ← toLCNFType (← liftMetaM do Meta.inferType (mkAppN e.getAppFn args[:casesInfo.arity]))
|
||||
let discr ← visitAppArg args[casesInfo.discrPos]!
|
||||
let .inductInfo indVal ← getConstInfo typeName | unreachable!
|
||||
for i in casesInfo.altsRange, numParams in casesInfo.altNumParams, ctorName in indVal.ctors do
|
||||
let (altType, alt) ← visitAlt ctorName numParams args[i]!
|
||||
unless compatibleTypes altType resultType do
|
||||
resultType := anyTypeExpr
|
||||
alts := alts.push alt
|
||||
let cases : Cases := { typeName, discr := discr.fvarId!, resultType, alts }
|
||||
let auxDecl ← mkAuxParam resultType
|
||||
pushElement (.cases auxDecl cases)
|
||||
let result := .fvar auxDecl.fvarId
|
||||
if args.size == casesInfo.arity then
|
||||
return result
|
||||
if casesInfo.numAlts == 0 then
|
||||
/- `casesOn` of an empty type. -/
|
||||
mkUnreachable resultType
|
||||
else
|
||||
mkOverApplication result args casesInfo.arity
|
||||
let mut alts := #[]
|
||||
let typeName := casesInfo.declName.getPrefix
|
||||
let discr ← visitAppArg args[casesInfo.discrPos]!
|
||||
let .inductInfo indVal ← getConstInfo typeName | unreachable!
|
||||
for i in casesInfo.altsRange, numParams in casesInfo.altNumParams, ctorName in indVal.ctors do
|
||||
let (altType, alt) ← visitAlt ctorName numParams args[i]!
|
||||
unless compatibleTypes altType resultType do
|
||||
resultType := anyTypeExpr
|
||||
alts := alts.push alt
|
||||
let cases : Cases := { typeName, discr := discr.fvarId!, resultType, alts }
|
||||
let auxDecl ← mkAuxParam resultType
|
||||
pushElement (.cases auxDecl cases)
|
||||
let result := .fvar auxDecl.fvarId
|
||||
if args.size == casesInfo.arity then
|
||||
return result
|
||||
else
|
||||
mkOverApplication result args casesInfo.arity
|
||||
|
||||
visitCtor (arity : Nat) (e : Expr) : M Expr :=
|
||||
etaIfUnderApplied e arity do
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ structure CasesInfo where
|
|||
altNumParams : Array Nat
|
||||
motivePos : Nat
|
||||
|
||||
def CasesInfo.numAlts (c : CasesInfo) : Nat :=
|
||||
c.altNumParams.size
|
||||
|
||||
private def getCasesOnInductiveVal? (declName : Name) : CoreM (Option InductiveVal) := do
|
||||
unless isCasesOnRecursor (← getEnv) declName do return none
|
||||
let .inductInfo val ← getConstInfo declName.getPrefix | return none
|
||||
|
|
|
|||
9
tests/lean/run/emptyLcnf.lean
Normal file
9
tests/lean/run/emptyLcnf.lean
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import Lean
|
||||
|
||||
inductive MyEmpty
|
||||
|
||||
def f (x : MyEmpty) : Nat :=
|
||||
MyEmpty.casesOn x
|
||||
|
||||
set_option trace.Compiler.result true
|
||||
#eval Lean.Compiler.compile #[``f]
|
||||
Loading…
Add table
Reference in a new issue