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):

(src#orelse.formatter)


Last updated: May 02 2025 at 03:31 UTC