You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Extend PartialStruct to represent non-contiguously defined fields (#57304)
So far, `PartialStruct` has been unable to represent non-contiguously
defined fields, where e.g. a struct would have fields 1 and 3 defined
but not field 2. This PR extends it so that such information may be
represented with `PartialStruct`, extending the applicability of
optimizations e.g. introduced in #55297 by @aviatesk or #57222.
The semantics of `new` prevent the creation of a struct with
non-contiguously defined fields, therefore this change is mostly
relevant to model mutable structs whose fields may be previously set or
assumed to be defined after creation, or immutable structs whose
creation is opaque.
Notably, with this change we may now infer information about structs in
the following case:
```julia
mutable struct A; x; y; z; A() = new(); end
function f()
mut = A()
# some opaque call preventing optimizations
# who knows, maybe `identity` will set fields from `mut` in a future world age!
invokelatest(identity, mut)
isdefined(mut, :z) && isdefined(mut, :x) || return
isdefined(mut, :x) & isdefined(mut, :z) # this now infers as `true`
isdefined(mut, :y) # this does not
end
```
whereas previously, only information gained successively with
`isdefined(mut, :x) && isdefined(mut, :y) && isdefined(mut, :z)` could
allow inference to model `mut` having its `z` field defined.
---------
Co-authored-by: Cédric Belmant <[email protected]>
Co-authored-by: Shuhei Kadowaki <[email protected]>
@assert!isa(typea, LimitedAccuracy) &&!isa(typeb, LimitedAccuracy) "LimitedAccuracy not supported by simplertype lattice"# n.b. the caller was supposed to handle these
333
389
typea === typeb &&returntrue
334
390
if typea isa PartialStruct
335
391
aty =widenconst(typea)
336
-
if typeb isa Const
337
-
@assertlength(typea.fields) ≤n_initialized(typeb) "typeb ⊑ typea is assumed"
392
+
if typeb isa Const|| typeb isa PartialStruct
393
+
@assertn_initialized(typea) ≤n_initialized(typeb) "typeb ⊑ typea is assumed"
338
394
elseif typeb isa PartialStruct
339
-
@assertlength(typea.fields) ≤length(typeb.fields) "typeb ⊑ typea is assumed"
0 commit comments