@@ -2637,21 +2637,14 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
26372637 elseif f === Core. getfield && argtypes_are_actually_getglobal (argtypes)
26382638 return Future (abstract_eval_getglobal (interp, sv, si. saw_latestworld, argtypes))
26392639 elseif f === Core. isdefined && argtypes_are_actually_getglobal (argtypes)
2640- exct = Bottom
2641- if length (argtypes) == 4
2642- order = argtypes[4 ]
2643- exct = global_order_exct (order, #= loading=# true , #= storing=# false )
2644- if ! (isa (order, Const) && get_atomic_order (order. val, #= loading=# true , #= storing=# false ). x >= MEMORY_ORDER_UNORDERED. x)
2645- exct = Union{exct, ConcurrencyViolationError}
2646- end
2647- end
2648- return Future (merge_exct (CallMeta (abstract_eval_isdefined (
2649- interp,
2650- GlobalRef ((argtypes[2 ]:: Const ). val:: Module ,
2651- (argtypes[3 ]:: Const ). val:: Symbol ),
2652- si. saw_latestworld,
2653- sv),
2654- NoCallInfo ()), exct))
2640+ return Future (abstract_eval_isdefinedglobal (interp, argtypes[2 ], argtypes[3 ], Const (true ),
2641+ length (argtypes) == 4 ? argtypes[4 ] : Const (:unordered ),
2642+ si. saw_latestworld, sv))
2643+ elseif f === Core. isdefinedglobal && 3 <= length (argtypes) <= 5
2644+ return Future (abstract_eval_isdefinedglobal (interp, argtypes[2 ], argtypes[3 ],
2645+ length (argtypes) >= 4 ? argtypes[4 ] : Const (true ),
2646+ length (argtypes) >= 5 ? argtypes[5 ] : Const (:unordered ),
2647+ si. saw_latestworld, sv))
26552648 elseif f === Core. get_binding_type
26562649 return Future (abstract_eval_get_binding_type (interp, sv, argtypes))
26572650 end
@@ -3203,21 +3196,73 @@ function abstract_eval_isdefined_expr(interp::AbstractInterpreter, e::Expr, ssta
32033196 return abstract_eval_isdefined (interp, sym, sstate. saw_latestworld, sv)
32043197end
32053198
3206- function abstract_eval_isdefined (interp:: AbstractInterpreter , @nospecialize (sym), saw_latestworld:: Bool , sv:: AbsIntState )
3199+ const generic_isdefinedglobal_effects = Effects (EFFECTS_TOTAL, consistent= ALWAYS_FALSE, nothrow= false )
3200+ function abstract_eval_isdefinedglobal (interp:: AbstractInterpreter , mod:: Module , sym:: Symbol , allow_import:: Union{Bool, Nothing} , saw_latestworld:: Bool , sv:: AbsIntState )
32073201 rt = Bool
3202+ if saw_latestworld
3203+ return RTEffects (rt, Union{}, Effects (generic_isdefinedglobal_effects, nothrow= true ))
3204+ end
3205+
32083206 effects = EFFECTS_TOTAL
3209- exct = Union{}
3210- isa (sym, Symbol) && (sym = GlobalRef (frame_module (sv), sym))
3211- if isa (sym, GlobalRef)
3212- rte = abstract_eval_globalref (interp, sym, saw_latestworld, sv)
3207+ partition = lookup_binding_partition! (interp, GlobalRef (mod, sym), sv)
3208+ if allow_import != = true && is_some_imported (binding_kind (partition))
3209+ if allow_import === false
3210+ rt = Const (false )
3211+ else
3212+ effects = Effects (generic_isdefinedglobal_effects, nothrow= true )
3213+ end
3214+ else
3215+ partition = walk_binding_partition! (interp, partition, sv)
3216+ rte = abstract_eval_partition_load (interp, partition)
32133217 if rte. exct == Union{}
32143218 rt = Const (true )
32153219 elseif rte. rt === Union{} && rte. exct === UndefVarError
32163220 rt = Const (false )
32173221 else
3218- effects = Effects (EFFECTS_TOTAL; consistent= ALWAYS_FALSE)
3222+ effects = Effects (generic_isdefinedglobal_effects, nothrow= true )
3223+ end
3224+ end
3225+ return RTEffects (rt, Union{}, effects)
3226+ end
3227+
3228+ function abstract_eval_isdefinedglobal (interp:: AbstractInterpreter , @nospecialize (M), @nospecialize (s), @nospecialize (allow_import_arg), @nospecialize (order_arg), saw_latestworld:: Bool , sv:: AbsIntState )
3229+ exct = Bottom
3230+ allow_import = true
3231+ if allow_import_arg != = nothing
3232+ if ! isa (allow_import_arg, Const)
3233+ allow_import = nothing
3234+ if widenconst (allow_import_arg) != Bool
3235+ exct = Union{exct, TypeError}
3236+ end
3237+ else
3238+ allow_import = allow_import_arg. val
3239+ end
3240+ end
3241+ if order_arg != = nothing
3242+ exct = global_order_exct (order_arg, #= loading=# true , #= storing=# false )
3243+ if ! (isa (order_arg, Const) && get_atomic_order (order_arg. val, #= loading=# true , #= storing=# false ). x >= MEMORY_ORDER_UNORDERED. x)
3244+ exct = Union{exct, ConcurrencyViolationError}
3245+ end
3246+ end
3247+ if M isa Const && s isa Const
3248+ M, s = M. val, s. val
3249+ if M isa Module && s isa Symbol
3250+ return merge_exct (CallMeta (abstract_eval_isdefinedglobal (interp, M, s, allow_import, saw_latestworld, sv), NoCallInfo ()), exct)
32193251 end
3220- elseif isexpr (sym, :static_parameter )
3252+ return CallMeta (Union{}, TypeError, EFFECTS_THROWS, NoCallInfo ())
3253+ elseif ! hasintersect (widenconst (M), Module) || ! hasintersect (widenconst (s), Symbol)
3254+ return CallMeta (Union{}, TypeError, EFFECTS_THROWS, NoCallInfo ())
3255+ elseif M ⊑ Module && s ⊑ Symbol
3256+ return CallMeta (Bool, Union{exct, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo ())
3257+ end
3258+ return CallMeta (Bool, Union{exct, TypeError, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo ())
3259+ end
3260+
3261+ function abstract_eval_isdefined (interp:: AbstractInterpreter , @nospecialize (sym), saw_latestworld:: Bool , sv:: AbsIntState )
3262+ rt = Bool
3263+ effects = EFFECTS_TOTAL
3264+ exct = Union{}
3265+ if isexpr (sym, :static_parameter )
32213266 n = sym. args[1 ]:: Int
32223267 if 1 <= n <= length (sv. sptypes)
32233268 sp = sv. sptypes[n]
@@ -3443,22 +3488,31 @@ function abstract_eval_globalref_type(g::GlobalRef, src::Union{CodeInfo, IRCode,
34433488 return partition_restriction (partition)
34443489end
34453490
3446- function abstract_eval_binding_partition ! (interp:: AbstractInterpreter , g:: GlobalRef , sv:: AbsIntState )
3491+ function lookup_binding_partition ! (interp:: AbstractInterpreter , g:: GlobalRef , sv:: AbsIntState )
34473492 force_binding_resolution! (g)
34483493 partition = lookup_binding_partition (get_inference_world (interp), g)
34493494 update_valid_age! (sv, WorldRange (partition. min_world, partition. max_world))
3495+ partition
3496+ end
34503497
3498+ function walk_binding_partition! (interp:: AbstractInterpreter , partition:: Core.BindingPartition , sv:: AbsIntState )
34513499 while is_some_imported (binding_kind (partition))
34523500 imported_binding = partition_restriction (partition):: Core.Binding
34533501 partition = lookup_binding_partition (get_inference_world (interp), imported_binding)
34543502 update_valid_age! (sv, WorldRange (partition. min_world, partition. max_world))
34553503 end
3504+ return partition
3505+ end
34563506
3507+ function abstract_eval_binding_partition! (interp:: AbstractInterpreter , g:: GlobalRef , sv:: AbsIntState )
3508+ partition = lookup_binding_partition! (interp, g, sv)
3509+ partition = walk_binding_partition! (interp, partition, sv)
34573510 return partition
34583511end
34593512
34603513function abstract_eval_partition_load (interp:: AbstractInterpreter , partition:: Core.BindingPartition )
3461- if is_some_guard (binding_kind (partition))
3514+ kind = binding_kind (partition)
3515+ if is_some_guard (kind) || kind == BINDING_KIND_UNDEF_CONST
34623516 if InferenceParams (interp). assume_bindings_static
34633517 return RTEffects (Union{}, UndefVarError, EFFECTS_THROWS)
34643518 else
@@ -3468,13 +3522,12 @@ function abstract_eval_partition_load(interp::AbstractInterpreter, partition::Co
34683522 end
34693523 end
34703524
3471- if is_some_const_binding ( binding_kind (partition) )
3525+ if is_defined_const_binding (kind )
34723526 rt = Const (partition_restriction (partition))
34733527 return RTEffects (rt, Union{}, Effects (EFFECTS_TOTAL, inaccessiblememonly= is_mutation_free_argtype (rt) ? ALWAYS_TRUE : ALWAYS_FALSE))
34743528 end
34753529
34763530 rt = partition_restriction (partition)
3477-
34783531 return RTEffects (rt, UndefVarError, generic_getglobal_effects)
34793532end
34803533
0 commit comments