perf: ctorIdx for single-constructor inductives: no casesOn, macro_inline (#10135)
This PR lets the `ctorIdx` definition for single constructor inductives avoid the pointless `.casesOn`, and uses `macro_inline` to avoid compiling the function and wasting symbols.
This commit is contained in:
parent
9e47edd0df
commit
0803f1e77e
2 changed files with 47 additions and 17 deletions
|
|
@ -55,26 +55,34 @@ public def mkCtorIdx (indName : Name) : MetaM Unit := do
|
|||
let declType ← mkArrow indType natType
|
||||
let declType ← mkForallFVars xs declType
|
||||
let declValue ← withLocalDeclD `x indType fun x => do
|
||||
let motive ← mkLambdaFVars (indices.push x) natType
|
||||
let mut value := mkConst casesOnName (levelOne::us)
|
||||
value := mkAppN value params
|
||||
value := mkApp value motive
|
||||
value := mkAppN value indices
|
||||
value := mkApp value x
|
||||
for c in info.ctors do
|
||||
let cInfo ← getConstInfoCtor c
|
||||
let cType ← instantiateForall cInfo.type params
|
||||
let alt ← forallBoundedTelescope cType cInfo.numFields fun ys _ =>
|
||||
mkLambdaFVars ys <| mkRawNatLit cInfo.cidx
|
||||
value := mkApp value alt
|
||||
let value ← if info.numCtors = 1 then
|
||||
pure (mkRawNatLit 0)
|
||||
else
|
||||
let motive ← mkLambdaFVars (indices.push x) natType
|
||||
let mut value := mkConst casesOnName (levelOne::us)
|
||||
value := mkAppN value params
|
||||
value := mkApp value motive
|
||||
value := mkAppN value indices
|
||||
value := mkApp value x
|
||||
for c in info.ctors do
|
||||
let cInfo ← getConstInfoCtor c
|
||||
let cType ← instantiateForall cInfo.type params
|
||||
let alt ← forallBoundedTelescope cType cInfo.numFields fun ys _ =>
|
||||
mkLambdaFVars ys <| mkRawNatLit cInfo.cidx
|
||||
value := mkApp value alt
|
||||
pure value
|
||||
mkLambdaFVars (xs.push x) value
|
||||
addAndCompile (.defnDecl (← mkDefinitionValInferringUnsafe
|
||||
let decl := .defnDecl (← mkDefinitionValInferringUnsafe
|
||||
(name := declName)
|
||||
(levelParams := info.levelParams)
|
||||
(type := declType)
|
||||
(value := declValue)
|
||||
(hints := ReducibilityHints.abbrev)
|
||||
))
|
||||
)
|
||||
addDecl decl
|
||||
if info.numCtors = 1 then
|
||||
setInlineAttribute declName .macroInline
|
||||
compileDecl decl
|
||||
modifyEnv fun env => addToCompletionBlackList env declName
|
||||
modifyEnv fun env => addProtected env declName
|
||||
setReducibleAttribute declName
|
||||
|
|
@ -82,13 +90,16 @@ public def mkCtorIdx (indName : Name) : MetaM Unit := do
|
|||
-- Deprecated alias for enumeration types (which used to have `toCtorIdx`)
|
||||
if (← isEnumType indName) then
|
||||
let aliasName := mkToCtorIdxName indName
|
||||
addAndCompile (.defnDecl (← mkDefinitionValInferringUnsafe
|
||||
let decl := .defnDecl (← mkDefinitionValInferringUnsafe
|
||||
(name := aliasName)
|
||||
(levelParams := info.levelParams)
|
||||
(type := declType)
|
||||
(value := mkConst declName us)
|
||||
(hints := ReducibilityHints.abbrev)
|
||||
))
|
||||
)
|
||||
addDecl decl
|
||||
setInlineAttribute aliasName .macroInline
|
||||
compileDecl decl
|
||||
modifyEnv fun env => addToCompletionBlackList env aliasName
|
||||
modifyEnv fun env => addProtected env aliasName
|
||||
setReducibleAttribute aliasName
|
||||
|
|
|
|||
|
|
@ -54,11 +54,30 @@ fun {m a} x => x.casesOn (fun {n} a => 0) (fun {n} a => 1) 2
|
|||
#guard_msgs in
|
||||
#print B.ctorIdx
|
||||
|
||||
-- Single constructor inductives do not use casesOn
|
||||
|
||||
inductive Single where | only (n : Nat)
|
||||
/--
|
||||
info: @[reducible] protected def Single.ctorIdx : Single → Nat :=
|
||||
fun x => 0
|
||||
-/
|
||||
#guard_msgs in #print Single.ctorIdx
|
||||
|
||||
structure Struct where
|
||||
field1 : Nat
|
||||
field2 : Bool
|
||||
/--
|
||||
info: @[reducible] protected def Struct.ctorIdx : Struct → Nat :=
|
||||
fun x => 0
|
||||
-/
|
||||
#guard_msgs in #print Struct.ctorIdx
|
||||
|
||||
-- Unsafe inductives do get a definition
|
||||
|
||||
unsafe inductive U : Type | mk : (U → U) → U
|
||||
/--
|
||||
info: @[reducible] unsafe protected def U.ctorIdx : U → Nat :=
|
||||
fun x => U.casesOn x fun a => 0
|
||||
fun x => 0
|
||||
-/
|
||||
#guard_msgs in
|
||||
#print U.ctorIdx
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue