Skip to content

Commit cde3ff8

Browse files
committed
tock-registers: fix Copy and Clone implementation on Field
A Field contains a PhantomData over a generic R: RegisterLongName, and a PhantomData<R> is copyable regardless of whether R: Copy. However, using #[derive(Copy, Clone)] will generate #[automatically_derived] #[allow(unused_qualifications)] impl<T: ::core::marker::Copy + IntLike, R: ::core::marker::Copy + RegisterLongName> ::core::marker::Copy for Field<T, R> {} and hence Field will only implement Copy when R: Copy. Manually implementing Clone and Copy works around this issue. See rust-lang/rust#26925 for more information on this. Signed-off-by: Leon Schuermann <[email protected]>
1 parent 3d93d8f commit cde3ff8

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

libraries/tock-register-interface/src/registers.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,6 @@ impl<T: IntLike, R: RegisterLongName> InMemoryRegister<T, R> {
518518
/// Specific section of a register.
519519
///
520520
/// For the Field, the mask is unshifted, ie. the LSB should always be set.
521-
#[derive(Copy, Clone)]
522521
pub struct Field<T: IntLike, R: RegisterLongName> {
523522
pub mask: T,
524523
pub shift: usize,
@@ -552,6 +551,33 @@ impl<T: IntLike, R: RegisterLongName> Field<T, R> {
552551
}
553552
}
554553

554+
// #[derive(Copy, Clone)] won't work here because it will use
555+
// incorrect bounds, as a result of using a PhantomData over the
556+
// generic R. The PhantomData<R> implements Copy regardless of whether
557+
// R does, but the #[derive(Copy, Clone)] generates
558+
//
559+
// #[automatically_derived]
560+
// #[allow(unused_qualifications)]
561+
// impl<T: ::core::marker::Copy + IntLike,
562+
// R: ::core::marker::Copy + RegisterLongName>
563+
// ::core::marker::Copy for Field<T, R> {}
564+
//
565+
// , so Field will only implement Copy if R: Copy.
566+
//
567+
// Manually implementing Clone and Copy works around this issue.
568+
//
569+
// Relevant Rust issue: https://github.com/rust-lang/rust/issues/26925
570+
impl<T: IntLike, R: RegisterLongName> Clone for Field<T, R> {
571+
fn clone(&self) -> Self {
572+
Field {
573+
mask: self.mask,
574+
shift: self.shift,
575+
associated_register: self.associated_register,
576+
}
577+
}
578+
}
579+
impl<T: IntLike, R: RegisterLongName> Copy for Field<T, R> {}
580+
555581
macro_rules! Field_impl_for {
556582
($type:ty) => {
557583
impl<R: RegisterLongName> Field<$type, R> {

0 commit comments

Comments
 (0)