Skip to content

Instantly share code, notes, and snippets.

@bwo bwo/confused.rs Secret
Created Feb 3, 2015

Embed
What would you like to do?
confused by lifetime error message!
macro_rules! gen_soa {
($soa:ident, $soazip:ident, $soazipm:ident | $($ty:ident),+ | $($nm:ident),+ | $($nmu:ident),+) => {
#[unsafe_no_drop_flag]
pub struct $soa<$($ty),+> {
$($nm: Unadorned<$ty>),+,
e: Extent,
}
pub struct $soazip<'a, $($ty:'a),+> {
parent: &'a $soa<$($ty),+>,
i: usize
}
// this compiles fine
impl<'a, $($ty),+> Iterator for $soazip<'a, $($ty),+> {
type Item = ($(&'a $ty),+);
#[inline]
fn next(&mut self) -> Option<($(&'a $ty),+)> {
let i = self.i;
if i == self.parent.len() { return None }
self.i += 1;
let ($($nm),+) = self.parent.as_slices();
unsafe {
Some(($($nm.get_unchecked(i)),+))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.parent.len(), Some(self.parent.len()))
}
}
pub struct $soazipm<'a, $($ty:'a),+> {
parent: &'a mut $soa<$($ty),+>,
i: usize
}
// this apparently quite similar impl does not compile at all:
/*
soa.rs:45:1: 452:2 note: in expansion of gen_soa!
soa.rs:456:1: 456:100 note: expansion site
soa.rs:88:46: 88:61 error: cannot infer an appropriate lifetime for autoref due to conflicting requirements
soa.rs:88 let ($($nm),+) = self.parent.as_mut_slices();
^~~~~~~~~~~~~~~
soa.rs:84:13: 92:14 help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self)
-> Option<(&'a mut A, &'a mut B, &'a mut C, &'a mut D, &'a mut E, &'a mut F)>
soa.rs:84 fn next(&mut self) -> Option<($(&'a mut $ty),+)> {
soa.rs:85 let i = self.i;
soa.rs:86 if i == self.parent.len() { return None }
soa.rs:87 self.i += 1;
soa.rs:88 let ($($nm),+) = self.parent.as_mut_slices();
soa.rs:89 unsafe {
Of course, I can't actually write &'a mut self in the method signature, because then I'll get
a complaint: "method `next` has an incompatible type for trait: expected bound lifetime parameter ,
found concrete lifetime"
*/
impl<'a, $($ty),+> Iterator for $soazipm<'a, $($ty),+> {
type Item = ($(&'a mut $ty),+);
#[inline]
fn next(&mut self) -> Option<($(&'a mut $ty),+)> {
let i = self.i;
if i == self.parent.len() { return None }
self.i += 1;
let ($($nm),+) = self.parent.as_mut_slices();
unsafe {
Some(($($nm.get_unchecked_mut(i)),+))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.parent.len(), Some(self.parent.len()))
}
}
impl<$($ty),+> $soa<$($ty),+> {
fn new() -> $soa<$($ty),+> {
unsafe {
$(let ($nm, $nmu) = Unadorned::new());+;
let e = unadorned::new_update(&[$($nmu),+]);
$soa { $($nm: $nm),+ , e: e}
}
}
// blah blah blah ...
// many functions later ...
#[inline]
pub fn as_mut_slices<'a> (&'a mut self) -> ($(&'a mut [$ty]),+) {
unsafe {
let len = self.e.len;
($(self.$nm.as_mut_slice(len)),+)
}
}
#[inline]
pub fn as_slices<'a>(&'a self) -> ($(&'a [$ty]),+) {
unsafe { let len = self.e.len;
($(self.$nm.as_slice(len)),+) }
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.