diff --git a/src/Lean/Meta/WHNF.lean b/src/Lean/Meta/WHNF.lean index b72ede6dc9..96d02a6a13 100644 --- a/src/Lean/Meta/WHNF.lean +++ b/src/Lean/Meta/WHNF.lean @@ -429,8 +429,7 @@ mutual else return none if smartUnfolding.get (← getOptions) then - let fAuxInfo? ← getConstNoEx? (mkSmartUnfoldingNameFor fInfo.name) - match fAuxInfo? with + match (← getConstNoEx? (mkSmartUnfoldingNameFor fInfo.name)) with | some fAuxInfo@(ConstantInfo.defnInfo _) => deltaBetaDefinition fAuxInfo fLvls e.getAppRevArgs (fun _ => pure none) fun e₁ => do let e₂ ← whnfUntilIdRhs e₁ @@ -438,7 +437,12 @@ mutual return some (extractIdRhs e₂) else return none - | _ => unfoldDefault () + | _ => + if (← getMatcherInfo? fInfo.name).isSome then + -- Recall that `whnfCore` tries to reduce "matcher" applications. + return none + else + unfoldDefault () else unfoldDefault () | Expr.const declName lvls _ => do diff --git a/tests/lean/run/match1.lean b/tests/lean/run/match1.lean index 3e56661be7..01f1625316 100644 --- a/tests/lean/run/match1.lean +++ b/tests/lean/run/match1.lean @@ -6,16 +6,18 @@ def checkWithMkMatcherInput (matcher : Lean.Name) : Lean.MetaM Unit := let origMatcher ← Lean.getConstInfo matcher if not <| input.matcherName == matcher then throwError "matcher name not reconstructed correctly: {matcher} ≟ {input.matcherName}" - + let lCtx ← Lean.getLCtx let fvars ← Lean.collectFVars {} res.matcher let closure ← Lean.Meta.Closure.mkLambda (fvars.fvarSet.toList.toArray.map lCtx.get!) res.matcher - let origTy := origMatcher.value! + let origTy := origMatcher.value! let newTy ← closure if not <| ←Lean.Meta.isDefEq origTy newTy then throwError "matcher {matcher} does not round-trip correctly:\n{origTy} ≟ {newTy}" - + +set_option smartUnfolding false + def f (xs : List Nat) : List Bool := xs.map fun | 0 => true diff --git a/tests/lean/smartUnfoldingMatch.lean b/tests/lean/smartUnfoldingMatch.lean new file mode 100644 index 0000000000..d52f2bb3ff --- /dev/null +++ b/tests/lean/smartUnfoldingMatch.lean @@ -0,0 +1,12 @@ +import Lean + +open Lean Meta Elab Term in +elab "whnf%" t:term : term <= expectedType => do + let r ← whnf (← elabTerm t expectedType) + trace[Meta.debug] "r: {r}" + return r + +constant x : Option Nat := some 42 + +set_option trace.Meta.debug true +#eval whnf% x.getD 0 diff --git a/tests/lean/smartUnfoldingMatch.lean.expected.out b/tests/lean/smartUnfoldingMatch.lean.expected.out new file mode 100644 index 0000000000..bb471418cd --- /dev/null +++ b/tests/lean/smartUnfoldingMatch.lean.expected.out @@ -0,0 +1,4 @@ +42 +[Meta.debug] r: match x, 0 with + | some x, x_1 => x + | none, e => e