(* Cases with let-in in constructors types *)
Unset Printing Allow Match Default Clause.
Inductive t : Set :=
k : let x := t in x -> x.
Print t_rect.
Record TT : Type := CTT { f1 := 0 : nat; f2: nat; f3 : f1=f1 }.
Eval cbv in fun d:TT => match d return 0 = 0 with CTT a _ b => b end.
Eval lazy in fun d:TT => match d return 0 = 0 with CTT a _ b => b end.
(* Do not contract nested patterns with dependent return type *)
(* see bug #1699 *)
Definition proj (x y:nat) (P:nat -> Type) (def:P x) (prf:P y) : P y :=
match eq_nat_dec x y return P y with
| left eqprf =>
match eqprf in (_ = z) return (P z) with
| refl_equal => def
end
| _ => prf
end.
Print proj.
(* Use notations even below aliases *)
Fixpoint foo (A:Type) (l:list A) : option A :=
match l with
| nil => None
| x0 :: nil => Some x0
| x0 :: (x1 :: xs) as l0 => foo A l0
end.
Print foo.
(* Accept and use notation with binded parameters *)
#[universes(template)]
Inductive I (A: Type) : Type := C : A -> I A.
Notation "x <: T" := (C T x) (at level 38).
Definition uncast A (x : I A) :=
match x with
| x <: _ => x
end.
Print uncast.
(* Do not duplicate the matched term *)
Definition foo' :=
match A 0 with
| true => true
| x => x
end.
Print foo'.
(* Was bug #3293 (eta-expansion at "match" printing time was failing because of let-in's interpreted as being part of the expansion)  *)
Inductive B : Prop := AC : P b -> B.
Definition f : B -> True.
Print lem1.
let x := fresh "aa" in
let y := fresh "bb" in
let z := fresh "cc" in
let k := fresh "dd" in
refine (fun k => if k as x return x = x then eq_refl else eq_refl).
Qed.
Print lem2.

Lemma lem3 : forall k, k=k :>nat * nat.