-
-
Notifications
You must be signed in to change notification settings - Fork 128
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
Acceptable costs for the removal of unsafe code? #648
Comments
For example 1: Can you point to where this would allow the removal of unsafe code? It's unclear to me. For example 2: The whole point of In general, while I try to avoid unsafe code, I'm not against using it when it's useful. I don't really see the need to pull in dependencies just to eliminate some uses of it. Having absolutely no uses of |
First of all, I agree that it probably doesn't make sense to eliminate all uses of unsafe. My interest is more in reducing the number to make the remaining unsafe code easier to audit. For example 1:
Again, I think these are sound (as long as num_complex doesn't change), so the sole purpose is just to eliminate the keyword. bytemuck is already used by several libraries Uiua uses, so it kind of is and kind of isn't already a dependency of Uiua. When you say you don't want to take on a dependency, do you mean that you don't want to add previously unvetted code to the supply chain? or do you mean you don't want to think about more APIs? or something else? For example 2: In terms of code semantics, the change I described does add an extra switch statement. This is indeed present in the llvm-ir for debug mode. However, in release mode the compiler sees that all branches result in the same instructions, and optimize out the branching. I'd expect this to be stable across compiler versions since it doesn't rely on inlining triggering, and the number of instructions involved is quite small. So I would expect it to have some small impact in debug mode, and none in release mode. This is why I was asking how important debug mode performance is. |
If you find some good uses of bytemuck, I'd likely accept a PR. |
I would like to remove instances of unsafe in the code-base that aren't essential for performance or functionality. As per the contributor guidelines, this isn't a bug fix, so I'd like to ask what sort of changes would be acceptable in a PR before I do too much work. I've already done a bit just to see if it is even worthwhile, so I have some idea of what I might ask for:
Examples of changes I've tried or want to try:
mem::transmute
. This requires no structural changes to the code.value::Value
to avalue::Repr
which is currently done inValue::shape
,Value::meta_mut
, and several similar functions. I can do this by moving the logic for the management ofarray::Array.meta
into a wrapper objectArrayMetaHolder
(to monomorphize the meta pointer management code), and then usingval_as_array!(self, |arr| &mut arr.meta).meta_mut()
and friends to get the shape and metadata from the array inside the value. I've checked the llvm-ir emitted by the rust compiler in release mode for several of the functions which inlineValue::meta_mut
and friends. I can confirm that in release mode the compiler realizes that checking the discriminant ofValue
is unnecessary and unconditionally offsets theValue
pointer to the location of theshape
ormeta
fields, which I assume was the point of castingValue
toRepr
in the first place. However, in debug mode what is generated is a switch on the discriminant to a bunch of identical blocks of code which all set the pointer value to the same thing. After the switch statementArrayMetaHolder::meta_mut
and friends are called if needed.Array::convert
. It checks if we are converting to an array of the same type via TypeId, and transmutesArray<T>
toArray<U>
ifT == U
. This is essentially a specialization of theconvert
function whenT == U
. If I could pull in thecastaway
crate, I could replace this specialization with safe code. (To be clear, I haven't tried this yet) It also means that further specializations of generic functions for concrete types could be added to the codebase without needing to worry that much if the specialization is sound. See the discussion in the rust issue tracker about the 'min-specialization' and 'specialization' unstable features for why this sort of thing is tricky to do soundly in general. The castaway crate implements a known safe subset of specializations.The text was updated successfully, but these errors were encountered: