These are chat archives for rust-lang/rust

7th
Apr 2018
Uli Schlachter
@psychon
Apr 07 2018 11:06
Hi, is there a safe way to turn a &[u8] into a &[u32] with (at most) a fourth of the length without actually copying the data around?
Basically, I am looking for a safe version of the following:
fn cast(slice: &[u8]) -> &[u32]
{
    unsafe {
        let ptr: *const u32 = std::mem::transmute(slice.as_ptr());
        std::slice::from_raw_parts(ptr, slice.len() / 4)
    }
}
Since I expect someone will be asking "why?": cairo's ARGB32 image format is specified as a "32-bit quantity" using the native endianness: https://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t
Michal 'vorner' Vaner
@vorner
Apr 07 2018 11:08
I don't think there's a safe way to do this.
Uli Schlachter
@psychon
Apr 07 2018 11:08
Other code (e.g. GdkPixbuf) however uses image formats that are based on bytes
Andy Grove
@andygrove
Apr 07 2018 13:09
I'm going crazy on the last step of a huge refactor ... could someone help with a dumb mutable borrow question please?
pub struct DataSourceIterator {
    ds: Rc<DataSource>,
}

impl DataSourceIterator {
    pub fn new(ds: Rc<DataSource>) -> Self {
        DataSourceIterator { ds }
    }
}

impl Iterator for DataSourceIterator {
    type Item = Result<Rc<RecordBatch>, ExecutionError>;

    fn next(&mut self) -> Option<Self::Item> {
        use std::borrow::BorrowMut;
        self.ds.next()
    }
}
I always struggle with iterators
I cannot do self.ds.next() because
82 |         self.ds.next()
   |         ^^^^^^^ cannot borrow as mutable
self is mutable ... and self owns ds which is an Rc
can I not have call mutable methods on things wrapped in Rc?
Krisztián Szűcs
@kszucs
Apr 07 2018 13:13

Hey @andygrove

Shared references in Rust disallow mutation by default, and Rc is no exception: you cannot generally obtain a mutable reference to something inside an Rc. If you need mutability, put a Cell or RefCell inside the Rc; see an example of mutability inside an Rc.

Andy Grove
@andygrove
Apr 07 2018 13:14
Hey @kszucs .. thanks .. maybe I should have used Box instead of Rc in this case ... I'm wrapping a file reader essentially
Ed Page
@epage
Apr 07 2018 17:29
Any tips for flattening Iter<Result<Iter>>?
For more details, see https://play.rust-lang.org/?gist=dd10e8e571f8bd1d1dd76abd51055d8e&version=stable
Boris-Chengbiao Zhou
@Bobo1239
Apr 07 2018 18:04
This works but I'd like to think that there's a better solution without using Box...
Ed Page
@epage
Apr 07 2018 18:13
Yeah, I was worried Box might be my only option
red75prime
@red75prime
Apr 07 2018 18:36
@epage There's a way https://play.rust-lang.org/?gist=d8f485c0583816ba19791ebf7b3464c2&version=stable , but I'm not sure about performance
Denis
@mexus
Apr 07 2018 18:37
@epage the problem is that your closure in flat_map returns two distinct types (despite the fact that both of them implement the same trait), so you can either Box them up or wrap them up somehow
haha
well I've coded something similar to @red75prime 's example: https://play.rust-lang.org/?gist=846fa5abc8109ed9bbcc8fd435cf6672&version=nightly
but his solution is definitely more general
Ed Page
@epage
Apr 07 2018 18:42
Yeah, one of those fun situations where, in theory, the flat_maps could have the same type because they only contain a function pointer but the hoops for a dev to jump through to activate it or the smarts needed in the compiler to detect it becomes prohibitive.
Denis
@mexus
Apr 07 2018 18:46
it's not like the compiler is bitchy :) it's just because rust is strictly typed so you can't return two different types from a function
and regarding using a pointer to a function.. well, the Box solution does exactly that
well okay, not exactly, but something extremely similar
Ed Page
@epage
Apr 07 2018 18:46
I was more so referring to a fn rather than Fn.
The compiler requires coaxing to turn the Fn (exact type one per closure) to afn (type only defined by signature).
Drat, I missed the fact that the in-parameter is of different types
So there is no way to get them to match types.
red75prime
@red75prime
Apr 07 2018 18:53
This compiles
fn test<F: Fn()>(_: F) {}

fn test2(_: fn()) {}

fn foo() {}

fn main() {
    test(foo);
    test(foo as fn());
    test(|| foo());
    test2(foo);
    test2(foo as fn());
    test2(|| foo());
}
Denis
@mexus
Apr 07 2018 18:55

Drat, I missed the fact that the in-parameter is of different types

yep, that's the issue

Denis
@mexus
Apr 07 2018 19:04
both implement the same trait but are distinct types essentially