https://github.com/JuliaLang/julia
Tip revision: affe96a42f3ac5f36af70671453babdd58578c9e authored by Milan Bouchet-Valat on 17 January 2021, 17:30:37 UTC
Simplify computation of return type in broadcast
Simplify computation of return type in broadcast
Tip revision: affe96a
deprecated.jl
# This file is a part of Julia. License is MIT: https://julialang.org/license
# Deprecated functions and objects
#
# Please add new deprecations at the bottom of the file.
# A function deprecated in a release will be removed in the next one.
# Please also add a reference to the pull request which introduced the
# deprecation. For simple cases where a direct replacement is available,
# use @deprecate. @deprecate takes care of calling the replacement
# and of exporting the function.
#
# For more complex cases, move the body of the deprecated method in this file,
# and call depwarn() directly from inside it. The symbol depwarn() expects is
# the name of the function, which is used to ensure that the deprecation warning
# is only printed the first time for each call place.
"""
@deprecate old new [ex=true]
Deprecate method `old` and specify the replacement call `new`. Prevent `@deprecate` from
exporting `old` by setting `ex` to `false`. `@deprecate` defines a new method with the same
signature as `old`.
!!! compat "Julia 1.5"
As of Julia 1.5, functions defined by `@deprecate` do not print warning when `julia`
is run without the `--depwarn=yes` flag set, as the default value of `--depwarn` option
is `no`. The warnings are printed from tests run by `Pkg.test()`.
# Examples
```jldoctest
julia> @deprecate old(x) new(x)
old (generic function with 1 method)
julia> @deprecate old(x) new(x) false
old (generic function with 1 method)
```
"""
macro deprecate(old, new, ex=true)
meta = Expr(:meta, :noinline)
if isa(old, Symbol)
oldname = Expr(:quote, old)
newname = Expr(:quote, new)
Expr(:toplevel,
ex ? Expr(:export, esc(old)) : nothing,
:(function $(esc(old))(args...)
$meta
depwarn($"`$old` is deprecated, use `$new` instead.", Core.Typeof($(esc(old))).name.mt.name)
$(esc(new))(args...)
end))
elseif isa(old, Expr) && (old.head === :call || old.head === :where)
remove_linenums!(new)
oldcall = sprint(show_unquoted, old)
newcall = sprint(show_unquoted, new)
# if old.head is a :where, step down one level to the :call to avoid code duplication below
callexpr = old.head === :call ? old : old.args[1]
if callexpr.head === :call
if isa(callexpr.args[1], Symbol)
oldsym = callexpr.args[1]::Symbol
elseif isa(callexpr.args[1], Expr) && callexpr.args[1].head === :curly
oldsym = callexpr.args[1].args[1]::Symbol
else
error("invalid usage of @deprecate")
end
else
error("invalid usage of @deprecate")
end
Expr(:toplevel,
ex ? Expr(:export, esc(oldsym)) : nothing,
:($(esc(old)) = begin
$meta
depwarn($"`$oldcall` is deprecated, use `$newcall` instead.", Core.Typeof($(esc(oldsym))).name.mt.name)
$(esc(new))
end))
else
error("invalid usage of @deprecate")
end
end
function depwarn(msg, funcsym; force::Bool=false)
opts = JLOptions()
if opts.depwarn == 2
throw(ErrorException(msg))
end
deplevel = force || opts.depwarn == 1 ? CoreLogging.Warn : CoreLogging.BelowMinLevel
@logmsg(
deplevel,
msg,
_module=begin
bt = backtrace()
frame, caller = firstcaller(bt, funcsym)
# TODO: Is it reasonable to attribute callers without linfo to Core?
caller.linfo isa Core.MethodInstance ? caller.linfo.def.module : Core
end,
_file=String(caller.file),
_line=caller.line,
_id=(frame,funcsym),
_group=:depwarn,
caller=caller,
maxlog=funcsym === nothing ? nothing : 1
)
nothing
end
firstcaller(bt::Vector, ::Nothing) = Ptr{Cvoid}(0), StackTraces.UNKNOWN
firstcaller(bt::Vector, funcsym::Symbol) = firstcaller(bt, (funcsym,))
function firstcaller(bt::Vector, funcsyms)
# Identify the calling line
found = false
for ip in bt
lkups = StackTraces.lookup(ip)
for lkup in lkups
if lkup == StackTraces.UNKNOWN || lkup.from_c
continue
end
if found
return ip, lkup
end
found = lkup.func in funcsyms
# look for constructor type name
if !found && lkup.linfo isa Core.MethodInstance
li = lkup.linfo
ft = ccall(:jl_first_argument_datatype, Any, (Any,), li.def.sig)
if isa(ft, DataType) && ft.name === Type.body.name
ft = unwrap_unionall(ft.parameters[1])
found = (isa(ft, DataType) && ft.name.name in funcsyms)
end
end
end
end
return C_NULL, StackTraces.UNKNOWN
end
deprecate(m::Module, s::Symbol, flag=1) = ccall(:jl_deprecate_binding, Cvoid, (Any, Any, Cint), m, s, flag)
macro deprecate_binding(old, new, export_old=true, dep_message=:nothing, constant=true)
dep_message === :nothing && (dep_message = ", use $new instead.")
return Expr(:toplevel,
export_old ? Expr(:export, esc(old)) : nothing,
Expr(:const, Expr(:(=), esc(Symbol(string("_dep_message_",old))), esc(dep_message))),
constant ? Expr(:const, Expr(:(=), esc(old), esc(new))) : Expr(:(=), esc(old), esc(new)),
Expr(:call, :deprecate, __module__, Expr(:quote, old)))
end
macro deprecate_stdlib(old, mod, export_old=true, newname=old)
rename = old === newname ? "" : " as `$newname`"
dep_message = """: it has been moved to the standard library package `$mod`$rename.
Add `using $mod` to your imports."""
new = GlobalRef(Base.root_module(Base, mod), newname)
return Expr(:toplevel,
export_old ? Expr(:export, esc(old)) : nothing,
Expr(:const, Expr(:(=), esc(Symbol(string("_dep_message_",old))), esc(dep_message))),
Expr(:const, Expr(:(=), esc(old), esc(new))),
Expr(:call, :deprecate, __module__, Expr(:quote, old)))
end
macro deprecate_moved(old, new, export_old=true)
eold = esc(old)
emsg = string(old, " has been moved to the package ", new, ".jl.\n",
"Run `Pkg.add(\"", new, "\")` to install it, restart Julia,\n",
"and then run `using ", new, "` to load it.")
return Expr(:toplevel,
:($eold(args...; kwargs...) = error($emsg)),
export_old ? Expr(:export, eold) : nothing,
Expr(:call, :deprecate, __module__, Expr(:quote, old), 2))
end
# BEGIN 1.0 deprecations
@deprecate one(i::CartesianIndex) oneunit(i)
@deprecate one(I::Type{CartesianIndex{N}}) where {N} oneunit(I)
@deprecate BigFloat(x, prec::Int) BigFloat(x; precision=prec)
@deprecate BigFloat(x, prec::Int, rounding::RoundingMode) BigFloat(x, rounding; precision=prec)
@deprecate BigFloat(x::Real, prec::Int) BigFloat(x; precision=prec)
@deprecate BigFloat(x::Real, prec::Int, rounding::RoundingMode) BigFloat(x, rounding; precision=prec)
# END 1.0 deprecations
# BEGIN 1.5 deprecations
"""
isimmutable(v) -> Bool
!!! warning
Consider using `!ismutable(v)` instead, as `isimmutable(v)` will be replaced by `!ismutable(v)` in a future release. (Since Julia 1.5)
Return `true` iff value `v` is immutable. See [Mutable Composite Types](@ref)
for a discussion of immutability. Note that this function works on values, so if you give it
a type, it will tell you that a value of `DataType` is mutable.
# Examples
```jldoctest
julia> isimmutable(1)
true
julia> isimmutable([1,2])
false
```
"""
isimmutable(@nospecialize(x)) = !ismutable(x)
export isimmutable
# Note isimmutable is not @deprecated out of performance concerns
macro get!(h, key0, default)
f, l = __source__.file, __source__.line
@warn "`@get!(dict, key, default)` at $f:$l is deprecated, use `get!(()->default, dict, key)` instead."
return quote
get!(()->$(esc(default)), $(esc(h)), $(esc(key0)))
end
end
pointer(V::SubArray{<:Any,<:Any,<:Array,<:Tuple{Vararg{RangeIndex}}}, is::Tuple) = pointer(V, CartesianIndex(is))
# END 1.5 deprecations
# BEGIN 1.6 deprecations
# These changed from SimpleVector to `MethodMatch`. These definitions emulate
# being a SimpleVector to ease transition for packages that make explicit
# use of (internal) APIs that return raw method matches.
iterate(match::Core.MethodMatch, field::Int=1) =
field > nfields(match) ? nothing : (getfield(match, field), field+1)
getindex(match::Core.MethodMatch, field::Int) =
getfield(match, field)
# these were internal functions, but some packages seem to be relying on them
tuple_type_head(T::Type) = fieldtype(T, 1)
tuple_type_cons(::Type, ::Type{Union{}}) = Union{}
function tuple_type_cons(::Type{S}, ::Type{T}) where T<:Tuple where S
@_pure_meta
Tuple{S, T.parameters...}
end
function parameter_upper_bound(t::UnionAll, idx)
@_pure_meta
return rewrap_unionall((unwrap_unionall(t)::DataType).parameters[idx], t)
end
# these were internal functions, but some packages seem to be relying on them
@deprecate cat_shape(dims, shape::Tuple{}, shapes::Tuple...) cat_shape(dims, shapes)
cat_shape(dims, shape::Tuple{}) = () # make sure `cat_shape(dims, ())` do not recursively calls itself
# END 1.6 deprecations