From 4c3ae2011041670d1f1552da270e4195f4e689d8 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Tue, 26 Oct 2021 21:48:32 +1000 Subject: [PATCH] Make Base.ifelse a generic function (#37343) Allow user code to directly extend `Base.ifelse` rather than needing a special package for it. --- base/boot.jl | 4 ++-- base/compiler/abstractinterpretation.jl | 2 +- base/compiler/optimize.jl | 2 +- base/compiler/tfuncs.jl | 2 +- base/essentials.jl | 16 ++++++++++++++++ base/operators.jl | 16 ---------------- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/base/boot.jl b/base/boot.jl index 4679acd85d26d..b9de755ed8125 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -192,8 +192,8 @@ export Expr, QuoteNode, LineNumberNode, GlobalRef, # object model functions fieldtype, getfield, setfield!, swapfield!, modifyfield!, replacefield!, - nfields, throw, tuple, ===, isdefined, eval, ifelse, - # sizeof # not exported, to avoid conflicting with Base.sizeof + nfields, throw, tuple, ===, isdefined, eval, + # ifelse, sizeof # not exported, to avoid conflicting with Base # type reflection <:, typeof, isa, typeassert, # method reflection diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 2c7e26428c7b6..b338a80cbbe74 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1082,7 +1082,7 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, (; fargs sv::InferenceState, max_methods::Int) @nospecialize f la = length(argtypes) - if f === ifelse && fargs isa Vector{Any} && la == 4 + if f === Core.ifelse && fargs isa Vector{Any} && la == 4 cnd = argtypes[2] if isa(cnd, Conditional) newcnd = widenconditional(cnd) diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index eb80c336fc7d4..53f59f8487031 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -162,7 +162,7 @@ const _PURE_BUILTINS = Any[tuple, svec, ===, typeof, nfields] const _PURE_OR_ERROR_BUILTINS = [ fieldtype, apply_type, isa, UnionAll, getfield, arrayref, const_arrayref, isdefined, Core.sizeof, - Core.kwfunc, ifelse, Core._typevar, (<:) + Core.kwfunc, Core.ifelse, Core._typevar, (<:) ] const TOP_TUPLE = GlobalRef(Core, :tuple) diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index c2cab794ee6b3..cac266ff9ce6c 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -231,7 +231,7 @@ function ifelse_tfunc(@nospecialize(cnd), @nospecialize(x), @nospecialize(y)) end return tmerge(x, y) end -add_tfunc(ifelse, 3, 3, ifelse_tfunc, 1) +add_tfunc(Core.ifelse, 3, 3, ifelse_tfunc, 1) function egal_tfunc(@nospecialize(x), @nospecialize(y)) xx = widenconditional(x) diff --git a/base/essentials.jl b/base/essentials.jl index 5280252f1946a..cd4b618b5b0b1 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -477,6 +477,22 @@ Stacktrace: """ sizeof(x) = Core.sizeof(x) +""" + ifelse(condition::Bool, x, y) + +Return `x` if `condition` is `true`, otherwise return `y`. This differs from `?` or `if` in +that it is an ordinary function, so all the arguments are evaluated first. In some cases, +using `ifelse` instead of an `if` statement can eliminate the branch in generated code and +provide higher performance in tight loops. + +# Examples +```jldoctest +julia> ifelse(1 > 2, 1, 2) +2 +``` +""" +ifelse(condition::Bool, x, y) = Core.ifelse(condition, x, y) + # simple Array{Any} operations needed for bootstrap @eval setindex!(A::Array{Any}, @nospecialize(x), i::Int) = arrayset($(Expr(:boundscheck)), A, x, i) diff --git a/base/operators.jl b/base/operators.jl index ebd1d515f92b0..82b393e0a9e9e 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -429,22 +429,6 @@ const ≥ = >= # which is more idiomatic: isless(x::Real, y::Real) = x ifelse(1 > 2, 1, 2) -2 -``` -""" -ifelse - """ cmp(x,y)