Skip to content
This repository has been archived by the owner on Aug 19, 2019. It is now read-only.

Cannot infer an appropriate lifetime when returning an Event from Iterator::next #2

Closed
mitchmindtree opened this issue Nov 24, 2014 · 9 comments

Comments

@mitchmindtree
Copy link
Member

The culprit line is here.

I want to return a mutable reference to the output buffer in the Event::Out so that a user can fill the buffer before being collected by the portaudio backend, however I'm unsure how to do this from the Iterator's next method. Here's the error I'm getting:

155:64 error: cannot infer an appropriate lifetime for pattern due to conflicting requirements
            let SoundStream { output_buffer: ref mut buffer, settings: settings, .. } = *self;
                                             ^~~~~~~~~~~~~~
165:6 help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self) -> Option<Event<'a, B, I, O>>
 fn next(&mut self) -> Option<Event<'a, B, I, O>> {
     // First, determine the new state by checking the previous state.
     let new_state = match self.prev_state {
         State::In => State::Out,
         State::Out => {

It suggests to use an explicit lifetime in the method signature, however this is obviously not possible as this would make the method signature differ from the trait declaration.

Can anyone spot what I'm missing here?

@bvssvni
Copy link

bvssvni commented Nov 24, 2014

The problem is in fn next(&mut self) -> Option<Event<'a, B, I, O>> because the lifetime at the parameter is anonymous, while the lifetime out is explicit. As a general rule, the compiler is not capable of "creating new" lifetimes, it must get something to give something out.

@bvssvni
Copy link

bvssvni commented Nov 24, 2014

One exception is that if you implement it for an object with a lifetime, then it might work. for SoundStream<B, I, O> does not have a lifetime, so it won't work.

@mitchmindtree
Copy link
Member Author

But this is the same issue with MutItems<'a, T> (the mutable slice iterator) and it manages to work quite well. I understand that it uses some kind of unsafe code to kind of coerce the lifetime, however it also uses a ContravariantLifetime marker and I'm not sure how to add this marker to an enum (the Event enum in this case) :/

@bvssvni
Copy link

bvssvni commented Nov 24, 2014

Perhaps you could create an iterator object from SoundStream and use a lifetime in it?

@mitchmindtree
Copy link
Member Author

when you say use a lifetime in it, do you mean one of those ContravariantLifetime marker things?

@bvssvni
Copy link

bvssvni commented Nov 24, 2014

I've never used that before, but it seems to do the same thing as when you have a mutable reference foo: &'a mut Foo. The NoCopy marker seems to prevent aliasing of the iterator object. Not sure how it tracks the borrowing of the original object.

@mitchmindtree
Copy link
Member Author

@bvssvni I've added a lifetime to SoundStream, however I still seem to be getting the same errors 😣 Does it look like I've missed anything? Sorry to bug ya, this one's definitely getting the best of me!

@mitchmindtree mitchmindtree changed the title How to return a mutable reference from Iterator::next(&mut self) -> ... ? Cannot infer an appropriate lifetime when returning an Event from Iterator::next Nov 28, 2014
@bvssvni
Copy link

bvssvni commented Nov 28, 2014

@mitchmindtree Perhaps let SoundStream { output_buffer: ref mut buffer, settings: settings, .. } means Rust tries to move out the settings, while keeping a mutable reference and register this as a conflicting requirement. Maybe you can do ref settings and clone it to the next object?

@mitchmindtree
Copy link
Member Author

Ended up solving this using transmute 👍

It's not safe, but a user would really have to try to mess it up... It's incredibly unlikely it would happen unintentionally. I left a note above the transmute with an explanation.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants