Skip to content

Commit 4606c35

Browse files
leodemouraKha
andauthored
feat: @[instance_reducible] (#12247)
This PR adds the new transparency setting `@[instance_reducible]`. We used to check whether a declaration had `instance` reducibility by using the `isInstance` predicate. However, this was not a robust solution because: - We have scoped instances, and `isInstance` returns `true` only if the scope is active. - We have auxiliary declarations used to construct instances manually, such as: ```lean def lt_wfRel : WellFoundedRelation Nat ``` `isInstance` also returns `false` for this kind of declaration. In both cases, the declaration may be (or may have been) used to construct an instance, but `isInstance` returns `false`. Thus, we claim it is a mistake to check the reducibility status using `isInstance`. `isInstance` indicates whether a declaration is available for the type class resolution mechanism, not its transparency status. **We are decoupling whether a declaration is available for type class resolution from its transparency status.** **Remak**: We need a update stage0 to complete this feature. --------- Co-authored-by: Sebastian Ullrich <[email protected]>
1 parent 9f4c813 commit 4606c35

37 files changed

+185
-124
lines changed

src/Init/Syntax.lean

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@ Copyright (c) 2020 Microsoft Corporation. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Leonardo de Moura, Mario Carneiro
55
-/
6-
76
module
8-
97
prelude
108
public import Init.Data.Array.Set
11-
129
public section
1310

1411
/-!

src/Lean/Compiler/LCNF/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ def Decl.isTemplateLike (decl : Decl pu) : CoreM Bool := do
746746
let env ← getEnv
747747
if ← hasLocalInst decl.type then
748748
return true -- `decl` applications will be specialized
749-
else if Meta.isInstanceCore env decl.name then
749+
else if (← isInstanceReducible decl.name) then
750750
return true -- `decl` is "fuel" for code specialization
751751
else if decl.inlineable || hasSpecializeAttribute env decl.name then
752752
return true -- `decl` is going to be inlined or specialized

src/Lean/Compiler/LCNF/LambdaLifting.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def eagerLambdaLifting : Pass where
214214
name := `eagerLambdaLifting
215215
run := fun decls => do
216216
decls.foldlM (init := #[]) fun decls decl => do
217-
if decl.inlineable || (← Meta.isInstance decl.name) then
217+
if decl.inlineable || (← isInstanceReducible decl.name) then
218218
return decls.push decl
219219
else
220220
return decls ++ (← decl.lambdaLifting (liftInstParamOnly := true) (allowEtaContraction := false) (suffix := `_elam))

src/Lean/Compiler/LCNF/Simp/InlineCandidate.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def inlineCandidate? (e : LetValue .pure) : SimpM (Option InlineCandidateInfo) :
5656
We assume that at the base phase these annotations are for the instance methods that have been lambda lifted.
5757
-/
5858
if (← inBasePhase) then
59-
if (← Meta.isInstance decl.name) then
59+
if (← isInstanceReducible decl.name) then
6060
unless decl.name == ``instDecidableEqBool do
6161
/-
6262
TODO: remove this hack after we refactor `Decidable` as suggested by Gabriel.

src/Lean/Compiler/LCNF/Simp/Main.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def etaPolyApp? (letDecl : LetDecl .pure) : OptionT SimpM (FunDecl .pure) := do
7676
let .const declName us args := letDecl.value | failure
7777
let some info := (← getEnv).find? declName | failure
7878
guard <| (← hasLocalInst info.type)
79-
guard <| !(← Meta.isInstance declName)
79+
guard <| !(← isInstanceReducible declName)
8080
let some ⟨.pure, decl⟩ ← getDecl? declName | failure
8181
guard <| decl.getArity > args.size
8282
let params ← mkNewParams letDecl.type

src/Lean/Compiler/LCNF/Specialize.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ mutual
399399
partial def specializeApp? (e : LetValue .pure) : SpecializeM (Option (LetValue .pure)) := do
400400
let .const declName us args := e | return none
401401
if args.isEmpty then return none
402-
if (← Meta.isInstance declName) then return none
402+
if (← isInstanceReducible declName) then return none
403403
let some specEntry ← getSpecEntry? declName | return none
404404
unless (← shouldSpecialize specEntry args) do return none
405405
let some ⟨.pure, decl⟩ ← getDecl? declName | return none

src/Lean/Elab/DeclModifiers.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ def Modifiers.addFirstAttr (modifiers : Modifiers) (attr : Attribute) : Modifier
125125
def Modifiers.filterAttrs (modifiers : Modifiers) (p : Attribute → Bool) : Modifiers :=
126126
{ modifiers with attrs := modifiers.attrs.filter p }
127127

128+
/-- Returns `true` if `modifiers` contains an attribute satisfying `p`. -/
129+
def Modifiers.anyAttr (modifiers : Modifiers) (p : Attribute → Bool) : Bool :=
130+
modifiers.attrs.any p
131+
128132
instance : ToFormat Modifiers := ⟨fun m =>
129133
let components : List Format :=
130134
(match m.docString? with

src/Lean/Elab/DefView.lean

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Leonardo de Moura, Sebastian Ullrich
55
-/
66
module
7-
87
prelude
98
public import Lean.Elab.DeclNameGen
109
public import Lean.Elab.DeclUtil
11-
1210
public section
13-
1411
namespace Lean.Elab
1512

1613
inductive DefKind where
@@ -165,11 +162,18 @@ def mkDefViewOfTheorem (modifiers : Modifiers) (stx : Syntax) : DefView :=
165162

166163
def mkDefViewOfInstance (modifiers : Modifiers) (stx : Syntax) : CommandElabM DefView := do
167164
-- leading_parser Term.attrKind >> "instance " >> optNamedPrio >> optional declId >> declSig >> declVal
165+
/-
166+
**Note**: add `instance_reducible` attribute if declaration is not already marked with `@[reducible]`
167+
-/
168+
let modifiers := if modifiers.anyAttr fun attr => attr.name == `reducible then
169+
modifiers
170+
else
171+
modifiers.addAttr { name := `instance_reducible }
168172
let attrKind ← liftMacroM <| toAttributeKind stx[0]
169173
let prio ← liftMacroM <| expandOptNamedPrio stx[2]
170174
let attrStx ← `(attr| instance $(quote prio):num)
171-
let (binders, type) := expandDeclSig stx[4]
172175
let modifiers := modifiers.addAttr { kind := attrKind, name := `instance, stx := attrStx }
176+
let (binders, type) := expandDeclSig stx[4]
173177
let declId ← match stx[3].getOptional? with
174178
| some declId =>
175179
if ← isTracingEnabledFor `Elab.instance.mkInstanceName then

src/Lean/Elab/Deriving/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def processDefDeriving (view : DerivingClassView) (decl : Expr) : TermElabM Unit
205205
let decl ← mkDefinitionValInferringUnsafe instName result.levelParams.toList result.type result.value hints
206206
addAndCompile (logCompileErrors := !(← read).isNoncomputableSection) <| Declaration.defnDecl decl
207207
trace[Elab.Deriving] "Derived instance `{.ofConstName instName}`"
208-
addInstance instName AttributeKind.global (eval_prio default)
208+
registerInstance instName AttributeKind.global (eval_prio default)
209209
addDeclarationRangesFromSyntax instName (← getRef)
210210

211211
end Term

src/Lean/Elab/MutualDef.lean

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Leonardo de Moura
55
-/
66
module
7-
87
prelude
98
public import Lean.Elab.Deriving.Basic
109
public import Lean.Elab.PreDefinition.Main
1110
import all Lean.Elab.ErrorUtils
12-
1311
public section
14-
1512
namespace Lean.Elab
1613
open Lean.Parser.Term
1714

0 commit comments

Comments
 (0)