@@ -583,23 +583,38 @@ julia> collect(Float64, 1:2:5)
583583"""
584584collect (:: Type{T} , itr) where {T} = _collect (T, itr, IteratorSize (itr))
585585
586- _collect (:: Type{T} , itr, isz:: HasLength ) where {T} = copyto! ( Vector {T} (undef, Int ( length (itr) :: Integer )), itr)
587- _collect ( :: Type{T} , itr, isz :: HasShape ) where {T} = copyto! (similar (Array{T}, axes (itr)), itr)
586+ _collect (:: Type{T} , itr, isz:: Union{ HasLength,HasShape} ) where {T} =
587+ copyto! (_array_for (T, isz, _similar_shape (itr, isz )), itr)
588588function _collect (:: Type{T} , itr, isz:: SizeUnknown ) where T
589589 a = Vector {T} ()
590590 for x in itr
591- push! (a,x)
591+ push! (a, x)
592592 end
593593 return a
594594end
595595
596596# make a collection similar to `c` and appropriate for collecting `itr`
597- _similar_for (c:: AbstractArray , :: Type{T} , itr, :: SizeUnknown ) where {T} = similar (c, T, 0 )
598- _similar_for (c:: AbstractArray , :: Type{T} , itr, :: HasLength ) where {T} =
599- similar (c, T, Int (length (itr):: Integer ))
600- _similar_for (c:: AbstractArray , :: Type{T} , itr, :: HasShape ) where {T} =
601- similar (c, T, axes (itr))
602- _similar_for (c, :: Type{T} , itr, isz) where {T} = similar (c, T)
597+ _similar_for (c, :: Type{T} , itr, isz, shp) where {T} = similar (c, T)
598+
599+ _similar_shape (itr, :: SizeUnknown ) = nothing
600+ _similar_shape (itr, :: HasLength ) = length (itr):: Integer
601+ _similar_shape (itr, :: HasShape ) = axes (itr)
602+
603+ _similar_for (c:: AbstractArray , :: Type{T} , itr, :: SizeUnknown , :: Nothing ) where {T} =
604+ similar (c, T, 0 )
605+ _similar_for (c:: AbstractArray , :: Type{T} , itr, :: HasLength , len:: Integer ) where {T} =
606+ similar (c, T, len)
607+ _similar_for (c:: AbstractArray , :: Type{T} , itr, :: HasShape , axs) where {T} =
608+ similar (c, T, axs)
609+
610+ # make a collection appropriate for collecting `itr::Generator`
611+ _array_for (:: Type{T} , :: SizeUnknown , :: Nothing ) where {T} = Vector {T} (undef, 0 )
612+ _array_for (:: Type{T} , :: HasLength , len:: Integer ) where {T} = Vector {T} (undef, Int (len))
613+ _array_for (:: Type{T} , :: HasShape{N} , axs) where {T,N} = similar (Array{T,N}, axs)
614+
615+ # used by syntax lowering for simple typed comprehensions
616+ _array_for (:: Type{T} , itr, isz) where {T} = _array_for (T, isz, _similar_shape (itr, isz))
617+
603618
604619"""
605620 collect(collection)
@@ -638,10 +653,10 @@ collect(A::AbstractArray) = _collect_indices(axes(A), A)
638653collect_similar (cont, itr) = _collect (cont, itr, IteratorEltype (itr), IteratorSize (itr))
639654
640655_collect (cont, itr, :: HasEltype , isz:: Union{HasLength,HasShape} ) =
641- copyto! (_similar_for (cont, eltype (itr), itr, isz), itr)
656+ copyto! (_similar_for (cont, eltype (itr), itr, isz, _similar_shape (itr, isz) ), itr)
642657
643658function _collect (cont, itr, :: HasEltype , isz:: SizeUnknown )
644- a = _similar_for (cont, eltype (itr), itr, isz)
659+ a = _similar_for (cont, eltype (itr), itr, isz, nothing )
645660 for x in itr
646661 push! (a,x)
647662 end
@@ -699,24 +714,19 @@ else
699714 end
700715end
701716
702- _array_for (:: Type{T} , itr, isz:: HasLength ) where {T} = _array_for (T, itr, isz, length (itr))
703- _array_for (:: Type{T} , itr, isz:: HasShape{N} ) where {T,N} = _array_for (T, itr, isz, axes (itr))
704- _array_for (:: Type{T} , itr, :: HasLength , len) where {T} = Vector {T} (undef, len)
705- _array_for (:: Type{T} , itr, :: HasShape{N} , axs) where {T,N} = similar (Array{T,N}, axs)
706-
707717function collect (itr:: Generator )
708718 isz = IteratorSize (itr. iter)
709719 et = @default_eltype (itr)
710720 if isa (isz, SizeUnknown)
711721 return grow_to! (Vector {et} (), itr)
712722 else
713- shape = isz isa HasLength ? length (itr) : axes (itr )
723+ shp = _similar_shape (itr, isz )
714724 y = iterate (itr)
715725 if y === nothing
716- return _array_for (et, itr . iter, isz )
726+ return _array_for (et, isz, shp )
717727 end
718728 v1, st = y
719- dest = _array_for (typeof (v1), itr . iter, isz, shape )
729+ dest = _array_for (typeof (v1), isz, shp )
720730 # The typeassert gives inference a helping hand on the element type and dimensionality
721731 # (work-around for #28382)
722732 et′ = et <: Type ? Type : et
@@ -726,15 +736,22 @@ function collect(itr::Generator)
726736end
727737
728738_collect (c, itr, :: EltypeUnknown , isz:: SizeUnknown ) =
729- grow_to! (_similar_for (c, @default_eltype (itr), itr, isz), itr)
739+ grow_to! (_similar_for (c, @default_eltype (itr), itr, isz, nothing ), itr)
730740
731741function _collect (c, itr, :: EltypeUnknown , isz:: Union{HasLength,HasShape} )
742+ et = @default_eltype (itr)
743+ shp = _similar_shape (itr, isz)
732744 y = iterate (itr)
733745 if y === nothing
734- return _similar_for (c, @default_eltype (itr) , itr, isz)
746+ return _similar_for (c, et , itr, isz, shp )
735747 end
736748 v1, st = y
737- collect_to_with_first! (_similar_for (c, typeof (v1), itr, isz), v1, itr, st)
749+ dest = _similar_for (c, typeof (v1), itr, isz, shp)
750+ # The typeassert gives inference a helping hand on the element type and dimensionality
751+ # (work-around for #28382)
752+ et′ = et <: Type ? Type : et
753+ RT = dest isa AbstractArray ? AbstractArray{<: et′ , ndims (dest)} : Any
754+ collect_to_with_first! (dest, v1, itr, st):: RT
738755end
739756
740757function collect_to_with_first! (dest:: AbstractArray , v1, itr, st)
0 commit comments