feat: add option pp.piBinderNames (#10374)
This PR adds the options `pp.piBinderNames` and `pp.piBinderNames.hygienic`. Enabling `pp.piBinderNames` causes non-dependent pi binder names to be pretty printed, rather than be omitted. When `pp.piBinderNames.hygienic` is false (the default) then only non-hygienic such biner names are pretty printed. Setting `pp.all` enables `pp.piBinderNames` if it is not otherwise explicitly set. Implementation note: this is exposing the secret pretty printer option `pp.piBinderNames` that was being used within the signature pretty printer. Closes #1134.
This commit is contained in:
parent
409cbe1da9
commit
7e9ea00ac0
7 changed files with 121 additions and 9 deletions
|
|
@ -954,8 +954,6 @@ def delabLam : Delab :=
|
|||
|
||||
/-- Don't do any renaming for forall binders, but do add fresh macro scopes when there is shadowing. -/
|
||||
private def ppPiPreserveNames := `pp.piPreserveNames
|
||||
/-- Causes non-dependent foralls to print with binder names. -/
|
||||
private def ppPiBinderNames := `pp.piBinderNames
|
||||
|
||||
/--
|
||||
Similar to `delabBinders`, but tracking whether `forallE` is dependent or not.
|
||||
|
|
@ -964,7 +962,11 @@ See issue #1571
|
|||
-/
|
||||
private partial def delabForallBinders (prop : Bool) (delabGroup : Array Syntax → Bool → Syntax → Delab) (curNames : Array Syntax := #[]) (curDep := false) : Delab := do
|
||||
-- Logic note: wanting to print with binder names is equivalent to pretending the forall is dependent.
|
||||
let mut dep := !(← getExpr).isArrow || (← getOptionsAtCurrPos).get ppPiBinderNames false
|
||||
let opts ← getOptionsAtCurrPos
|
||||
let mut dep :=
|
||||
!(← getExpr).isArrow
|
||||
|| (getPPPiBinderNames opts
|
||||
&& (!(← getExpr).bindingName!.hasMacroScopes || getPPPiBinderNamesHygienic opts))
|
||||
if !dep && prop && (← getExpr).binderInfo.isExplicit then
|
||||
-- RFC #1834: If `∀` notation is enabled, avoid using `→` for propositions if the domain is not a proposition.
|
||||
-- We can pretend the type is dependent in this case.
|
||||
|
|
@ -975,7 +977,7 @@ private partial def delabForallBinders (prop : Bool) (delabGroup : Array Syntax
|
|||
-- don't group
|
||||
delabGroup curNames curDep (← delab)
|
||||
else
|
||||
let preserve := (← getOptionsAtCurrPos).get ppPiPreserveNames false
|
||||
let preserve := opts.get ppPiPreserveNames false
|
||||
let curDep := dep
|
||||
if ← shouldGroupWithNext then
|
||||
-- group with nested binder => recurse immediately
|
||||
|
|
@ -1554,7 +1556,7 @@ where
|
|||
if n.hasMacroScopes then
|
||||
return (opts, .forallE n t b' bi)
|
||||
else if !used then
|
||||
let opts := opts.insertAt subExpr.pos ppPiBinderNames true
|
||||
let opts := opts.insertAt subExpr.pos pp.piBinderNames.name true
|
||||
return (opts, .forallE n t b' bi)
|
||||
else
|
||||
let n' ← withFreshMacroScope <| MonadQuotation.addMacroScope n
|
||||
|
|
|
|||
|
|
@ -88,6 +88,17 @@ register_builtin_option pp.piBinderTypes : Bool := {
|
|||
group := "pp"
|
||||
descr := "(pretty printer) display types of pi parameters"
|
||||
}
|
||||
register_builtin_option pp.piBinderNames : Bool := {
|
||||
defValue := false
|
||||
group := "pp"
|
||||
descr := "(pretty printer) display names for pi parameters, even if they are unused; \
|
||||
when `pp.piBinderNames.hygienic` is false then unused hygienic parameters are not displayed."
|
||||
}
|
||||
register_builtin_option pp.piBinderNames.hygienic : Bool := {
|
||||
defValue := false
|
||||
group := "pp"
|
||||
descr := "(pretty printer) if false, disables displaying names for unused pi parameters with hygienic names."
|
||||
}
|
||||
register_builtin_option pp.foralls : Bool := {
|
||||
defValue := true
|
||||
group := "pp"
|
||||
|
|
@ -276,6 +287,8 @@ def getPPMaxSteps (o : Options) : Nat := o.get pp.maxSteps.name pp.maxSteps.defV
|
|||
def getPPAll (o : Options) : Bool := o.get pp.all.name false
|
||||
def getPPFunBinderTypes (o : Options) : Bool := o.get pp.funBinderTypes.name (getPPAll o)
|
||||
def getPPPiBinderTypes (o : Options) : Bool := o.get pp.piBinderTypes.name pp.piBinderTypes.defValue
|
||||
def getPPPiBinderNames (o : Options) : Bool := o.get pp.piBinderNames.name (getPPAll o)
|
||||
def getPPPiBinderNamesHygienic (o : Options) : Bool := o.get pp.piBinderNames.hygienic.name pp.piBinderNames.hygienic.defValue
|
||||
def getPPLetVarTypes (o : Options) : Bool := o.get pp.letVarTypes.name (getPPAll o)
|
||||
def getPPNumericTypes (o : Options) : Bool := o.get pp.numericTypes.name pp.numericTypes.defValue
|
||||
def getPPNatLit (o : Options) : Bool := o.get pp.natLit.name (getPPNumericTypes o && !getPPAll o)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
fun {α : Sort v} => PEmpty.rec.{v, u_1} fun (x : PEmpty.{u_1}) => α : {α : Sort v} → PEmpty.{u_1} → α
|
||||
fun {α : Sort v} => PEmpty.rec.{v, u_1} fun (x : PEmpty.{u_1}) => α : {α : Sort v} → (t : PEmpty.{u_1}) → α
|
||||
276.lean:9:4-9:16: error: code generator does not support recursor `PEmpty.rec` yet, consider using 'match ... with' and/or structural recursion
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ def h : BV 32 → Array Bool :=
|
|||
fun x => (fun x => g (f x).val) x
|
||||
def r : Nat → Prop :=
|
||||
fun a => if (a == 0) = true then (a != 1) = true else (a != 2) = true
|
||||
def r : Nat → Prop :=
|
||||
def r : (a : Nat) → Prop :=
|
||||
fun (a : Nat) =>
|
||||
@ite.{1} Prop
|
||||
(@Eq.{1} Bool
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ mkAppN add #[mkLit (Literal.natVal 3), mkLit (Literal.natVal 5)]
|
|||
#eval tstWHNF t5
|
||||
|
||||
set_option pp.all true
|
||||
/-- info: @List.cons.{0} Nat : Nat → List.{0} Nat → List.{0} Nat -/
|
||||
/-- info: @List.cons.{0} Nat : (head : Nat) → (tail : List.{0} Nat) → List.{0} Nat -/
|
||||
#guard_msgs in
|
||||
#check @List.cons Nat
|
||||
|
||||
|
|
|
|||
97
tests/lean/run/ppPiBinderNames.lean
Normal file
97
tests/lean/run/ppPiBinderNames.lean
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/-!
|
||||
# Testing pretty printing option `pp.piBinderNames`
|
||||
-/
|
||||
|
||||
/-!
|
||||
Tests of default options.
|
||||
-/
|
||||
section
|
||||
|
||||
/-!
|
||||
Unused name, doesn't print.
|
||||
-/
|
||||
/-- info: Nat → Type : Type 1 -/
|
||||
#guard_msgs in #check (x : Nat) → Type
|
||||
|
||||
/-!
|
||||
Unused hygienic name, doesn't print.
|
||||
-/
|
||||
/-- info: Nat → Type : Type 1 -/
|
||||
#guard_msgs in #check Nat → Type
|
||||
|
||||
end
|
||||
|
||||
/-!
|
||||
Tests with `pp.piBinderNames` enabled.
|
||||
-/
|
||||
section
|
||||
set_option pp.piBinderNames true
|
||||
|
||||
/-!
|
||||
Unused name, prints since not hygienic.
|
||||
-/
|
||||
/-- info: (x : Nat) → Type : Type 1 -/
|
||||
#guard_msgs in #check (x : Nat) → Type
|
||||
|
||||
/-!
|
||||
Unused hygienic name, doesn't print.
|
||||
-/
|
||||
/-- info: Nat → Type : Type 1 -/
|
||||
#guard_msgs in #check Nat → Type
|
||||
|
||||
end
|
||||
|
||||
/-!
|
||||
Tests with `pp.piBinderNames` and `pp.piBinderNames.hygienic` enabled.
|
||||
-/
|
||||
section
|
||||
set_option pp.piBinderNames true
|
||||
set_option pp.piBinderNames.hygienic true
|
||||
|
||||
/-!
|
||||
Prints unused name.
|
||||
-/
|
||||
/-- info: (x : Nat) → Type : Type 1 -/
|
||||
#guard_msgs in #check (x : Nat) → Type
|
||||
|
||||
/-!
|
||||
Prints unused hygienic name.
|
||||
-/
|
||||
/-- info: (a : Nat) → Type : Type 1 -/
|
||||
#guard_msgs in #check Nat → Type
|
||||
|
||||
end
|
||||
|
||||
/-!
|
||||
Tests with `pp.all`. Enables `pp.piBinderNames`.
|
||||
-/
|
||||
section
|
||||
set_option pp.all true
|
||||
|
||||
/-!
|
||||
Unused name, prints since not hygienic.
|
||||
-/
|
||||
/-- info: (x : Nat) → Type : Type 1 -/
|
||||
#guard_msgs in #check (x : Nat) → Type
|
||||
|
||||
/-!
|
||||
Unused hygienic name, doesn't print.
|
||||
-/
|
||||
/-- info: Nat → Type : Type 1 -/
|
||||
#guard_msgs in #check Nat → Type
|
||||
|
||||
set_option pp.piBinderNames.hygienic true
|
||||
|
||||
/-!
|
||||
Prints unused name.
|
||||
-/
|
||||
/-- info: (x : Nat) → Type : Type 1 -/
|
||||
#guard_msgs in #check (x : Nat) → Type
|
||||
|
||||
/-!
|
||||
Prints unused hygienic name.
|
||||
-/
|
||||
/-- info: (a : Nat) → Type : Type 1 -/
|
||||
#guard_msgs in #check Nat → Type
|
||||
|
||||
end
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
(100, 400)
|
||||
(49, 576, 576)
|
||||
def g : Int → Int → Int :=
|
||||
def g : (x y : Int) → Int :=
|
||||
fun (x y : Int) => @mul.{0} (@magmaOfMul.{0} Int Int.instMul) x y
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue