Skip to content

Instantly share code, notes, and snippets.

@U007D
Last active January 12, 2018 17:36
Show Gist options
  • Save U007D/1d390409002b26ab24e53d27be58c896 to your computer and use it in GitHub Desktop.
Save U007D/1d390409002b26ab24e53d27be58c896 to your computer and use it in GitHub Desktop.
Errors
/// crate gpio_mmap
/// mod gpio_mmap
pub trait GpioMmap {
type Error: Fail;
type Register;
fn new(...) -> Result<Self, Self::Error> where Self: Sized;
fn registers(&self) -> &[Self::Register];
}
/// crate raspbian_osal
/// mod raspbial_gpio_mmap
/// Mmap is defined in an external crate (memmap::Mmap on crates.io); details not relevant (I hope) ;)
pub struct RaspbianGpioMmap {
mmap: Mmap,
...
}
impl GpioMmap for RaspbianGpioMmap {
type Error = Error;
type Register = Register;
fn new(...) -> Result<Self> {
...
}
fn registers(&self) -> &[Self::Register] {
assert_ne!(size_of::<Self::Register>(), 0, "{}", MSG_ERR_INTERNAL_ZERO_SIZED_REGISTER_TYPE);
unsafe {
slice::from_raw_parts(self.mmap.ptr() as *const Self::Register,
self.mmap.len() * size_of::<u8>() / size_of::<Self::Register>())
}
}
}
/// mod raspbian_osal
pub struct RaspbianOsal<'a> {
gpio_registers: &'a [Register],
}
impl<'a> Osal<'a> for RaspbianOsal<'a> {
type Error = Error;
type Register = Register;
fn new<T>(gpio_mmap: &'a T) -> Result<Self> where T: GpioMmap<Register = Self::Register>,
Self: Sized, {
Ok(Self {
gpio_registers: gpio_mmap.registers(),
})
}
...
}
/// crate rpi3_chal
pub struct Rpi3ChalRaspbianOsalTestContainer {
...
pub gpio_mmap: Option<RaspbianGpioMmap>,
}
impl Rpi3ChalRaspbianOsalTestContainer {
pub fn build() -> Self {
...
let mut container = Self {
...
gpio_mmap: None,
};
container.resolve_gpio_mmap_once();
container
}
pub fn resolve_gpio_mmap_once(&mut self) -> Result<()> {
match self.mmap_already_instantiated.compare_and_swap(false, true, Ordering::Relaxed) {
true => Err(Error::SingletonViolation.context(MSG_GPIO_MMAP))?,
false => {
self.gpio_mmap = Some(RaspbianGpioMmap::new(&RASPBIAN_GPIO_DEVICE_ID,
RPI3_GPIO_BASE,
RPI3_GPIO_REGISTER_COUNT)?);
Ok(())
},
}
}
pub fn resolve_osal_once(&mut self) -> Result<RaspbianOsal> {
match self.osal_already_instantiated.compare_and_swap(false, true, Ordering::Relaxed) {
true => Err(Error::SingletonViolation.context(MSG_RASPBIAN_OSAL))?,
false => Ok(RaspbianOsal::new(&self.gpio_mmap.expect(MSG_ERR_INTERNAL_MMAP_CACHE))?), // <- this is the offending line ("line 56" in the error message below)
}
}
...
}
/// Here's the resulting error message:
```rust
error[E0597]: borrowed value does not live long enough
--> rpi3_chal/src/unit_tests/di.rs:56:44
|
56 | false => Ok(RaspbianOsal::new(&self.gpio_mmap.expect(MSG_ERR_INTERNAL_MMAP_CACHE))?),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value only lives until here
| |
| temporary value does not live long enough
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the method body at 53:5...
--> rpi3_chal/src/unit_tests/di.rs:53:5
|
53 | / pub fn resolve_osal_once(&mut self) -> Result<RaspbianOsal> {
54 | | match self.osal_already_instantiated.compare_and_swap(false, true, Ordering::Relaxed) {
55 | | true => Err(Error::SingletonViolation.context(MSG_RASPBIAN_OSAL))?,
56 | | false => Ok(RaspbianOsal::new(&self.gpio_mmap.expect(MSG_ERR_INTERNAL_MMAP_CACHE))?),
57 | | }
58 | | }
| |_____^
error[E0509]: cannot move out of type `unit_tests::di::Rpi3ChalRaspbianOsalTestContainer`, which implements the `Drop` trait
--> rpi3_chal/src/unit_tests/di.rs:56:44
|
56 | false => Ok(RaspbianOsal::new(&self.gpio_mmap.expect(MSG_ERR_INTERNAL_MMAP_CACHE))?),
| ^^^^^^^^^^^^^^ cannot move out of here
error: aborting due to 2 previous errors
error: Could not compile `rpi3_chal`.
/// I would have expected the ref to have been captured and stored. Its referent outlives the function call. How do I tell the compiler that this is OK?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment