diff --git a/base/some.jl b/base/some.jl index 0d538cbed6c23..46b912243f859 100644 --- a/base/some.jl +++ b/base/some.jl @@ -138,10 +138,31 @@ true This macro is available as of Julia 1.7. """ macro something(args...) - expr = :(nothing) + noth = GlobalRef(Base, :nothing) + something = GlobalRef(Base, :something) + + # This preserves existing semantics of throwing on `nothing` + expr = :($something($noth)) + + #= + We go through the arguments in reverse + because we're building a nested if/else + expression from the inside out. + The innermost thing to check is the last argument, + which is why we need the last argument first + when building the final expression. + =# for arg in reverse(args) - expr = :(val = $(esc(arg)); val !== nothing ? val : ($expr)) + val = gensym() + expr = quote + $val = $(esc(arg)) + if !isnothing($val) + # unwrap eagerly to help type inference + $something($val) + else + $expr + end + end end - something = GlobalRef(Base, :something) - return :($something($expr)) + return expr end