Before, app unexpanders would only be applied to entire applications. However, some notations produce functions, and these functions can be given additional arguments. The solution so far has been to write app unexpanders so that they can take an arbitrary number of additional arguments. However, as reported in [this Zulip thread](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/pretty.20printer.20bug/near/420662236), this leads to misleading hover information in the Infoview. For example, while `HAdd.hAdd f g 1` pretty prints as `(f + g) 1`, hovering over `f + g` shows `f`. There is no way to fix the situation from within an app unexpander; the expression position for `HAdd.hAdd f g` is absent, and app unexpanders cannot register TermInfo. This commit changes the app delaborator to try running app unexpanders on every prefix of an application, from longest to shortest prefix. For efficiency, it is careful to only try this when app delaborators do in fact exist for the head constant, and it also ensures arguments are only delaborated once. Then, in `(f + g) 1`, the `f + g` gets TermInfo registered for that subexpression, making it properly hoverable. The app delaborator is also refactored, and there are some bug fixes: - app unexpanders only run when `pp.explicit` is false - trailing parameters in under-applied applications are now only considered up to reducible & instance transparency, which lets, for example, optional arguments for `IO`-valued functions to be omitted. (`IO` is a reader monad, so it's hiding a pi type) - app unexpanders will no longer run for delaborators that use `withOverApp` - auto parameters now always pretty print, since we are not verifying that the provided argument equals the result of evaluating the tactic Furthermore, the `notation` command has been modified to generate an app unexpander that relies on the app delaborator's new behavior. The change to app unexpanders is reverse-compatible, but it's recommended to update `@[app_unexpander]`s in downstream projects so that they no longer handle overapplication themselves.
41 lines
958 B
Text
41 lines
958 B
Text
/-!
|
|
Tests for delaborating over-applied functions.
|
|
For example, checking to see that the algorithm for app unexpanders handles over-applications.
|
|
-/
|
|
|
|
/-!
|
|
Technically these are not examples of overapplied functions,
|
|
but in principle these are two-argument functions that return functions.
|
|
-/
|
|
def add (f g : Nat → Nat) : Nat → Nat := fun x => f x + g x
|
|
def mul (f g : Nat → Nat) : Nat → Nat := fun x => f x * g x
|
|
|
|
variable (f g : Nat → Nat)
|
|
|
|
infixl:65 " +' " => add
|
|
|
|
/-!
|
|
Checking the app unexpander that was generated by the `infixl` command works when overapplied.
|
|
-/
|
|
#check f +' g
|
|
#check (f +' g) 1
|
|
|
|
@[app_unexpander mul]
|
|
def unexpandAdd : Lean.PrettyPrinter.Unexpander
|
|
| `($_ $f $g) => `($f * $g)
|
|
| _ => throw ()
|
|
|
|
/-!
|
|
Checking the app unexpander when both applied and overapplied
|
|
-/
|
|
#check mul f g
|
|
#check mul f g 1
|
|
|
|
/-!
|
|
Make sure pp.explicit turns off app unexpanders
|
|
-/
|
|
section
|
|
set_option pp.explicit true
|
|
#check mul f g
|
|
#check mul f g 1
|
|
end
|