diff --git a/Qq/Macro.lean b/Qq/Macro.lean index 4f1a5ea..d7ce920 100644 --- a/Qq/Macro.lean +++ b/Qq/Macro.lean @@ -253,6 +253,10 @@ partial def unquoteExpr (e : Expr) : UnquoteM Expr := do abstractedFVars := s.abstractedFVars.push fvarId } return fv + if let .fvar _ := e then + Lean.logWarning m!"Interpolated variable `{e}` should have type `Q(_)` not `{eTy}`. \ + Adding `have {e} : Q(_) := {e}` may fix this." + return e let e ← whnf e let .const c _ := e.getAppFn | throwError "unquoteExpr: {e} : {eTy}" let nargs := e.getAppNumArgs diff --git a/examples/unquoteExprWarning.lean b/examples/unquoteExprWarning.lean new file mode 100644 index 0000000..d993386 --- /dev/null +++ b/examples/unquoteExprWarning.lean @@ -0,0 +1,31 @@ +import Lean +import Qq.Macro + +open Qq +open Lean Meta Elab Tactic Command + +elab "iff_constructor" : tactic => do + let mvarId ← getMainGoal + let goalType ← getMainTarget + + let_expr Iff a b := goalType + | throwError "Goal type is not of the form `a ↔ b`" + + let a : Q(Prop) := a + let b : Q(Prop) := b + + let mvarId1 ← mkFreshExprMVar q($a → $b) (userName := `mp) + let mvarId2 ← mkFreshExprMVar q($b → $a) (userName := `mpr) + + let mvarId1 : Q($a → $b) := mvarId1 + let mvarId2 : Q($b → $a) := mvarId2 + + mvarId.assign q(@Iff.intro $a $b $mvarId1 $mvarId2) + + modify fun _ => { goals := [mvarId1.mvarId!, mvarId2.mvarId!] } + +example (p q : Prop) (h1 : p → q) (h2 : q → p) : p ↔ q := by + iff_constructor + + case mp => assumption + case mpr => assumption