This PR makes it harder to create "fake" theorems about definitions that are stubbed-out with `sorry` by ensuring that each `sorry` is not definitionally equal to any other. For example, this now fails: ```lean example : (sorry : Nat) = sorry := rfl -- fails ``` However, this still succeeds, since the `sorry` is a single indeterminate `Nat`: ```lean def f (n : Nat) : Nat := sorry example : f 0 = f 1 := rfl -- succeeds ``` One can be more careful by putting parameters to the right of the colon: ```lean def f : (n : Nat) → Nat := sorry example : f 0 = f 1 := rfl -- fails ``` Most sources of synthetic sorries (recall: a sorry that originates from the elaborator) are now unique, except for elaboration errors, since making these unique tends to cause a confusing cascade of errors. In general, however, such sorries are labeled. This enables "go to definition" on `sorry` in the Infoview, which brings you to its origin. The option `set_option pp.sorrySource true` causes the pretty printer to show source position information on sorries. **Details:** * Adds `Lean.Meta.mkLabeledSorry`, which creates a sorry that is labeled with its source position. For example, `(sorry : Nat)` might elaborate to ``` sorryAx (Lean.Name → Nat) false `lean.foo.12.8.12.13.8.13._sorry._@.lean.foo._hyg.153 ``` It can either be made unique (like the above) or merely labeled. Labeled sorries use an encoding that does not impact defeq: ``` sorryAx (Unit → Nat) false (Function.const Lean.Name () `lean.foo.14.7.13.7.13.69._sorry._@.lean.foo._hyg.174) ``` * Makes the `sorry` term, the `sorry` tactic, and every elaboration failure create labeled sorries. Most are unique sorries, but some elaboration errors are labeled sorries. * Renames `OmissionInfo` to `DelabTermInfo` and adds configuration options to control LSP interactions. One field is a source position to use for "go to definition". This is used to implement "go to definition" on labeled sorries. * Makes hovering over a labeled `sorry` show something friendlier than that full `sorryAx` expression. Instead, the first hover shows the simplified ``sorry `«lean.foo:48:11»``. Hovering over that hover shows the full `sorryAx`. Setting `set_option pp.sorrySource true` makes `sorry` always start with printing with this source position information. * Removes `Lean.Meta.mkSyntheticSorry` in favor of `Lean.Meta.mkSorry` and `Lean.Meta.mkLabeledSorry`. * Changes `sorryAx` so that the `synthetic` argument is no longer optional. * Gives `addPPExplicitToExposeDiff` awareness of labeled sorries. It can set `pp.sorrySource` when source positions differ. * Modifies the delaborator framework so that delaborators can set Info themselves without it being overwritten. Incidentally closes #4972. Inspired by [this Zulip thread](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Is.20a.20.60definition_wanted.60.20keyword.20possible.3F/near/477260277).
106 lines
2.2 KiB
Text
106 lines
2.2 KiB
Text
/-!
|
|
# Tests of the `sorry` term elaborator
|
|
-/
|
|
|
|
set_option pp.mvars false
|
|
|
|
/-!
|
|
Basic usage.
|
|
-/
|
|
|
|
/-- warning: declaration uses 'sorry' -/
|
|
#guard_msgs in example : False := sorry
|
|
|
|
/-- warning: declaration uses 'sorry' -/
|
|
#guard_msgs in example : False := by sorry
|
|
|
|
/-!
|
|
Pretty printing
|
|
-/
|
|
|
|
/-- info: sorry : Nat -/
|
|
#guard_msgs in #check (sorry : Nat)
|
|
|
|
/-- info: fun x => sorry : Nat → Nat -/
|
|
#guard_msgs in #check fun x : Nat => (sorry : Nat)
|
|
|
|
/-- info: fun x => sorry (x + 1) : Nat → Nat -/
|
|
#guard_msgs in #check fun x : Nat => (sorry : Nat → Nat) (x + 1)
|
|
|
|
/-!
|
|
Uniqueness
|
|
-/
|
|
|
|
/-- warning: declaration uses 'sorry' -/
|
|
#guard_msgs in
|
|
example : (sorry : Nat) = sorry := by
|
|
fail_if_success rfl
|
|
sorry
|
|
|
|
/-- warning: declaration uses 'sorry' -/
|
|
#guard_msgs in
|
|
def f (n : Nat) : Nat → Nat := sorry
|
|
|
|
example : f 0 0 = f 0 0 := rfl -- succeeds
|
|
|
|
/-!
|
|
If `sorry` is used for a function type, then one gets a family of unique `sorry`s.
|
|
-/
|
|
/--
|
|
error: type mismatch
|
|
rfl
|
|
has type
|
|
?_ = ?_ : Prop
|
|
but is expected to have type
|
|
f 0 1 = f 0 0 : Prop
|
|
-/
|
|
#guard_msgs in example : f 0 1 = f 0 0 := rfl
|
|
|
|
/-!
|
|
It is not completely unique though. The `sorry` did not pay attention to variables in the local context.
|
|
-/
|
|
#guard_msgs in example : f 1 0 = f 0 0 := rfl
|
|
|
|
/-!
|
|
Showing source position when surfacing differences.
|
|
-/
|
|
-- note: the module name is `sorry` and not `lean.run.sorry` in the testing environment,
|
|
-- so this test fails in VS Code.
|
|
/--
|
|
error: type mismatch
|
|
sorry
|
|
has type
|
|
sorry `«sorry:77:43» : Sort _
|
|
but is expected to have type
|
|
sorry `«sorry:77:25» : Sort _
|
|
-/
|
|
#guard_msgs in example : sorry := (sorry : sorry)
|
|
|
|
/-!
|
|
Elaboration errors are just labeled, not unique, to limit cascading errors.
|
|
-/
|
|
/--
|
|
error: unknown identifier 'a'
|
|
---
|
|
error: unknown identifier 'b'
|
|
---
|
|
info: ⊢ sorry = sorry
|
|
-/
|
|
#guard_msgs in
|
|
set_option autoImplicit false in
|
|
example : a = b := by trace_state; rfl
|
|
|
|
/-!
|
|
Showing that the sorries in the previous test are labeled.
|
|
-/
|
|
/--
|
|
error: unknown identifier 'a'
|
|
---
|
|
error: unknown identifier 'b'
|
|
---
|
|
info: ⊢ sorry `«sorry:106:10» = sorry `«sorry:106:14»
|
|
-/
|
|
#guard_msgs in
|
|
set_option autoImplicit false in
|
|
set_option pp.sorrySource true in
|
|
example : a = b := by trace_state; rfl
|