-
-
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
inference: improve TypeVar
/Vararg
handling
#42583
Conversation
2c6d5b5
to
a7a21c6
Compare
d058fe6
to
777b4b0
Compare
widenconst
always return Type
TypeVar
and Vararg
874dd2d
to
d850968
Compare
With some early-take of #42583.
With some early-take of #42583.
9a3825c
to
c80f8a2
Compare
With some early-take of #42583.
Alright, so I think this is good to go ? |
c80f8a2
to
d14503a
Compare
yeah, just keep an eye on the next nightly pkgeval |
Or run PkgEval first? |
@nanosoldier |
After <JuliaLang/julia#42583> is merged, `widenconst` doesn't accept non-valid Julia types (i.e. `TypeVar`/`Vararg`), and we will handle them explicitly.
test/compiler/inference.jl
Outdated
Type{Bound}, # DataType => Type{Bound} where Bound<:Integer | ||
Type{unbound}, # DataType => Type | ||
Vector{Some{Bound}}, # DataType => Vector{Some{Bound}} where Bound<:Integer | ||
Vector{Some{unbound}}, # DataType => Array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You really went overboard here! Most of these cannot happen at runtime, since this would not declare a valid object (for example). Only wrap_Type (Type{T}) can contain an invalid parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So conceptually we want to replace invalid non-Type
s with Bottom
? It feels a bit weird to keep inference going when we know something never happens at runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it just shouldn't occur, so it is a lot of code and tests to handle a situation that can only be user-constructed as arguments to code_typed
. Conceptually it only happens in the runtime for Type{T}::DataType
, so the replacement could be just:
has_free_typevars(t) ? (isType(t) ? Type : Any) : t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I got it.
Since I saw some unbound TypeVar
s during sysimg creation, I thought inference sometimes seemed to forward unbound TypeVar
s, but it shouldn't and so it might also be bad entry arguments given at somewhere (maybe return_type
?).
Anyway, I believe this PR is solid now so I'm going to merge this once CI gets passed.
Your package evaluation job has completed - possible new issues were detected. A full report can be found here. |
During working on the incoming lattice overhaul, I found it's quite confusing that `TypeVar` and `Vararg` can appear in the same context as valid `Type` objects as well as extended lattice elements. Since it usually needs special cases to operate on `TypeVar` and `Vararg` (e.g. they can not be used in subtyping as an obvious example), I believe it would be great avoid bugs and catch logic errors in the future development if we separate contexts where they can appear from ones where `Type` objects and extended lattice elements are expected. So this commit: - tries to separate their context, e.g. now `TypeVar` and `Vararg` should not be used in `_limit_type_size`, which is supposed to return `Type`, but they should be handled its helper function `__limit_type_size` - makes sure `tfunc`s don't return `TypeVar`s and `TypeVar` never spills into the abstract state - makes sure `widenconst` are not called on `TypeVar` and `Vararg`, and now `widenconst` is ensured to return `Type` always - and does other general refactors
a62c695
to
dd036ef
Compare
This commit eliminates unbound `TypeVar`s from `argtypes` in order to make the analysis much easier down the road. At runtime, only `Type{...}::DataType` can contain invalid type parameters, but we may have arbitrary malformed user-constructed type arguments given at inference entries. So we will replace only the malformed `Type{...}::DataType` with `Type` and simply replace other possibilities with `Any`. The replacement might not be that accurate, but an unbound `TypeVar` is really invalid in anyway. Like the change added on `arrayref_tfunc`, now we may be able to remove some `isa(x, TypeVar)`/`has_free_typevars` predicates used in various places, but it is left as an exercise for the reader.
dd036ef
to
36cc1c1
Compare
Follows #42583. The missing case within `const_prop_function_heuristic` was originally reported from RationalAI's test suite. I added the other two cases by some code review.
Follows #42583. The missing case within `const_prop_function_heuristic` was originally reported from RationalAI's test suite. I added the other two cases by some code review.
JuliaLang#42971) Follows JuliaLang#42583. The missing case within `const_prop_function_heuristic` was originally reported from RerationalAI's test suite. I added the other two cases by some code review.
JuliaLang#42971) Follows JuliaLang#42583. The missing case within `const_prop_function_heuristic` was originally reported from RerationalAI's test suite. I added the other two cases by some code review.
… computed by `abstract_apply` (#51393) This commit adds special handling for `Vararg` types that may appear at the end of `argtypes`, as computed by `abstract_apply`. Even though PR #42583 has ensured that `Vararg` and `TypeVar` should never appear within the abstract state, they can still be part of `argtypes`. As a result, this kind of special handling is still necessary. It remains an open question whether we can refactor `abstract_apply` to prevent `Vararg`s from appearing in `argtypes` in the first place.
During working on the incoming lattice overhaul, I found it's quite
confusing that
TypeVar
andVararg
can appear in the same contextas valid
Type
objects as well as extended lattice elements.Since it usually needs special cases to operate on
TypeVar
andVararg
(e.g. they can not be used in subtyping), I believe it would be helpful
to avoid bugs and catch logic errors in the future development if we
separate contexts where they can appear from ones where
Type
objects and extended lattice elements are expected.
So this PR:
TypeVar
andVararg
shouldnot be used in
_limit_type_size
, which is supposed to returnType
,but they should be handled by its helper function
__limit_type_size
tfunc
s don't returnTypeVar
s andTypeVar
never spillsinto the abstract state
widenconst
are not called onTypeVar
andVararg
,and now
widenconst
is ensured to returnType
always