-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Deprecate partial linear indexing #20079
Changes from all commits
f99ace8
abd35fe
5ff6bc4
606c88f
fbb047c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,40 +59,40 @@ end | |
function depwarn(msg, funcsym) | ||
opts = JLOptions() | ||
if opts.depwarn > 0 | ||
ln = Int(unsafe_load(cglobal(:jl_lineno, Cint))) | ||
fn = unsafe_string(unsafe_load(cglobal(:jl_filename, Ptr{Cchar}))) | ||
bt = backtrace() | ||
caller = firstcaller(bt, funcsym) | ||
if opts.depwarn == 1 # raise a warning | ||
warn(msg, once=(caller != C_NULL), key=caller, bt=bt, | ||
filename=fn, lineno=ln) | ||
elseif opts.depwarn == 2 # raise an error | ||
throw(ErrorException(msg)) | ||
end | ||
_depwarn(msg, opts, bt, firstcaller(bt, funcsym)) | ||
end | ||
nothing | ||
end | ||
function _depwarn(msg, opts, bt, caller) | ||
ln = Int(unsafe_load(cglobal(:jl_lineno, Cint))) | ||
fn = unsafe_string(unsafe_load(cglobal(:jl_filename, Ptr{Cchar}))) | ||
if opts.depwarn == 1 # raise a warning | ||
warn(msg, once=(caller != StackTraces.UNKNOWN), key=(caller,fn,ln), bt=bt, | ||
filename=fn, lineno=ln) | ||
elseif opts.depwarn == 2 # raise an error | ||
throw(ErrorException(msg)) | ||
end | ||
end | ||
|
||
function firstcaller(bt::Array{Ptr{Void},1}, funcsym::Symbol) | ||
firstcaller(bt::Array{Ptr{Void},1}, funcsym::Symbol) = firstcaller(bt, (funcsym,)) | ||
function firstcaller(bt::Array{Ptr{Void},1}, funcsyms) | ||
# Identify the calling line | ||
i = 1 | ||
while i <= length(bt) | ||
lkups = StackTraces.lookup(bt[i]) | ||
i += 1 | ||
found = false | ||
lkup = StackTraces.UNKNOWN | ||
for frame in bt | ||
lkups = StackTraces.lookup(frame) | ||
for lkup in lkups | ||
if lkup === StackTraces.UNKNOWN | ||
continue | ||
end | ||
if lkup.func == funcsym | ||
@goto found | ||
end | ||
found && @goto found | ||
found = lkup.func in funcsyms | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these two lines look like they should be reversed to me There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, that's very intentional. The caller is the next stack trace after we find the symbol we're looking for. |
||
end | ||
end | ||
return StackTraces.UNKNOWN | ||
@label found | ||
if i <= length(bt) | ||
return bt[i] | ||
end | ||
return C_NULL | ||
return lkup | ||
end | ||
|
||
deprecate(s::Symbol) = deprecate(current_module(), s) | ||
|
@@ -1739,6 +1739,46 @@ eval(Base.Test, quote | |
export @test_approx_eq | ||
end) | ||
|
||
# Deprecate partial linear indexing | ||
function partial_linear_indexing_warning_lookup(nidxs_remaining) | ||
# We need to figure out how many indices were passed for a sensible deprecation warning | ||
opts = JLOptions() | ||
if opts.depwarn > 0 | ||
# Find the caller -- this is very expensive so we don't want to do it twice | ||
bt = backtrace() | ||
found = false | ||
call = StackTraces.UNKNOWN | ||
caller = StackTraces.UNKNOWN | ||
for frame in bt | ||
lkups = StackTraces.lookup(frame) | ||
for caller in lkups | ||
if caller === StackTraces.UNKNOWN | ||
continue | ||
end | ||
found && @goto found | ||
if caller.func in (:getindex, :setindex!, :view) | ||
found = true | ||
call = caller | ||
end | ||
end | ||
end | ||
@label found | ||
fn = "`reshape`" | ||
if call != StackTraces.UNKNOWN && !isnull(call.linfo) | ||
# Try to grab the number of dimensions in the parent array | ||
mi = get(call.linfo) | ||
args = mi.specTypes.parameters | ||
if length(args) >= 2 && args[2] <: AbstractArray | ||
fn = "`reshape(A, Val{$(ndims(args[2]) - nidxs_remaining + 1)})`" | ||
end | ||
end | ||
_depwarn("Partial linear indexing is deprecated. Use $fn to make the dimensionality of the array match the number of indices.", opts, bt, caller) | ||
end | ||
end | ||
function partial_linear_indexing_warning(n) | ||
depwarn("Partial linear indexing is deprecated. Use `reshape(A, Val{$n})` to make the dimensionality of the array match the number of indices.", (:getindex, :setindex!, :view)) | ||
end | ||
|
||
# Deprecate Array(T, dims...) in favor of proper type constructors | ||
@deprecate Array{T,N}(::Type{T}, d::NTuple{N,Int}) Array{T,N}(d) | ||
@deprecate Array{T}(::Type{T}, d::Int...) Array{T,length(d)}(d...) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the reason for changing
key
fromcaller
to this tuple?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I forgot about this. It came up when I was trying to explicitly catch the depwarns. Without this, the warning misses multiple calls at different points in the same caller. Like in tests. Or large functions.
This should help make finding depreciations a little easier to do in one shot.