WHERE THERE’S A WILL, THERE’S A WAY!!
Check this out. BorrowChecker.jl now uses Cassette.jl to overdub Core.setfield!(::Core.Box, :contents, ...) so that if you try to capture any Bound variable in a closure, an error will be thrown:
julia> using BorrowChecker
julia> function f()
@bind x = 1
function g()
x = x + 1
end
g()
return x
end
f (generic function with 1 method)
julia> BorrowChecker.@managed begin
f()
end
ERROR: You are not allowed to capture bound variable `x` inside a closure.
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
Works like this:
function Cassette.overdub(ctx::ManagedCtx, f, args...)
if f == Core.setfield! &&
length(args) == 3 &&
args[1] isa Core.Box &&
args[2] == :contents &&
args[3] isa Union{Bound,BoundMut}
symbol = args[3].symbol
error("You are not allowed to capture bound variable `$(symbol)` inside a closure.")
end
#= Other overdubbing =#
end
(And before anybody says “this is hacky, don’t do this, etc.”, yes, I know. BorrowChecker.jl is not going to be standard Julia code. That’s ok though, because it’s just a debugging tool!)