Skip to content

Commit

Permalink
Improve assembly of Contiguous derive
Browse files Browse the repository at this point in the history
`from_integer` and `into_integer` are usually provided by the trait's
default implementation. We override this implementation because it goes
through `transmute_copy`, which can lead to inefficient assembly as seen
in Lokathor#175 .
  • Loading branch information
e00E committed Jul 19, 2023
1 parent 62a7ec9 commit 09b6d85
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions derive/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,31 @@ impl Derivable for Contiguous {
let min_lit = LitInt::new(&format!("{}", min), input.span());
let max_lit = LitInt::new(&format!("{}", max), input.span());

// `from_integer` and `into_integer` are usually provided by the trait's default implementation.
// We override this implementation because it goes through `transmute_copy`, which can lead to
// inefficient assembly as seen in https://github.com/Lokathor/bytemuck/issues/175 .

Ok((
quote!(),
quote! {
type Int = #integer_ty;
const MIN_VALUE: #integer_ty = #min_lit;
const MAX_VALUE: #integer_ty = #max_lit;

#[inline]
fn from_integer(value: Self::Int) -> Option<Self> {
#[allow(clippy::manual_range_contains)]
if Self::MIN_VALUE <= value && value <= Self::MAX_VALUE {
Some(unsafe { ::core::mem::transmute(value) })
} else {
None
}
}

#[inline]
fn into_integer(self) -> Self::Int {
self as #integer_ty
}
},
))
}
Expand Down

0 comments on commit 09b6d85

Please sign in to comment.