import Lean /-! # Tests of the `#eval` command -/ set_option eval.type true /-! Basic values -/ /-- info: 2 : Nat -/ #guard_msgs in #eval 2 /-- info: some 2 : Option Nat -/ #guard_msgs in #eval some 2 /-- info: [2, 3, 4] : List Nat -/ #guard_msgs in #eval [1,2,3].map (· + 1) /-! Deciding a proposition -/ /-- info: true : Bool -/ #guard_msgs in #eval True /-! Can't evaluate proofs -/ /-- error: Cannot evaluate, proofs are not computationally relevant -/ #guard_msgs in #eval trivial /-! Can't evaluate types -/ /-- error: Cannot evaluate, types are not computationally relevant -/ #guard_msgs in #eval Nat /-! Capturing `dbg_trace` output -/ def Nat.choose : Nat → Nat → Nat | _, 0 => dbg_trace "(_, 0)"; 1 | 0, _ + 1 => dbg_trace "(0, _ + 1)"; 0 | n + 1, k + 1 => dbg_trace "(_ + 1, _ + 1)"; choose n k + choose n (k + 1) /-- info: (_ + 1, _ + 1) (_ + 1, _ + 1) (_, 0) (0, _ + 1) (_ + 1, _ + 1) (0, _ + 1) (0, _ + 1) --- info: 1 : Nat -/ #guard_msgs in #eval Nat.choose 2 2 /-! Custom monad -/ abbrev MyMonad := ReaderT Nat IO /-- error: Unable to synthesize `MonadEval` instance to adapt MyMonad Nat to `IO` or `Lean.Elab.Command.CommandElabM`. -/ #guard_msgs in #eval (pure 2 : MyMonad Nat) -- Note that there is no "this is due to..." diagonostic in this case. /-- error: Could not synthesize a `ToExpr`, `Repr`, or `ToString` instance for type MyMonad (Nat → Nat) -/ #guard_msgs in #eval (pure id : MyMonad (Nat → _)) instance : MonadEval MyMonad IO where monadEval m := m.run 0 /-- info: 2 : Nat -/ #guard_msgs in #eval (pure 2 : MyMonad Nat) -- Note that now we have a MonadEval instance, it doesn't mention MyMonad in the error. /-- error: Could not synthesize a `ToExpr`, `Repr`, or `ToString` instance for type Nat → Nat -/ #guard_msgs in #eval (pure id : MyMonad (Nat → _)) /-! Elaboration error, does not attempt to evaluate. -/ /-- error: Unknown identifier `x` -/ #guard_msgs in #eval 2 + x /-! Defaulting to the CommandElabM monad -/ /-- info: 2 : Nat -/ #guard_msgs in #eval do pure 2 /-- info: true : Bool -/ #guard_msgs in #eval do return (← Lean.getEnv).contains ``Lean.MessageData /-! Defaulting does not affect postponed elaborators. -/ /-- info: 1 : Nat -/ #guard_msgs in #eval if True then 1 else 2 /-! Testing that dbg_trace and logs carry over from all the major meta monads. -/ /-- info: hi --- info: dbg -/ #guard_msgs in #eval show Lean.Elab.Term.TermElabM Unit from do dbg_trace "dbg"; Lean.logInfo m!"hi" /-- info: hi --- info: dbg -/ #guard_msgs in #eval show Lean.MetaM Unit from do dbg_trace "dbg"; Lean.logInfo m!"hi" /-- info: hi --- info: dbg -/ #guard_msgs in #eval show Lean.CoreM Unit from do dbg_trace "dbg"; Lean.logInfo m!"hi" /-! Testing delta deriving -/ def Foo := List Nat def Foo.mk (l : List Nat) : Foo := l /-- info: [1, 2, 3] : Foo -/ #guard_msgs in #eval Foo.mk [1,2,3] /-- info: [1, 2, 3] : Foo -/ #guard_msgs in #eval do return Foo.mk [1,2,3] /-! Testing auto-deriving -/ inductive Baz | a | b /-- info: Baz.a : Baz -/ #guard_msgs in #eval Baz.a /-! Returning after printing -/ def returns : Lean.CoreM Nat := do IO.println "hi" return 2 /-- info: hi --- info: 2 : Nat -/ #guard_msgs in #eval returns /-! Throwing an exception after printing -/ def throwsEx : Lean.CoreM Nat := do IO.println "hi" throwError "ex" /-- info: hi --- error: ex -/ #guard_msgs in #eval throwsEx /-! Let rec support (issue #2374) -/ /-- info: 37 : Nat -/ #guard_msgs in #eval let rec bar : Nat := 1 37 /-- info: 120 : Nat -/ #guard_msgs in #eval let rec fact (n : Nat) : Nat := match n with | 0 => 1 | n' + 1 => n * fact n' fact 5 /-! Elaborate `variables` and have a specific error about referenced free variables, rather than give an "unknown identifier" error while elaborating. -/ section variable (m n : Nat) {α : Type} [DecidableEq α] (x y : α) /-- error: Cannot evaluate, contains free variable `n` -/ #guard_msgs in #eval n /-- error: Cannot evaluate, contains free variables `m` and `n` -/ #guard_msgs in #eval m + n /-! Picks up on decidable instances from the `Prop`->`Bool` conversion too. -/ /-- error: Cannot evaluate, contains free variables `α`, `x`, `y`, and `inst✝` -/ #guard_msgs in #eval x = y end