Skip to content

Commit eda5672

Browse files
committed
inference: refine setglobal! rt for invalid assignments
1 parent 0ded536 commit eda5672

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

Compiler/src/abstractinterpretation.jl

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2419,8 +2419,8 @@ function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState,
24192419
if isa(M, Const) && isa(s, Const)
24202420
M, s = M.val, s.val
24212421
if M isa Module && s isa Symbol
2422-
exct = global_assignment_exct(interp, sv, saw_latestworld, GlobalRef(M, s), v)
2423-
return CallMeta(v, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), NoCallInfo())
2422+
rt, exct = global_assignment_rt_exct(interp, sv, saw_latestworld, GlobalRef(M, s), v)
2423+
return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), NoCallInfo())
24242424
end
24252425
return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo())
24262426
end
@@ -2485,7 +2485,7 @@ function abstract_eval_replaceglobal!(interp::AbstractInterpreter, sv::AbsIntSta
24852485
if binding_kind(partition) == BINDING_KIND_GLOBAL
24862486
T = partition_restriction(partition)
24872487
end
2488-
exct = Union{rte.exct, global_assignment_binding_exct(partition, v)}
2488+
exct = Union{rte.exct, global_assignment_binding_rt_exct(interp, partition, v)[2]}
24892489
effects = merge_effects(rte.effects, Effects(setglobal!_effects, nothrow=exct===Bottom))
24902490
sg = CallMeta(Any, exct, effects, NoCallInfo())
24912491
else
@@ -3401,31 +3401,35 @@ function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, saw_
34013401
return ret
34023402
end
34033403

3404-
function global_assignment_exct(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, g::GlobalRef, @nospecialize(newty))
3404+
function global_assignment_rt_exct(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, g::GlobalRef, @nospecialize(newty))
34053405
if saw_latestworld
3406-
return Union{ErrorException, TypeError}
3406+
return Pair{Any,Any}(newty, Union{ErrorException, TypeError})
34073407
end
34083408
partition = abstract_eval_binding_partition!(interp, g, sv)
3409-
return global_assignment_binding_exct(partition, newty)
3409+
return global_assignment_binding_rt_exct(interp, partition, newty)
34103410
end
34113411

3412-
function global_assignment_binding_exct(partition::Core.BindingPartition, @nospecialize(newty))
3412+
function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partition::Core.BindingPartition, @nospecialize(newty))
34133413
kind = binding_kind(partition)
3414-
if is_some_guard(kind) || is_some_const_binding(kind)
3415-
return ErrorException
3414+
if is_some_guard(kind)
3415+
return Pair{Any,Any}(newty, ErrorException)
3416+
elseif is_some_const_binding(kind)
3417+
return Pair{Any,Any}(Bottom, ErrorException)
34163418
end
3417-
34183419
ty = partition_restriction(partition)
3419-
if !(widenconst(newty) <: ty)
3420-
return TypeError
3420+
wnewty = widenconst(newty)
3421+
if !hasintersect(wnewty, ty)
3422+
return Pair{Any,Any}(Bottom, TypeError)
3423+
elseif !(wnewty <: ty)
3424+
retty = tmeet(typeinf_lattice(interp), newty, ty)
3425+
return Pair{Any,Any}(retty, TypeError)
34213426
end
3422-
3423-
return Union{}
3427+
return Pair{Any,Any}(newty, Bottom)
34243428
end
34253429

34263430
function handle_global_assignment!(interp::AbstractInterpreter, frame::InferenceState, saw_latestworld::Bool, lhs::GlobalRef, @nospecialize(newty))
34273431
effect_free = ALWAYS_FALSE
3428-
nothrow = global_assignment_exct(interp, frame, saw_latestworld, lhs, ignorelimited(newty)) === Union{}
3432+
nothrow = global_assignment_rt_exct(interp, frame, saw_latestworld, lhs, ignorelimited(newty))[2] === Union{}
34293433
inaccessiblememonly = ALWAYS_FALSE
34303434
if !nothrow
34313435
sub_curr_ssaflag!(frame, IR_FLAG_NOTHROW)

Compiler/test/inference.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6088,3 +6088,12 @@ function issue56387(nt::NamedTuple, field::Symbol=:a)
60886088
types[index]
60896089
end
60906090
@test Base.infer_return_type(issue56387, (typeof((;a=1)),)) == Type{Int}
6091+
6092+
global setglobal!_refine::Int
6093+
@test Base.infer_return_type((Integer,)) do x
6094+
setglobal!(@__MODULE__, :setglobal!_refine, x)
6095+
end === Int
6096+
global setglobal!_must_throw::Int = 42
6097+
@test Base.infer_return_type((String,)) do x
6098+
setglobal!(@__MODULE__, :setglobal!_must_throw, x)
6099+
end === Union{}

0 commit comments

Comments
 (0)