building upon #3714, this (almost) implements the second half of #3302. The main effect is that we now get a better error message when `rfl` fails. For ```lean example : n+1+m = n + (1+m) := by rfl ``` instead of the wall of text ``` The rfl tactic failed. Possible reasons: - The goal is not a reflexive relation (neither `=` nor a relation with a @[refl] lemma). - The arguments of the relation are not equal. Try using the reflexivity lemma for your relation explicitly, e.g. `exact Eq.refl _` or `exact HEq.rfl` etc. n m : Nat ⊢ n + 1 + m = n + (1 + m) ``` we now get ``` error: tactic 'rfl' failed, the left-hand side n + 1 + m is not definitionally equal to the right-hand side n + (1 + m) n m : Nat ⊢ n + 1 + m = n + (1 + m) ``` Unfortunately, because of very subtle differences in semantics (which transparency setting is used when reducing the goal and whether the “implicit lambda” feature applies) I could not make this simply the only `rfl` implementation. So `rfl` remains a macro and is still expanded to `eq_refl` (difference transparency setting) and `exact Iff.rfl` and `exact HEq.rfl` (implicit lambda) to not break existing code. This can be revised later, so this still closes: #3302. A user might still be puzzled *why* to terms are not defeq. Explaining that better (“reduced to… and reduces to… etc.”) would also be great, but that’s not specific to `rfl`, so better left for some other time.
25 lines
566 B
Text
25 lines
566 B
Text
/-!
|
|
The (attribute-extensible) `rfl` tactic only unfolds the goal with reducible transparency to look
|
|
for a relation which may have a `refl` lemma associated with it. But historically, `rfl` also
|
|
invoked `eq_refl`, which more aggressively unfolds. This checks that this still works.
|
|
-/
|
|
|
|
def Foo (a b : Nat) : Prop := a = b
|
|
|
|
/--
|
|
error: tactic 'rfl' failed, no @[refl] lemma registered for relation
|
|
Foo
|
|
⊢ Foo 1 1
|
|
-/
|
|
#guard_msgs in
|
|
example : Foo 1 1 := by
|
|
apply_rfl
|
|
|
|
|
|
#guard_msgs in
|
|
example : Foo 1 1 := by
|
|
eq_refl
|
|
|
|
#guard_msgs in
|
|
example : Foo 1 1 := by
|
|
rfl
|