I think I should have put my code to gist to track changes easily. Amending: https://gist.github.com/dpx-infinity/6751843
2013/9/29 Vladimir Matveev <[email protected]>: > Yes, this is what I have observed too, see issue > https://github.com/mozilla/rust/issues/9597. I didn't know that using > extra parameter with lifetime will help though. It indeed works. But I > think that polluting traits-interfaces with lifetime annotation is > wrong. Why the trait should have lifetime annotation? It is > implementation detail. > > I just managed to do what I wanted with some kind of hack. The > following code compiles and works: > > // Some business-logic trait > trait Walker { > fn walk(self); // Just self, without pointers > } > > // ReaderContainer implementation remains the same > > // A struct which is intended to be an implementor of Walker trait > // Note that it has lifetime parameter in order to work for any kind > // of pointer to a Reader > struct ReaderContainer<'self> { > priv reader: &'self Reader, > priv counter: int > } > > // Some auxiliary structure for ReaderContainer > // It may be anything but it should have a reference to ReaderContainer > // We have to use lifetime parameter because this structure is 'attached' > // to ReaderContainer, hence it must be of the same lifetime > struct ReaderContainerIterator<'self> { > priv container: &'self mut ReaderContainer<'self> > } > > // Some made-up implementation of iterator protocol for our > // auxiliary structure, it does not really matter > impl<'self> Iterator<u8> for ReaderContainerIterator<'self> { > fn next(&mut self) -> Option<u8> { > if self.container.counter < 10 { > self.container.counter += 1; > Some(self.container.reader.read_byte() as u8) > } else { > None > } > } > } > > impl<'self> ReaderContainer<'self> { > // A constructor for ReaderContainer, nothing special > fn new<'a>(reader: &'a Reader) -> ReaderContainer<'a> { > ReaderContainer { reader: reader, counter: 0 } > } > > // A method which returns our auxiliary structure, i.e. iterator > // Note that self parameter has lifetime 'self, otherwise this naturally > // does not compile > fn iter(&'self mut self) -> ReaderContainerIterator<'self> { > ReaderContainerIterator { container: self } > } > } > > // And here are the changes > > // We implement Walker for a reference of the specific type! > impl<'self> Walker for &'self mut ReaderContainer<'self> { > // Here self automatically is &'self mut reference, so we can safely > // use iter() method > fn walk(self) { > for b in self.iter() { > println(fmt!("byte %?", b)); > } > } > } > > fn main() { > use std::io; > > let r = io::stdin(); > let mut c = ReaderContainer::new(r); > > c.walk(); // No extra parameters > } > > > In short, I'm implementing `Walker` trait not for > `ReaderContainer<'self>` but for `&'self mut ReaderContainer<'self>`. > > This does not feel right, but I do not see immediate problems with > this solution. Maybe someone who knows more about lifetimes could > comment on this. > > 2013/9/29 David Renshaw <[email protected]>: >> If I drop the unused parameter, I get an internal compiler error: >> 'assertion failed: self.variance.is_some()' _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
