Skip to content

Lifetime of dependent type cannot depend on the function #44961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
uzytkownik opened this issue Oct 1, 2017 · 2 comments
Closed

Lifetime of dependent type cannot depend on the function #44961

uzytkownik opened this issue Oct 1, 2017 · 2 comments

Comments

@uzytkownik
Copy link

(This might be partially related to issue #44950)

Currently dependent types lifetime must not depend on the lifetime of the iterator. This is problematic when the method of iteration might alter the structure but copy is expensive or impossible (I run into this while binding C API but this affects also database cursors etc.).

Here's an example of code which shows the issue ([u8; 4096] is just an example of expensive-to-copy data).

struct Handle {
    buf: *mut [u8; 4096]
}

struct Iter {
    buf: Box<[u8; 4096]>,
    hnd: Handle
}

unsafe fn fake_c_method_init(buf: *mut [u8; 4096]) -> Handle {
    Handle {
        buf: buf
    }
}

unsafe fn fake_c_method_next(hnd: &mut Handle) -> bool {
    (*hnd.buf)[0] += 1;
    true
}

impl Iter {
    fn new() -> Self {
        use std::borrow::BorrowMut;
        let mut buf = Box::new([0; 4096]);
        let hnd = unsafe {
            fake_c_method_init(buf.borrow_mut() as *mut [u8; 4096])
        };
        Iter {
            buf: buf,
            hnd: hnd
        }
    }

    fn next_fast(&mut self) -> Option<&[u8; 4096]> {
        use std::borrow::Borrow;
        if unsafe {fake_c_method_next(&mut self.hnd)} {
            Some(self.buf.borrow())
        } else {
            None
        }
    }
}

impl Iterator for Iter {
    type Item = [u8; 4096];
    fn next(&mut self) -> Option<Self::Item> {
        self.next_fast().map(|arr| {
            let mut res = [0; 4096];
            for i in 0..4096 {
                res[i] = arr[i];
            }
            res
        })
    }
}

This is even though in most cases a copy is not needed.

@sfackler
Copy link
Member

sfackler commented Oct 1, 2017

You may be interested in https://docs.rs/streaming-iterator/0.1.2/streaming_iterator/.

This kind of thing is fundamentally incompatible with Iterator itself.

@XAMPPRocky
Copy link
Member

Closing as inactionable.

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

No branches or pull requests

3 participants