mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-17 10:24:07 +00:00
feat: option to ignore borrowing annotations completely (#12886)
This PR adds support for ignoring user defined borrow annotations. This can be useful when defining `extern`/`export` pairs as the `extern` might be infected by borrow annotations while in `export` they are already ignored.
This commit is contained in:
@@ -15,6 +15,7 @@ import Lean.Compiler.LCNF.ExplicitBoxing
|
||||
import Lean.Compiler.LCNF.Internalize
|
||||
public import Lean.Compiler.ExternAttr
|
||||
import Lean.Compiler.LCNF.ExplicitRC
|
||||
import Lean.Compiler.Options
|
||||
|
||||
public section
|
||||
|
||||
@@ -32,9 +33,10 @@ where
|
||||
let type ← Compiler.LCNF.getOtherDeclMonoType declName
|
||||
let mut typeIter := type
|
||||
let mut params := #[]
|
||||
let ignoreBorrow := Compiler.compiler.ignoreBorrowAnnotation.get (← getOptions)
|
||||
repeat
|
||||
let .forallE binderName ty b _ := typeIter | break
|
||||
let borrow := isMarkedBorrowed ty
|
||||
let borrow := !ignoreBorrow && isMarkedBorrowed ty
|
||||
params := params.push {
|
||||
fvarId := (← mkFreshFVarId)
|
||||
type := ty,
|
||||
|
||||
@@ -7,10 +7,13 @@ module
|
||||
prelude
|
||||
public import Lean.Compiler.InitAttr
|
||||
public import Lean.Compiler.LCNF.ToLCNF
|
||||
import Lean.Compiler.Options
|
||||
import Lean.Meta.Transform
|
||||
import Lean.Meta.Match.MatcherInfo
|
||||
import Init.While
|
||||
|
||||
public section
|
||||
|
||||
namespace Lean.Compiler.LCNF
|
||||
/--
|
||||
Inline constants tagged with the `[macro_inline]` attribute occurring in `e`.
|
||||
@@ -127,10 +130,11 @@ def toDecl (declName : Name) : CompilerM (Decl .pure) := do
|
||||
let paramsFromTypeBinders (expr : Expr) : CompilerM (Array (Param .pure)) := do
|
||||
let mut params := #[]
|
||||
let mut currentExpr := expr
|
||||
let ignoreBorrow := compiler.ignoreBorrowAnnotation.get (← getOptions)
|
||||
repeat
|
||||
match currentExpr with
|
||||
| .forallE binderName type body _ =>
|
||||
let borrow := isMarkedBorrowed type
|
||||
let borrow := !ignoreBorrow && isMarkedBorrowed type
|
||||
params := params.push (← mkParam binderName type borrow)
|
||||
currentExpr := body
|
||||
| _ => break
|
||||
@@ -156,12 +160,15 @@ def toDecl (declName : Name) : CompilerM (Decl .pure) := do
|
||||
let value ← macroInline value
|
||||
return (type, value)
|
||||
let code ← toLCNF value
|
||||
let decl ← if let .fun decl (.return _) := code then
|
||||
let mut decl ← if let .fun decl (.return _) := code then
|
||||
eraseFunDecl decl (recursive := false)
|
||||
pure { name := declName, params := decl.params, type, value := .code decl.value, levelParams := info.levelParams, safe, inlineAttr? : Decl .pure }
|
||||
else
|
||||
pure { name := declName, params := #[], type, value := .code code, levelParams := info.levelParams, safe, inlineAttr? }
|
||||
/- `toLCNF` may eta-reduce simple declarations. -/
|
||||
decl.etaExpand
|
||||
decl ← decl.etaExpand
|
||||
if compiler.ignoreBorrowAnnotation.get (← getOptions) then
|
||||
decl := { decl with params := ← decl.params.mapM (·.updateBorrow false) }
|
||||
return decl
|
||||
|
||||
end Lean.Compiler.LCNF
|
||||
|
||||
@@ -35,4 +35,10 @@ register_builtin_option compiler.relaxedMetaCheck : Bool := {
|
||||
descr := "Allow mixed `meta`/non-`meta` references in the same module. References to imports are unaffected."
|
||||
}
|
||||
|
||||
register_builtin_option compiler.ignoreBorrowAnnotation : Bool := {
|
||||
defValue := false
|
||||
descr := "Ignore user defined borrow inference annotations. This is useful for export/extern \
|
||||
forward declarations"
|
||||
}
|
||||
|
||||
end Lean.Compiler
|
||||
|
||||
38
tests/elab/compiler_disable_borrow_annotations.lean
Normal file
38
tests/elab/compiler_disable_borrow_annotations.lean
Normal file
@@ -0,0 +1,38 @@
|
||||
module
|
||||
|
||||
/-!
|
||||
This test asserts that disabling user-defined borrow annotations works. This is sometimes required for
|
||||
export/extern pairs
|
||||
-/
|
||||
|
||||
public abbrev Foo (α : Type) := (x : @& α) → α
|
||||
|
||||
/--
|
||||
trace: [Compiler.result] size: 0
|
||||
def t1 @&x : tobj :=
|
||||
extern
|
||||
[Compiler.result] size: 2
|
||||
def t1._boxed x : tobj :=
|
||||
let res := t1 x;
|
||||
dec x;
|
||||
return res
|
||||
-/
|
||||
#guard_msgs in
|
||||
set_option trace.Compiler.result true in
|
||||
@[extern "t1"]
|
||||
public opaque t1 : Foo Nat
|
||||
|
||||
/--
|
||||
trace: [Compiler.result] size: 0
|
||||
def t2 x : tobj :=
|
||||
extern
|
||||
[Compiler.result] size: 1
|
||||
def t2._boxed x : tobj :=
|
||||
let res := t2 x;
|
||||
return res
|
||||
-/
|
||||
#guard_msgs in
|
||||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
set_option trace.Compiler.result true in
|
||||
@[extern "t2"]
|
||||
public opaque t2 : Foo Nat
|
||||
Reference in New Issue
Block a user