impl RegId {
pub fn to_u8(&self) -> u8 {
self.0}}
Is there a way to do an implicit RegId -> u8
conversion? Where anywhere we need a u8, we can pass it a RegId, and Rust will auto insert a .to_u8()
?
impl RegId {
pub fn to_u8(&self) -> u8 {
self.0}}
Is there a way to do an implicit RegId -> u8
conversion? Where anywhere we need a u8, we can pass it a RegId, and Rust will auto insert a .to_u8()
?
For whatever reason I've come across plenty of examples like this recently.
fn uses_u8<U: Into<u8>>(value: U) -> u8 { value.into().some_u8_calculation() }
I doubt auto-conversion without an explicit pathway is possible, but the alternative isn't bad.
This is a very cool solution, but unfortunately does not work in my case. I have a bunch of dynasm ( https://github.com/CensoredUsername/dynasm-rs ) code where there is a macro where one of the arguments is a u8 (indicates which register to use).
There's no way to do a true implicit conversion, but your macro could insert u8::from(value)
.
If the RegId
is a newtype over u8
, I think such implicit coercion would pass the benefits of the newtype patterns in vain as two different kinds of ids can be mixed together implicitly as a raw integer form.
https://github.com/CensoredUsername/dynasm-rs/blob/master/plugin/src/lib.rs#L44 is the macro in question
That's actually a good point. This started as
type RegId = u8
I changed it to
pub struct RegId(u8);
an auto conversion would pretty much undo all benefits.
Hmm... maybe RegId
should have stayed as a simple type alias, then?
You mentioned this will be used in a macro, so why not update the macro definition to always call .into()
on each of its arguments? Every type, T
, can be turned into itself so this would end up being a noop most of the time while letting you "implicitly" (from the point of view of the macro's caller) use a RegId
as a u8
.
Or alternatively, if you are passing values back and forth between assembly you could add a #[repr(transparent)]
to the RegId
definition. This would allow you to freely transmute back and forth between a RegId
and its u8
version, letting you use strong types on the Rust side and a byte in the generated machine code.
I'll just mention that u8::from
can work(can't speak to whether it's a good idea), because this is valid in the crate that declares RegId
:
impl From<RegId> for u8 {
fn from(this: RegId) -> u8 {
this.0
}
}
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.