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