/- Copyright (c) 2021 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura -/ import Lean.Meta.WHNF import Lean.Meta.Transform namespace Lean.Meta /-- Return true iff `declName` is one of the auxiliary definitions/projections used to implement coercions. -/ def isCoeDecl (declName : Name) : Bool := declName == ``Coe.coe || declName == ``CoeTC.coe || declName == ``CoeHead.coe || declName == ``CoeTail.coe || declName == ``CoeHTCT.coe || declName == ``CoeDep.coe || declName == ``CoeT.coe || declName == ``CoeFun.coe || declName == ``CoeSort.coe || declName == ``Lean.Internal.liftCoeM || declName == ``Lean.Internal.coeM /-- Expand coercions occurring in `e` -/ partial def expandCoe (e : Expr) : MetaM Expr := withReducibleAndInstances do return (← transform e (pre := step)) where step (e : Expr) : MetaM TransformStep := do let f := e.getAppFn if !f.isConst then return TransformStep.visit e else let declName := f.constName! if isCoeDecl declName then match (← unfoldDefinition? e) with | none => return TransformStep.visit e | some e => step e.headBeta else return TransformStep.visit e end Lean.Meta