Skip to content
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

from_raw(_mut)_buf returns slices with weird lifetimes #20031

Closed
Tobba opened this issue Dec 19, 2014 · 9 comments
Closed

from_raw(_mut)_buf returns slices with weird lifetimes #20031

Tobba opened this issue Dec 19, 2014 · 9 comments

Comments

@Tobba
Copy link
Contributor

Tobba commented Dec 19, 2014

These functions take a reference to the raw pointer you're trying to use and returns a slice with a lifetime based on the lifetime of your raw pointer. This behavior is not only extremely noisy, but leads to a mess of nasty transmutes or one-off variables when the raw pointer in question is calculated by i.e .offset().

A better approach might be letting the lifetime be inferred or letting the caller explicitly specify it.

@Gankra
Copy link
Contributor

Gankra commented Dec 19, 2014

We hashed this out on irc a while ago. The old design made you take a closure so that you didn't accidentally "elevate" a slice to 'static. This design is basically trying to do the same thing by constraining the lifetime. I'm not convinced it's the right design but at very least we want to give it a test-drive for a bit.

Note that you can also copy_lifetime or construct the slice yourself with a transmute.

CC @alexcrichton @nikomatsakis

@Tobba
Copy link
Contributor Author

Tobba commented Dec 19, 2014

I'm currently using transmute and raw::Slice for most slice construction due to the limitations of the old design. With the new design every one of those instances still require a transmutation to fix the lifetime (copy_lifetime never seems to do its job).

@nikomatsakis
Copy link
Contributor

I'd like to see your examples. I think if you are using a raw transmute, there is likely a better way to do it, but I agree that we have to experiment to find the right pattern.

@Tobba
Copy link
Contributor Author

Tobba commented Dec 21, 2014

Nearly all of the transmutes are necessary because the pointer type has to be casted or is returned from a function call. There are a few of these pointers that could have their type changed to help, but some cannot be fixed without changing a public API.

@aturon
Copy link
Member

aturon commented Jan 8, 2015

cc me, cc @alexcrichton

@reem
Copy link
Contributor

reem commented Jan 8, 2015

There is an open RFC to change the way the output lifetime is decided to instead use an explicit third parameter. That might be relevant to this (mostly based off of the examples in #20748).

@tomaka
Copy link
Contributor

tomaka commented Jan 8, 2015

Examples that should be working but don't because of this issue:

Casting between pointer types: (http://is.gd/eW1KmQ)

struct Foo { data: *mut i8, len: uint }
impl Foo {
    fn as_slice(&self) -> &[i8] {
        unsafe {
            // value "self.data as *const i8" does not live long enough
            std::slice::from_raw_buf(&(self.data as *const i8), self.len)
        }
    }
}

Using raw pointers in iterators: (http://is.gd/UsePsX)

struct Iter<'a> { data: *const u8, marker: ContravariantLifetime<'a> }
impl<'a> Iterator for Iter<'a> {
    type Item = &'a [u8];
    fn next(&mut self) -> Option<&'a [u8]> {
        Some(unsafe {
            // cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
            std::slice::from_raw_buf(&self.data, 1)
        })
    }
}

@mzabaluev
Copy link
Contributor

@reem here's the RFC draft

@alexcrichton
Copy link
Member

Fixed in #21926

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

9 participants