@@ -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