@@ -2186,21 +2186,48 @@ end # @static if isdefined(Core, :ImmutableArray)
2186
2186
end
2187
2187
end
2188
2188
2189
- # # TODO implement a finalizer elision pass
2190
- # mutable struct WithFinalizer
2191
- # v
2192
- # function WithFinalizer(v)
2193
- # x = new(v)
2194
- # f(t) = @async println("Finalizing $t.")
2195
- # return finalizer(x, x)
2196
- # end
2197
- # end
2198
- # make_m(v = 10) = MyMutable(v)
2199
- # function simple(cond)
2200
- # m = make_m()
2201
- # if cond
2202
- # # println(m.v)
2203
- # return nothing # <= insert `finalize` call here
2204
- # end
2205
- # return m
2206
- # end
2189
+ mutable struct WithFinalizer
2190
+ v
2191
+ function WithFinalizer (v)
2192
+ x = new (v)
2193
+ f (t) = @async println (" Finalizing $t ." )
2194
+ return finalizer (f, x)
2195
+ end
2196
+ end
2197
+ function simple (cond)
2198
+ m = WithFinalizer (42 )
2199
+ if cond
2200
+ # Should have a `finalize` call
2201
+ return nothing
2202
+ end
2203
+ # Should not have a `finalize` call
2204
+ return m
2205
+ end
2206
+ @testset " early finalization" begin
2207
+ let result = code_escapes (simple, (Bool,))
2208
+ println (result)
2209
+ alloc_idx = SSAValue (2 )
2210
+ @test isnew (result. ir. stmts. inst[2 ])
2211
+ info = result. state[alloc_idx]
2212
+ dump (info)
2213
+ @test ! has_all_escape (info)
2214
+ @test has_return_escape (info)
2215
+ @test has_finalizer_escape (info)
2216
+
2217
+ rs = findall (isreturn, result. ir. stmts. inst)
2218
+ @test length (rs) == 2
2219
+ @test ! has_return_escape (info, rs[1 ])
2220
+ @test has_return_escape (info, rs[2 ])
2221
+ for r in rs
2222
+ @test isreturn (result. ir. stmts. inst[r])
2223
+ end
2224
+
2225
+ finalizer_idx = findfirst (isfinalizer, result. ir. stmts. inst)
2226
+ @test finalizer_idx != = nothing
2227
+
2228
+ finalize_idx = findfirst (isfinalize, result. ir. stmts. inst)
2229
+ @test finalize_idx != = nothing
2230
+ # FIXME : Test that there is a `finalize` call dominating `rs[1]`,
2231
+ # but not `rs[2]`
2232
+ end
2233
+ end
0 commit comments