Zulip Chat Archive
Stream: lean4
Topic: format: uncaught backtrack exception
Eric Wieser (Mar 27 2024 at 23:40):
Minimized from mathlib:
import Lean
open Lean
def AddMonoidAlgebra (R A : Type) : Type := Unit
notation:9000 R:max "[" A "]" => AddMonoidAlgebra R A
-- format: uncaught backtrack exception
#eval do PrettyPrinter.ppTerm <| ← `(term| ∀ (f : R[A]), true)
Eric Wieser (Mar 27 2024 at 23:40):
This only seems to happen when the custom notation is used in a binder
Eric Wieser (Mar 27 2024 at 23:57):
It looks like this is interfering with array indexing notation?
Mario Carneiro (Mar 28 2024 at 01:41):
the syntax quotation is producing a choice
node
Mario Carneiro (Mar 28 2024 at 01:41):
if you make the notation high or low priority then it will not do this
Mario Carneiro (Mar 28 2024 at 03:14):
@Sebastian Ullrich It appears this is an unusual interaction of formatter combinators and ungrouped optional
nodes.
import Lean
open Lean
syntax:9000 (name := foo) term:max " [" term "-]" : term
syntax:9000 (name := foo2) term:max " [" term "-]" : term
run_meta
-- let stx ← `(Parser.Term.bracketedBinderF| (f : R[A]))
let stx ← `(Parser.Term.bracketedBinderF| (f : R[A-]))
_ ← PrettyPrinter.format Parser.Term.explicitBinder.formatter stx
Here's my test after inlining things to add logging
When testing with the non-overloaded syntax R[A]
, the optional node in binderType
is of the form [":" (term_[_] ...)]
, and optionalNoAntiquot.formatter
zooms in on the first subterm (term_[_] ...)
, which is consumed by term
(which moves the cursor to ":"
) and then ":"
as intended.
With the overloaded syntax R[A-]
, the optional node is instead [":" (choice (foo ...) (foo2 ...))]
, and again optionalNoAntiquot.formatter
zooms in on (choice (foo ...) (foo2 ...))
. But then we use orelse.formatter
(actually withAntiquot.formatter
) in order to try a possible antiquot at this position, and orelse.formatter
strips choice nodes, so it zooms in further to (foo2 ...)
; applying term
here succeeds and moves to the left to (foo ...)
and applying ":"
here fails.
Mario Carneiro (Mar 28 2024 at 03:16):
I think the issue is that orelse.formatter
has an implementation which doesn't make sense if the provided formatters p1
and p2
have arity > 1, which is the case here because p2
is ":" >> term
Eric Wieser (Mar 28 2024 at 06:01):
Last updated: May 02 2025 at 03:31 UTC