577577
578578# simulate iteration protocol on container type up to fixpoint
579579function abstract_iteration (interp:: AbstractInterpreter , @nospecialize (itft), @nospecialize (itertype), sv:: InferenceState )
580- if ! isdefined (Main, :Base ) || ! isdefined (Main. Base, :iterate ) || ! isconst (Main. Base, :iterate )
581- return Any[Vararg{Any}], nothing
582- end
583- if itft === nothing
584- iteratef = getfield (Main. Base, :iterate )
585- itft = Const (iteratef)
586- elseif isa (itft, Const)
580+ if isa (itft, Const)
587581 iteratef = itft. val
588582 else
589583 return Any[Vararg{Any}], nothing
@@ -595,6 +589,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
595589 # Return Bottom if this is not an iterator.
596590 # WARNING: Changes to the iteration protocol must be reflected here,
597591 # this is not just an optimization.
592+ # TODO : this doesn't realize that Array, SimpleVector, Tuple, and NamedTuple do not use the iterate protocol
598593 stateordonet === Bottom && return Any[Bottom], AbstractIterationInfo (CallMeta[CallMeta (Bottom, info)])
599594 valtype = statetype = Bottom
600595 ret = Any[]
@@ -658,7 +653,7 @@ function abstract_apply(interp::AbstractInterpreter, @nospecialize(itft), @nospe
658653 aftw = widenconst (aft)
659654 if ! isa (aft, Const) && (! isType (aftw) || has_free_typevars (aftw))
660655 if ! isconcretetype (aftw) || (aftw <: Builtin )
661- add_remark! (interp, sv, " Core._apply called on a function of a non-concrete type" )
656+ add_remark! (interp, sv, " Core._apply_iterate called on a function of a non-concrete type" )
662657 # bail now, since it seems unlikely that abstract_call will be able to do any better after splitting
663658 # this also ensures we don't call abstract_call_gf_by_type below on an IntrinsicFunction or Builtin
664659 return CallMeta (Any, false )
@@ -805,7 +800,8 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, fargs::U
805800 end
806801 rt = builtin_tfunction (interp, f, argtypes[2 : end ], sv)
807802 if f === getfield && isa (fargs, Vector{Any}) && la == 3 && isa (argtypes[3 ], Const) && isa (argtypes[3 ]. val, Int) && argtypes[2 ] ⊑ Tuple
808- cti, _ = precise_container_type (interp, nothing , argtypes[2 ], sv)
803+ # TODO : why doesn't this use the getfield_tfunc?
804+ cti, _ = precise_container_type (interp, iterate, argtypes[2 ], sv)
809805 idx = argtypes[3 ]. val
810806 if 1 <= idx <= length (cti)
811807 rt = unwrapva (cti[idx])
@@ -923,11 +919,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
923919 la = length (argtypes)
924920
925921 if isa (f, Builtin)
926- if f === _apply
927- ft = argtype_by_index (argtypes, 2 )
928- ft === Bottom && return CallMeta (Bottom, false )
929- return abstract_apply (interp, nothing , ft, argtype_tail (argtypes, 3 ), sv, max_methods)
930- elseif f === _apply_iterate
922+ if f === _apply_iterate
931923 itft = argtype_by_index (argtypes, 2 )
932924 ft = argtype_by_index (argtypes, 3 )
933925 (itft === Bottom || ft === Bottom) && return CallMeta (Bottom, false )
0 commit comments