diff --git a/base/array.jl b/base/array.jl index fad82af049850..a24a7773477a7 100644 --- a/base/array.jl +++ b/base/array.jl @@ -283,14 +283,10 @@ function _collect(cont, itr, ::HasEltype, isz::SizeUnknown) end if isdefined(Core, :Inference) - function _default_eltype(itrt::ANY) - rt = Core.Inference.return_type(first, Tuple{itrt}) - return isleaftype(rt) ? rt : Union{} - end + _default_eltype(itrt::ANY) = Core.Inference.return_type(first, Tuple{itrt}) else - _default_eltype(itr::ANY) = Union{} + _default_eltype(itr::ANY) = Any end -_default_eltype{I,T}(::Type{Generator{I,Type{T}}}) = T _array_for(T, itr, ::HasLength) = Array{T,1}(Int(length(itr)::Integer)) _array_for(T, itr, ::HasShape) = similar(Array{T}, indices(itr)) @@ -354,7 +350,12 @@ function collect_to!{T}(dest::AbstractArray{T}, itr, offs, st) return dest end -function grow_to!(dest, itr, st = start(itr)) +function grow_to!(dest, itr) + out = grow_to!(similar(dest,Union{}), itr, start(itr)) + return isempty(out) ? dest : out +end + +function grow_to!(dest, itr, st) T = eltype(dest) while !done(itr, st) el, st = next(itr, st) diff --git a/base/dict.jl b/base/dict.jl index 8990bb198c1a2..2ea7e983b1c85 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -380,11 +380,18 @@ end dict_with_eltype{K,V}(kv, ::Type{Tuple{K,V}}) = Dict{K,V}(kv) dict_with_eltype{K,V}(kv, ::Type{Pair{K,V}}) = Dict{K,V}(kv) -dict_with_eltype(kv, t) = grow_to!(Dict{Union{},Union{}}(), kv) +dict_with_eltype{K,V}(::Type{Pair{K,V}}) = Dict{K,V}() +dict_with_eltype(::Type) = Dict() +dict_with_eltype(kv, t) = grow_to!(dict_with_eltype(_default_eltype(typeof(kv))), kv) # this is a special case due to (1) allowing both Pairs and Tuples as elements, # and (2) Pair being invariant. a bit annoying. -function grow_to!{K,V}(dest::Associative{K,V}, itr, st = start(itr)) +function grow_to!(dest::Associative, itr) + out = grow_to!(similar(dest, Pair{Union{},Union{}}), itr, start(itr)) + return isempty(out) ? dest : out +end + +function grow_to!{K,V}(dest::Associative{K,V}, itr, st) while !done(itr, st) (k,v), st = next(itr, st) if isa(k,K) && isa(v,V) diff --git a/base/set.jl b/base/set.jl index cafa9b66eeac1..804fffa8a4d3f 100644 --- a/base/set.jl +++ b/base/set.jl @@ -10,7 +10,7 @@ Set() = Set{Any}() Set(itr) = Set{eltype(itr)}(itr) function Set(g::Generator) T = _default_eltype(typeof(g)) - T === Union{} && return grow_to!(Set{T}(), g) + (isleaftype(T) || T === Union{}) || return grow_to!(Set{T}(), g) return Set{T}(g) end