Skip to content

std::slice::from_raw_buf is very unergonomic #20748

@tomaka

Description

@tomaka

The signature of from_raw_buf is:

fn from_raw_buf<T>(p: &'a *const T, len: uint) -> &'a [T]

The fact that the lifetime of the returned slice is the same as the lifetime of the pointer is a very bad idea. And now that CVec is gone, this is the only way to build a slice from a raw pointer.

I can see many potential problems, but the ones that I've encountered while removing CVec is that you can't cast your pointers, not even from mut to const: (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)
        }
    }
}

And that you can't use raw pointers in iterators anymore: (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)
        })
    }
}

If I'm manipulating raw pointers which are unsafe by nature, please let me be unsafe!

The first example can be bypassed by using from_raw_mut_buf and casting the returned &mut [i8] to a &[i8], which means that the unsafe API is more restrictive than the safe API!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions