/-! # Tests that type annotations in binders are cleaned up when elaborating declaration bodies -/ set_option linter.unusedVariables false set_option pp.mvars false /-! Test definitions, theorems, and instances. (MutualDef elaborator) Both scope variables and header variables are handled. -/ section variable (a := true) /-- trace: a : Bool b : Nat ⊢ True -/ #guard_msgs in def d1 (b := 0) : Bool := have : True := by trace_state; trivial a /-- info: d1 (a : Bool := true) (b : Nat := 0) : Bool -/ #guard_msgs in #check d1 /-- trace: a : Bool h : a = true b : Nat ⊢ True -/ #guard_msgs in theorem t1 (h : a) (b := 0) : True := by trace_state trivial /-- info: t1 (a : Bool := true) (h : a = true) (b : Nat := 0) : True -/ #guard_msgs in #check t1 /-- trace: a : Bool b : Nat ⊢ True -/ #guard_msgs in instance i1 (b := 0) : Decidable (a.toNat = b) := have : True := by trace_state; trivial inferInstance /-- info: i1 (a : Bool := true) (b : Nat := 0) : Decidable (a.toNat = b) -/ #guard_msgs in #check i1 /-! Mutually recursive functions still can make use of optional parameters -/ mutual def d2 (b := 0) (c : Bool := true) : Bool := if c then match b with | 0 => true | b' + 1 => d3 b' else true def d3 (b := 0) : Bool := d2 b end /-- info: d2 (b : Nat := 0) (c : Bool := true) : Bool -/ #guard_msgs in #check d2 /-- info: d3 (b : Nat := 0) : Bool -/ #guard_msgs in #check d3 /-! Function elaboration cleans up annotations while propagating the expected type. -/ structure S where f : (x : Nat := 0) → Nat /-- trace: a : Bool y : Nat ⊢ Nat -/ #guard_msgs in example : S where f := fun y => by trace_state; exact y /-- trace: a : Bool y : Nat ⊢ Nat -/ #guard_msgs in example : S where f y := by trace_state; exact y /-! The function itself does not encode the annotations. -/ /-- info: fun x => x : Nat → Nat -/ #guard_msgs in #check ((fun x => x) : (x : Nat := 0) → Nat) /-! Let bindings clean up annotations while elaborating values, and they preserve the annotations in the resulting let binding. -/ /-- trace: a : Bool x : Nat ⊢ ?_ x --- trace: a : Bool f : optParam Nat 0 → Nat := fun x => x ⊢ True -/ #guard_msgs in example : True := let f (x : Nat := 0) := by trace_state; exact x by trace_state; trivial end /-! Let rec, both as `where` and as real `let rec`. -/ /-- trace: n✝ : Nat x : Bool n : Nat ⊢ Nat -/ #guard_msgs in def bar := go 1000 where go (n : Nat) (x := true) := match n with | 0 => 0 | n+1 => by trace_state; exact go n + 1 /-- trace: n✝ : Nat x : Bool n : Nat ⊢ Nat -/ #guard_msgs in def bar' := let rec go (n : Nat) (x := true) := match n with | 0 => 0 | n+1 => by trace_state; exact go n + 1 go 1000 /-- info: bar.go (n : Nat) (x : Bool := true) : Nat -/ #guard_msgs in #check bar.go /-- info: bar'.go (n : Nat) (x : Bool := true) : Nat -/ #guard_msgs in #check bar'.go