diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index 7bf1b70487087..4bfb5f3fcde56 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -1265,6 +1265,7 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse typ = unwrap_unionall(ir.stmts[newidx][:type]) # Could still end up here if we tried to setfield! on an immutable, which would # error at runtime, but is not illegal to have in the IR. + typ = widenconst(typ) ismutabletype(typ) || continue typ = typ::DataType # First check for any finalizer calls diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl index 43371b51f6a64..c704a8cf1c434 100644 --- a/test/compiler/irpasses.jl +++ b/test/compiler/irpasses.jl @@ -1230,3 +1230,18 @@ let src = code_typed1(named_tuple_elim, Tuple{Symbol, Tuple}) count(iscall((src, Core._svec_ref)), src.code) == 0 && count(iscall(x->!isa(argextype(x, src).val, Core.Builtin)), src.code) == 0 end + +# Test that sroa works if the struct type is a PartialStruct +mutable struct OneConstField + const a::Int + b::Int +end + +@eval function one_const_field_partial() + # Use explicit :new here to avoid inlining messing with the type + strct = $(Expr(:new, OneConstField, 1, 2)) + strct.b = 4 + strct.b = 5 + return strct.b +end +@test fully_eliminated(one_const_field_partial; retval=5)