This PR replaces the catch-all "unsupported pattern in syntax match" error that the new `do` elaborator produces for typical pattern mistakes (#2215, #8304, #10393) with the proper diagnostics from the regular pattern-var collector (e.g. "Invalid pattern: Expected a constructor or constant marked with `[match_pattern]`", "ambiguous pattern, use fully qualified name"), pointing at the offending pattern. `getPatternVarsEx` / `getPatternsVarsEx` in `Lean.Elab.Do` now try the syntax-quotation collector first (cheaply handling identifiers, holes, and antiquotations) and fall back to the regular pattern-var collector for everything else. When both fail, the regular collector's error wins via `<|>` semantics. The legacy `do` elaborator is intentionally left untouched, so the existing `tests/elab/doSyntaxPatternError.lean` guards (which capture the cryptic messages produced under legacy default) are unchanged. They will need updating when the new `do` elaborator becomes default. Fixes #2215, #8304, and #10393 for the new `do` elaborator.
104 lines
2.8 KiB
Text
104 lines
2.8 KiB
Text
import Lean.Meta
|
|
|
|
/-!
|
|
Regression tests that pattern errors inside the new `do` elaborator point at
|
|
the offending pattern with the proper diagnostic from the regular pattern-var
|
|
collector (e.g. "Invalid pattern: Expected a constructor or constant marked
|
|
with `[match_pattern]`", "ambiguous pattern, use fully qualified name") instead
|
|
of the catch-all "unsupported pattern in syntax match" used by syntax-quotation
|
|
matches.
|
|
|
|
* https://github.com/leanprover/lean4/issues/2215
|
|
* https://github.com/leanprover/lean4/issues/8304
|
|
* https://github.com/leanprover/lean4/issues/10393
|
|
-/
|
|
|
|
set_option backward.do.legacy false
|
|
|
|
inductive A where | a
|
|
inductive AA where | a
|
|
|
|
-- #10393
|
|
/-- error: ambiguous pattern, use fully qualified name, possible interpretations [AA.a, A.a] -/
|
|
#guard_msgs in
|
|
open A in
|
|
open AA in
|
|
def f (x : Option Nat) : Id Nat := Id.run do
|
|
if let some a := x then
|
|
22
|
|
else
|
|
33
|
|
|
|
-- #2215
|
|
/-- error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]` -/
|
|
#guard_msgs in
|
|
def foo (bar : Unit → Id Unit): Id Unit := do
|
|
let mut edgeCount : Nat := 0
|
|
match 42 with
|
|
| 42 => bar () edgeCount := 43
|
|
| _ => return ()
|
|
|
|
|
|
open Lean Meta
|
|
|
|
-- #8304: outside `do`, the proper diagnostic is produced
|
|
/--
|
|
error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]`
|
|
|
|
Hint: Using one of these would be valid:
|
|
[apply] `Or.inr`
|
|
[apply] `PSum.inr`
|
|
[apply] `Sum.inr`
|
|
[apply] `Sum.Lex.inr`
|
|
[apply] `Sum.LiftRel.inr`
|
|
-/
|
|
#guard_msgs in
|
|
def test1 : Nat :=
|
|
let a : (Sum Nat Nat) := .inr 1
|
|
let b : (Sum Nat Nat) := .inl 1
|
|
let c : (Sum Nat Nat) := .inr 1
|
|
match a, b, c with
|
|
| .inr x , .inl y, inr z => return x+y+z
|
|
| _,_,_ => return 37
|
|
|
|
-- #8304: inside `do`, the same diagnostic now surfaces too
|
|
/--
|
|
error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]`
|
|
|
|
Hint: Using one of these would be valid:
|
|
[apply] `Or.inr`
|
|
[apply] `PSum.inr`
|
|
[apply] `Sum.inr`
|
|
[apply] `Sum.Lex.inr`
|
|
[apply] `Sum.LiftRel.inr`
|
|
-/
|
|
#guard_msgs in
|
|
def test2 : MetaM Nat:= do
|
|
let a : MetaM (Sum Nat Nat) := return .inr 1
|
|
let b : MetaM (Sum Nat Nat) := return .inl 1
|
|
let c : MetaM (Sum Nat Nat) := return .inr 1
|
|
match ← a, ← b, ← c with
|
|
| .inr x , .inl y, inr z => return x+y+z
|
|
| _,_,_ => return 37
|
|
|
|
/--
|
|
error: Invalid pattern: Expected a constructor or constant marked with `[match_pattern]`
|
|
|
|
Hint: Using one of these would be valid:
|
|
[apply] `Or.inr`
|
|
[apply] `PSum.inr`
|
|
[apply] `Sum.inr`
|
|
[apply] `Sum.Lex.inr`
|
|
[apply] `Sum.LiftRel.inr`
|
|
-/
|
|
#guard_msgs in
|
|
def test3 : MetaM Nat:= do
|
|
let a : MetaM (Sum Nat Nat) := return .inr 1
|
|
let b : MetaM (Sum Nat Nat) := return .inl 1
|
|
let c : MetaM (Sum Nat Nat) := return .inr 1
|
|
let a ← a
|
|
let b ← b
|
|
let c ← c
|
|
match a, b, c with
|
|
| .inr x , .inl y, inr z => return x+y+z
|
|
| _,_,_ => return 37
|