-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
effects: improve effects analysis for Type
-objects
#46328
base: master
Are you sure you want to change the base?
Conversation
Almost, but not quite:
Don't know whether that is to worry about in practice, but it allows to produce the following inconsistency on this branch: julia> f(::Type{T} where T) = Val{T.flags}
f (generic function with 1 method)
julia> struct T; x::f(T); end
julia> f(T)
Val{0x62}
julia> @code_typed f(T)
CodeInfo(
1 ─ return Val{0x6a}
) => Type{Val{0x6a}} Can we restrict treating types as immutable to cases where a) we know not only it is a type, but which type and b) that type is fully constructed? Additionally, we'd want the result for a type that is still under construction not to be cached, as a future analysis might be less pessimistic. Can we do that? |
a1a6e2b
to
a26e76f
Compare
If we decide correctness is edge cases like those is sufficiently important to to be more conservative about treating types as immutable, we could use the opportunity to also fix this case which we already have on master: julia> f(::Type{T}) where T = isdefined(T, :instance)
f (generic function with 1 method)
julia> struct T; x::Val{f(T)}; end
julia> f(T)
false
julia> @code_typed f(T)
CodeInfo(
1 ─ return true
) => Bool |
It is UB right now to call a function (in this case |
1 similar comment
It is UB right now to call a function (in this case |
But as you note there, types have both #undef fields and non-constant fields (esp. |
There's also julia> struct Foo <: (println(isdefined(Foo, :super)); Any) end
false
julia> isdefined(Foo, :super)
true But AFAICT, all of these are set once during type construction and they don't change anymore.
But then this PR is valid as is? Or is a type actually changed somehow after its declaration is complete? |
AFAIK currently, the PR assumption is not valid (#46328 (comment)), so currently we have specific lists of fields that are valid for these effects. |
a26e76f
to
7e48407
Compare
`Type`-object never has "undef" field and we should prove `getfield` access to `Type`-object is `:consistent`.
7e48407
to
6683109
Compare
Do you have an example where undef-ness or mutability is observable which is not already UB? |
Sorry I just mistakenly pushed unrelated changes into this branch and fixed it up. I will follow the discussion later. |
This PR is composed of the following two changes:
Type
-object are immutable (essentially on Julia-level) and never has "undef" field,and so we should prove
getfield
access toType
-object is:consistent
.This is particularly useful as it allows us to inline
Ref.body.name
and such.