-
Notifications
You must be signed in to change notification settings - Fork 23
replace constructorof with something not UB #99
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
base: master
Are you sure you want to change the base?
Conversation
It is confusing that `constructorof` is documented as returning the constructor of `T`, which is normally defined to be `T`, and then typically does not return `T`, and so does not usually construct `T`. However, this PR is intended just to remove the undefined behavior here of using an unsound generated function (examining mutable state with getfield).
This didn't work out so well in the past: It would need to come with an assurance that its type stable and new julia versions wont break that. ( |
There is also UB at ConstructionBase.jl/src/functions.jl Line 11 in 72bb19d
|
#55 does not appear to have anything at all to do with this, except for pattern matching on the text "generated", as that touches a different function for different reasons @KristofferC that is good to know too. That one may be harder to make entirely safe, since it exists for the specific purpose of violating the safety of the compiler, but can perhaps have the same change made to it anyways |
#55 just has the "removing generated function lead to type instability and bug reports" problem. This generated function was also for performance at some stage - but that may have been driven by wanting to avoid @vtjnash it would just be good to have confirmation that |
getfield(parentmodule(T), nameof(T)) | ||
end | ||
|
||
constructorof(T::Type) = Base.typename(T).wrapper |
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.
constructorof(T::Type) = Base.typename(T).wrapper | |
constructorof(::Type{T}) where T = Base.typename(T).wrapper |
Is there a reason why the where T
was dropped as well?
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.
In practice, the where just reduces the information inference is permitted to use about the argument during inlining
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.
Ok, I guess I don't understand the scope of consequences of that.
From practical experience using where
on types and functions like this often fixes type stability bugs.
(The reason for my concern is a small loss of type stability in constructorof
could break the performance of 100s of packages)
Could you please rebase on master? CI was cleaned up there to avoid almost all spurious test failures. |
It appears that you have that ability disabled in settings |
It is confusing that
constructorof
is documented as returning the constructor ofT
, which is normally defined to beT
, and then typically does not returnT
, and so does not usually constructT
. However, this PR is intended just to remove the undefined behavior here of using an unsound generated function (examining mutable state with getfield).