Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,9 @@ Deprecated or removed

* `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`.

* The fallback definition of `eltype` that returned `Any` for any type is deprecated.
Code should be restructured to avoid calling `eltype` on types that might not support it ([#26852]).

Command-line option changes
---------------------------

Expand Down
2 changes: 1 addition & 1 deletion base/abstractdict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ end

function IdDict(kv)
try
dict_with_eltype((K, V) -> IdDict{K, V}, kv, eltype(kv))
dict_with_eltype((K, V) -> IdDict{K, V}, kv, IteratorEltype(typeof(kv)) isa HasEltype ? eltype(kv) : Any)
catch e
if !applicable(start, kv) || !all(x->isa(x,Union{Tuple,Pair}),kv)
throw(ArgumentError(
Expand Down
7 changes: 6 additions & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ julia> eltype(fill(0x1, (2,2)))
UInt8
```
"""
eltype(::Type) = Any
function eltype(t::Type)
# TODO: change post-0.7
#throw(MethodError(eltype, (t,)))
depwarn("The fallback definition of `eltype` is deprecated; either define it for your type or avoid calling it on types that might not support it.", :eltype)
return Any
end
eltype(::Type{Bottom}) = throw(ArgumentError("Union{} does not have elements"))
eltype(x) = eltype(typeof(x))

Expand Down
3 changes: 2 additions & 1 deletion base/asyncmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ end

# pass-through iterator traits to the iterable
# on which the mapping function is being applied
IteratorSize(itr::AsyncGenerator) = SizeUnknown()
IteratorSize(::Type{AsyncGenerator}) = SizeUnknown()
IteratorEltype(::Type{AsyncGenerator}) = EltypeUnknown()
size(itr::AsyncGenerator) = size(itr.collector.enumerator)
length(itr::AsyncGenerator) = length(itr.collector.enumerator)

Expand Down
2 changes: 1 addition & 1 deletion base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ function precise_container_type(@nospecialize(arg), @nospecialize(typ), vtypes::
else
return Any[ p for p in tti0.parameters ]
end
elseif tti0 <: Array
elseif tti0 isa Type{<:Array{T}} where T
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

aren't these supposed to be equivalent, with the subtyping test likely being more reliable

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type{<:Array{T}} where T is a strict subtype of Type{<:Array}, since no value of T turns Array{T} into Array.

return Any[Vararg{eltype(tti0)}]
else
return Any[abstract_iteration(typ, vtypes, sv)]
Expand Down
2 changes: 1 addition & 1 deletion base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Dict(ps::Pair...) = Dict(ps)

function Dict(kv)
try
dict_with_eltype((K, V) -> Dict{K, V}, kv, eltype(kv))
dict_with_eltype((K, V) -> Dict{K, V}, kv, IteratorEltype(typeof(kv)) isa HasEltype ? eltype(kv) : Any)
catch e
if !applicable(start, kv) || !all(x->isa(x,Union{Tuple,Pair}),kv)
throw(ArgumentError("Dict(kv): kv needs to be an iterator of tuples or pairs"))
Expand Down
1 change: 1 addition & 0 deletions base/error.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ function next(ebo::ExponentialBackOff, state)
end
done(ebo::ExponentialBackOff, state) = state[1]<1
length(ebo::ExponentialBackOff) = ebo.n
eltype(::Type{ExponentialBackOff}) = Float64

"""
retry(f::Function; delays=ExponentialBackOff(), check=nothing) -> Function
Expand Down
1 change: 1 addition & 0 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ lastindex(v::SimpleVector) = length(v)
start(v::SimpleVector) = 1
next(v::SimpleVector,i) = (v[i],i+1)
done(v::SimpleVector,i) = (length(v) < i)
eltype(::Type{SimpleVector}) = Any
keys(v::SimpleVector) = OneTo(length(v))
isempty(v::SimpleVector) = (length(v) == 0)
axes(v::SimpleVector) = (OneTo(length(v)),)
Expand Down
19 changes: 11 additions & 8 deletions base/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,8 @@ size(v::Pairs) = size(v.itr)
end
@inline done(v::Pairs, state) = done(v.itr, state)

eltype(::Type{Pairs{K, V}}) where {K, V} = Pair{K, V}

IteratorSize(::Type{Pairs{<:Any, <:Any, I}}) where {I} = IteratorSize(I)
IteratorEltype(::Type{Pairs{<:Any, <:Any, I}}) where {I} = IteratorEltype(I)
IteratorSize(::Type{<:Pairs{<:Any, <:Any, I}}) where {I} = IteratorSize(I)
IteratorEltype(::Type{<:Pairs{<:Any, <:Any, I}}) where {I} = IteratorEltype(I)

reverse(v::Pairs) = Pairs(v.data, reverse(v.itr))

Expand Down Expand Up @@ -472,11 +470,11 @@ start(i::Rest) = i.st
@propagate_inbounds next(i::Rest, st) = next(i.itr, st)
done(i::Rest, st) = done(i.itr, st)

eltype(::Type{Rest{I}}) where {I} = eltype(I)
IteratorEltype(::Type{Rest{I,S}}) where {I,S} = IteratorEltype(I)
eltype(::Type{<:Rest{I}}) where {I} = eltype(I)
IteratorEltype(::Type{<:Rest{I}}) where {I} = IteratorEltype(I)
rest_iteratorsize(a) = SizeUnknown()
rest_iteratorsize(::IsInfinite) = IsInfinite()
IteratorSize(::Type{Rest{I,S}}) where {I,S} = rest_iteratorsize(IteratorSize(I))
IteratorSize(::Type{<:Rest{I}}) where {I} = rest_iteratorsize(IteratorSize(I))

# Count -- infinite counting

Expand Down Expand Up @@ -897,7 +895,10 @@ flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Tuple}) = SizeUnknow
flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Number}) = HasLength()
flatten_iteratorsize(a, b) = SizeUnknown()

IteratorSize(::Type{Flatten{I}}) where {I} = flatten_iteratorsize(IteratorSize(I), eltype(I))
_flatten_iteratorsize(sz, ::EltypeUnknown, I) = SizeUnknown()
_flatten_iteratorsize(sz, ::HasEltype, I) = flatten_iteratorsize(sz, eltype(I))

IteratorSize(::Type{Flatten{I}}) where {I} = _flatten_iteratorsize(IteratorSize(I), IteratorEltype(I), I)

function flatten_length(f, T::Type{<:NTuple{N,Any}}) where {N}
fieldcount(T)*length(f.it)
Expand Down Expand Up @@ -968,6 +969,8 @@ function IteratorSize(::Type{PartitionIterator{T}}) where {T}
partition_iteratorsize(IteratorSize(T))
end

IteratorEltype(::Type{<:PartitionIterator{T}}) where {T} = IteratorEltype(T)

function length(itr::PartitionIterator)
l = length(itr.c)
return div(l, itr.n) + ((mod(l, itr.n) > 0) ? 1 : 0)
Expand Down
1 change: 1 addition & 0 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ isempty(m::MethodList) = isempty(m.ms)
start(m::MethodList) = start(m.ms)
done(m::MethodList, s) = done(m.ms, s)
next(m::MethodList, s) = next(m.ms, s)
eltype(::Type{MethodList}) = Method

function MethodList(mt::Core.MethodTable)
ms = Method[]
Expand Down
1 change: 1 addition & 0 deletions base/reshapedarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ start(R::ReshapedArrayIterator) = start(R.iter)
ReshapedIndex(item), inext
end
length(R::ReshapedArrayIterator) = length(R.iter)
eltype(::Type{<:ReshapedArrayIterator{I}}) where {I} = @isdefined(I) ? ReshapedIndex{eltype(I)} : Any

"""
reshape(A, dims...) -> R
Expand Down
1 change: 1 addition & 0 deletions base/task.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ isempty(c::CompositeException) = isempty(c.exceptions)
start(c::CompositeException) = start(c.exceptions)
next(c::CompositeException, state) = next(c.exceptions, state)
done(c::CompositeException, state) = done(c.exceptions, state)
eltype(::Type{CompositeException}) = Any

function showerror(io::IO, ex::CompositeException)
if !isempty(ex)
Expand Down
2 changes: 1 addition & 1 deletion base/weakkeydict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ WeakKeyDict(ps::Pair...) = WeakKeyDict{Any,Any}(ps)

function WeakKeyDict(kv)
try
Base.dict_with_eltype((K, V) -> WeakKeyDict{K, V}, kv, eltype(kv))
Base.dict_with_eltype((K, V) -> WeakKeyDict{K, V}, kv, IteratorEltype(typeof(kv)) isa HasEltype ? eltype(kv) : Any)
catch e
if !applicable(start, kv) || !all(x->isa(x,Union{Tuple,Pair}),kv)
throw(ArgumentError("WeakKeyDict(kv): kv needs to be an iterator of tuples or pairs"))
Expand Down
3 changes: 1 addition & 2 deletions stdlib/Distributed/src/cluster.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ mutable struct WorkerConfig

function WorkerConfig()
wc = new()
for n in 1:length(WorkerConfig.types)
T = eltype(fieldtype(WorkerConfig, n))
for n in 1:fieldcount(WorkerConfig)
setfield!(wc, n, nothing)
end
wc
Expand Down
6 changes: 3 additions & 3 deletions stdlib/Random/src/Random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct SamplerTrivial{T,E} <: Sampler{E}
self::T
end

SamplerTrivial(x::T) where {T} = SamplerTrivial{T,eltype(T)}(x)
SamplerTrivial(x::T) where {T} = SamplerTrivial{T,Any}(x)

Sampler(::AbstractRNG, x, ::Repetition) = SamplerTrivial(x)

Expand All @@ -144,14 +144,14 @@ struct SamplerSimple{T,S,E} <: Sampler{E}
data::S
end

SamplerSimple(x::T, data::S) where {T,S} = SamplerSimple{T,S,eltype(T)}(x, data)
SamplerSimple(x::T, data::S) where {T,S} = SamplerSimple{T,S,Any}(x, data)

Base.getindex(sp::SamplerSimple) = sp.self

# simple sampler carrying a (type) tag T and data
struct SamplerTag{T,S,E} <: Sampler{E}
data::S
SamplerTag{T}(s::S) where {T,S} = new{T,S,eltype(T)}(s)
SamplerTag{T}(s::S) where {T,S} = new{T,S,Any}(s)
end


Expand Down
5 changes: 4 additions & 1 deletion test/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ end
# ----
let s = "hello"
_, st = next(s, start(s))
@test collect(rest(s, st)) == ['e','l','l','o']
c = collect(rest(s, st))
@test c == ['e','l','l','o']
@test c isa Vector{Char}
end

@test_throws MethodError collect(rest(countfrom(1), 5))
Expand Down Expand Up @@ -452,6 +454,7 @@ end
@test values(d) == A
@test Base.IteratorSize(d) == Base.HasLength()
@test Base.IteratorEltype(d) == Base.HasEltype()
@test Base.IteratorSize(pairs([1 2;3 4])) isa Base.HasShape{2}
@test isempty(d) || haskey(d, first(keys(d)))
@test collect(v for (k, v) in d) == vec(collect(A))
if A isa NamedTuple
Expand Down
3 changes: 2 additions & 1 deletion test/missing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,8 @@ end
@test collect(x) isa Vector{Int}

x = skipmissing(v for v in [missing, 1, missing, 2, 4])
@test eltype(x) === Any
# TODO: enable in v0.7
#@test_throws MethodError eltype(x)
@test collect(x) == [1, 2, 4]
@test collect(x) isa Vector{Int}
end