589589
590590# simulate iteration protocol on container type up to fixpoint
591591function abstract_iteration (interp:: AbstractInterpreter , @nospecialize (itft), @nospecialize (itertype), sv:: InferenceState )
592- if ! isdefined (Main, :Base ) || ! isdefined (Main. Base, :iterate ) || ! isconst (Main. Base, :iterate )
593- return Any[Vararg{Any}], nothing
594- end
595- if itft === nothing
596- iteratef = getfield (Main. Base, :iterate )
597- itft = Const (iteratef)
598- elseif isa (itft, Const)
592+ if isa (itft, Const)
599593 iteratef = itft. val
600594 else
601595 return Any[Vararg{Any}], nothing
@@ -607,6 +601,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
607601 # Return Bottom if this is not an iterator.
608602 # WARNING: Changes to the iteration protocol must be reflected here,
609603 # this is not just an optimization.
604+ # TODO : this doesn't realize that Array, SimpleVector, Tuple, and NamedTuple do not use the iterate protocol
610605 stateordonet === Bottom && return Any[Bottom], AbstractIterationInfo (CallMeta[CallMeta (Bottom, info)])
611606 valtype = statetype = Bottom
612607 ret = Any[]
@@ -670,7 +665,7 @@ function abstract_apply(interp::AbstractInterpreter, @nospecialize(itft), @nospe
670665 aftw = widenconst (aft)
671666 if ! isa (aft, Const) && (! isType (aftw) || has_free_typevars (aftw))
672667 if ! isconcretetype (aftw) || (aftw <: Builtin )
673- add_remark! (interp, sv, " Core._apply called on a function of a non-concrete type" )
668+ add_remark! (interp, sv, " Core._apply_iterate called on a function of a non-concrete type" )
674669 # bail now, since it seems unlikely that abstract_call will be able to do any better after splitting
675670 # this also ensures we don't call abstract_call_gf_by_type below on an IntrinsicFunction or Builtin
676671 return CallMeta (Any, false )
@@ -830,7 +825,8 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, fargs::U
830825 end
831826 rt = builtin_tfunction (interp, f, argtypes[2 : end ], sv)
832827 if f === getfield && isa (fargs, Vector{Any}) && la == 3 && isa (argtypes[3 ], Const) && isa (argtypes[3 ]. val, Int) && argtypes[2 ] ⊑ Tuple
833- cti, _ = precise_container_type (interp, nothing , argtypes[2 ], sv)
828+ # TODO : why doesn't this use the getfield_tfunc?
829+ cti, _ = precise_container_type (interp, iterate, argtypes[2 ], sv)
834830 idx = argtypes[3 ]. val:: Int
835831 if 1 <= idx <= length (cti)
836832 rt = unwrapva (cti[idx])
@@ -949,11 +945,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
949945 la = length (argtypes)
950946
951947 if isa (f, Builtin)
952- if f === _apply
953- ft = argtype_by_index (argtypes, 2 )
954- ft === Bottom && return CallMeta (Bottom, false )
955- return abstract_apply (interp, nothing , ft, argtype_tail (argtypes, 3 ), sv, max_methods)
956- elseif f === _apply_iterate
948+ if f === _apply_iterate
957949 itft = argtype_by_index (argtypes, 2 )
958950 ft = argtype_by_index (argtypes, 3 )
959951 (itft === Bottom || ft === Bottom) && return CallMeta (Bottom, false )
0 commit comments