From 29b509da2efb9fa499b567fd1d976532da5864fc Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Fri, 25 Oct 2024 13:18:31 +0900 Subject: [PATCH] inference: fix `[modifyfield!|replacefield!]_tfunc`s (#56310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the following code snippet results in an internal error: ```julia julia> func(x) = @atomic :monotonic x[].count += 1; julia> let;Base.Experimental.@force_compile x = Ref(nothing) func(x) end Internal error: during type inference of ... ``` This issue is caused by the incorrect use of `_fieldtype_tfunc(𝕃, o, f)` within `modifyfield!_tfunc`, specifically because `o` should be `widenconst`ed, but it isn’t. By using `_fieldtype_tfunc` correctly, we can avoid the error through error-catching in `abstract_modifyop!`. This commit also includes a similar fix for `replacefield!_tfunc` as well. --- base/compiler/tfuncs.jl | 6 ++++-- test/compiler/inference.jl | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 450cfdcfadf82..a74146dcff552 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -1347,13 +1347,15 @@ end return getfield_tfunc(𝕃, o, f) end @nospecs function modifyfield!_tfunc(𝕃::AbstractLattice, o, f, op, v, order=Symbol) - T = _fieldtype_tfunc(𝕃, o, f, isconcretetype(o)) + oβ€² = widenconst(o) + T = _fieldtype_tfunc(𝕃, oβ€², f, isconcretetype(oβ€²)) T === Bottom && return Bottom PT = Const(Pair) return instanceof_tfunc(apply_type_tfunc(𝕃, PT, T, T), true)[1] end @nospecs function replacefield!_tfunc(𝕃::AbstractLattice, o, f, x, v, success_order=Symbol, failure_order=Symbol) - T = _fieldtype_tfunc(𝕃, o, f, isconcretetype(o)) + oβ€² = widenconst(o) + T = _fieldtype_tfunc(𝕃, oβ€², f, isconcretetype(oβ€²)) T === Bottom && return Bottom PT = Const(ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T) return instanceof_tfunc(apply_type_tfunc(𝕃, PT, T), true)[1] diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index dd62e329962c6..dab8e57aa2309 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -6063,3 +6063,18 @@ end === Union{} @test Base.infer_return_type() do TypeVar(:Issue56248, Any, 1) end === Union{} + +@test Base.infer_return_type((Nothing,)) do x + @atomic x.count += 1 +end == Union{} +@test Base.infer_return_type((Nothing,)) do x + @atomicreplace x.count 0 => 1 +end == Union{} +mutable struct AtomicModifySafety + @atomic count::Int +end +let src = code_typed((Union{Nothing,AtomicModifySafety},)) do x + @atomic x.count += 1 + end |> only |> first + @test any(@nospecialize(x)->Meta.isexpr(x, :invoke_modify), src.code) +end