Sometimes, typing out the problem is all thatβs needed.
julia> function f(a::Expr)
ex = a.args[2]
if ex isa Expr && Meta.isexpr(ex, :(=))
return ex
else
return nothing
end
end;
julia> @code_warntype f(a)
MethodInstance for f(::Expr)
from f(a::Expr) in Main at REPL[43]:1
Arguments
#self#::Core.Const(f)
a::Expr
Locals
ex::Any
Body::Union{Nothing, Expr}
1 β %1 = Base.getproperty(a, :args)::Vector{Any}
β (ex = Base.getindex(%1, 2))
β %3 = (ex isa Main.Expr)::Bool
βββ goto #4 if not %3
2 β %5 = Base.Meta.isexpr::Core.Const(Base.isexpr)
β %6 = ex::Expr
β %7 = (%5)(%6, :(=))::Bool
βββ goto #4 if not %7
3 β return ex::Expr
4 β return Main.nothing
Ops, sorry, I just noticed this particular example doesnβt work on 1.7 β itβs still fixed on 1.8 and higher. Especially, we need this PR to nicely handle this kind of situation (where the conditional object is represented as SSAValue).
julia> versioninfo()
Julia Version 1.8.0-beta2.9
Commit e077335b93 (2022-03-17 01:13 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin21.3.0)
CPU: 8 Γ Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-13.0.1 (ORCJIT, icelake-client)
Threads: 1 on 8 virtual cores
Environment:
JULIA_PROJECT = @.
JULIA_EDITOR = code
JULIA_PKG_DEVDIR = /Users/aviatesk/julia/packages
julia> function f(a::Expr)
ex = a.args[2]
if Meta.isexpr(ex, :(=))
return ex
else
return nothing
end
end
f (generic function with 1 method)
julia> @code_warntype f(:(a = nothing))
MethodInstance for f(::Expr)
from f(a::Expr) in Main at REPL[4]:1
Arguments
#self#::Core.Const(f)
a::Expr
Locals
ex::Any
Body::Union{Nothing, Expr}
1 β %1 = Base.getproperty(a, :args)::Vector{Any}
β (ex = Base.getindex(%1, 2))
β %3 = Base.Meta.isexpr::Core.Const(Base.isexpr)
β %4 = ex::Any
β %5 = (%3)(%4, :(=))::Bool
βββ goto #3 if not %5
2 β return ex::Expr
3 β return Main.nothing