These are chat archives for rust-lang/rust

25th
Jun 2018
Sai Zeng
@zengsai
Jun 25 2018 01:57
Help, lifetime confused me, when compile this code, A has Error, than I can understand, but B and C passed, it looks like than the 'a:b` on function header is not work:
fn lifetime_a_larger_than_b<'b, 'a: 'b, T>(_: &'a T, _: &'b T) {}

fn main() {
    let x = 5i32;
    let mut a = &x;

    let y = 0i32;
    let b = &y;

    // A
    // a = b; // Error: borrowed value does not live long enough.

    lifetime_a_larger_than_b(a, b);   // B
    lifetime_a_larger_than_b(b, a);   // C
}
Denis Lisov
@tanriol
Jun 25 2018 07:53
@zengsai Note that a function call may reborrow arguments, shortening their lifetimes.
Sai Zeng
@zengsai
Jun 25 2018 08:45
@tanriol Can you tell me more detail about this reborrow rule?
Sylwester Rąpała
@xoac
Jun 25 2018 08:51
How can I take from &[u8] iterator that hold 4 bytes and reserve them. By example [0,1,2,3,4,5,6,7,8] -> and I would like to have 3,2,1,0,7,6,5,4. I tried windows method on slice but I don't know how to reverse that window.
Paul Masurel
@fulmicoton
Jun 25 2018 08:52
window is sliding
what you want is chunks_mut
to get non overlapping mutable subslices
then the mutable slice has a .reverse function
Denis Lisov
@tanriol
Jun 25 2018 08:53
@zengsai When an argument is a (mutable) reference arg: &'any T, Rust implicitly passes to the function not arg, but &*arg, which is a new pointer to the same underlying object. It can live no longer than the original, but can live less.
Sylwester Rąpała
@xoac
Jun 25 2018 08:59
@fulmicoton has this be mut?
I want just read it
Paul Masurel
@fulmicoton
Jun 25 2018 09:00
it is a tad more difficult if you want to get the equivalent iterator without mutating
let me see
Sylwester Rąpała
@xoac
Jun 25 2018 09:01
I just need to cal CRC and I need take 4 bytes at time in reverse order :P
Paul Masurel
@fulmicoton
Jun 25 2018 09:04
v.chunks(4).flat_map(|chunk| chunk.iter().rev())
@xoac
does what you wnat
Sylwester Rąpała
@xoac
Jun 25 2018 09:05
thank you
Karthik Ravikanti
@plumenator
Jun 25 2018 12:07
What does &* mean?
Ingvar Stepanyan
@RReverser
Jun 25 2018 12:09
take a reference of dereferenced value
Dmitriy
@dpogretskiy
Jun 25 2018 12:09
  • uses Deref trait, so it's not always just a reference
*
Ingvar Stepanyan
@RReverser
Jun 25 2018 12:09
it might be a no-op, or it might allow you to take a reference of a different type than original one (if type implements custom Deref, simplest example being Box)
Karthik Ravikanti
@plumenator
Jun 25 2018 12:35
Thanks guys, took me a few google searches, but yeah, it was the Deref trait. Also TIL deref coercion
Josh
@joshlemer
Jun 25 2018 14:34
So this would typically be used for things like Guard and Arc and Rc right? Because it would be useless to use it for &T right?
Zakarum
@omni-viral
Jun 25 2018 15:22
@joshlemer &* makes sense to use for &T if in context you don't know it is &T but some misteriousimpl Deref<Target = T>. :smile:
Josh
@joshlemer
Jun 25 2018 15:23
ah got it, thanks :-)
Zakarum
@omni-viral
Jun 25 2018 15:24
And for &mut T it makes sence to drop mutability
Josh
@joshlemer
Jun 25 2018 17:35
If I have a function that only accepts numbers from 0 to 36 for example, is it better style to return a Result, or to just panic in the case of out range arguments?
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:40
It's pretty much always better to return a Result
Unless it's an internal helper and you know that input has been already validated, and so number out of range is a coding mistake, then panicking might be fine.
But for the last one it might be better to have a custom newtype that can hold only validated data.
Like MyNumber(u8) which can be only created as part of some u8 -> Result<MyNumber, Error> conversion
Then in all places you have MyNumber, you will be sure that it's in the correct range on type level, which makes it much easier to reason about the code.
Fredrik Portström
@portstrom
Jun 25 2018 17:43
Functions in Rust typically panic on invalid arguments. Returning a Result to require the user of a function to handle an error that cannot possibly happen when properly using the function is nothing but annoying. It's like the JSON object class in Java that requires you to catch exceptions that can never occur.
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:45

to require the user of a function to handle an error that cannot possibly happen when properly using the function is nothing but annoying

Rather the opposite; there should be always a way to gracefully handle validation errors, you can't expect that everyone is "properly using the function". With Result user of API can always opt-in to call .unwrap() if they're sure that data is correct, while going the other way around is much trickier.

Josh
@joshlemer
Jun 25 2018 17:49
I guess performance might be a concern
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:49

Functions in Rust typically panic on invalid arguments.

Also I'm not sure which functions you're referring to here. In stdlib, all conversion functions either return a Result or are explicitly marked as unsafe if they skip data validation.

I guess performance might be a concern

For which case?

Josh
@joshlemer
Jun 25 2018 17:50
maybe one could provide both fn foo(i: i32) -> Result<... and fn foo_unsafe(i: i32) -> ()
Fredrik Portström
@portstrom
Jun 25 2018 17:50
Calling unwrap is just a more verbose way to panic. Better make the function panic internally.
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:50
@joshlemer Why? It's really not winning anything.
Fredrik Portström
@portstrom
Jun 25 2018 17:50

Also I'm not sure which functions you're referring to here.

Most functions in the standard library.

Ingvar Stepanyan
@RReverser
Jun 25 2018 17:51
Can you provide an example?
Josh
@joshlemer
Jun 25 2018 17:51
@RReverser the thing I guess you're winning is that you're placing in the name that it is unsafe
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:51
I mean, performance-wise.
Josh
@joshlemer
Jun 25 2018 17:51
Maybe it will be a bit slower to wrap in a Result
I'm not exactly sure how much
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:52
Not really, Rust abstractions are usually zero-cost by design.
That's one of the features.
Fredrik Portström
@portstrom
Jun 25 2018 17:52
@RReverser Index typically panics even though the trait doesn't even say it may panic. https://doc.rust-lang.org/std/ops/trait.Index.html#tymethod.index
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:52
Index is not really a conversion function, but yeah, it's a good example.
But I'm talking about conversion functions which typically include validation (and hopefully there will be even more when TryFrom is stabilised).
Josh
@joshlemer
Jun 25 2018 17:53
the example I have in mind is more akin to indexing than validation
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:53
It doesn't cost anything to return a Result, and it helps a lot not to crash user's app just because some helper function in a library didn't pass validation.
Josh
@joshlemer
Jun 25 2018 17:54
specifically I'm translating google/hilbert to rust from Go, for fun :-) https://github.com/google/hilbert/blob/master/hilbert.go#L49
the argument must be between 0...n^2
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:54
@joshlemer Well, I stay on my newtype option then.
Josh
@joshlemer
Jun 25 2018 17:55
wouldn't forcing clients to construct a newType for their u32 be even more annoying than unwrapping a Result?
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:55
It translates to exactly same code as number, so performance-wise there would be no difference, while it becomes easier to see where data has been already checked in the code.
You don't need to force clients, it can be purely internal representation.
Josh
@joshlemer
Jun 25 2018 17:57
oh but I'm talking about the public api, map(t: u32) would need to become map(t: NewType)
Ingvar Stepanyan
@RReverser
Jun 25 2018 17:58
It's up to you; you can keep public API to accept any number, but then convert it to your NewType when validating data.
But then it really depends on how many functions you have, looking at this code, maybe you can just validate data w/o newtype and conversion if there is only one place where it can be incorrect (entry point to your library).
Either way, returning a Result is a better option if this is meant to be used as a library by a third-party code (which seems to be the case).
Josh
@joshlemer
Jun 25 2018 18:02
thanks for the advice @RReverser, I'll go with the Result
Zack Pierce
@ZackPierce
Jun 25 2018 18:20
@joshlemer If you're worried about the performance cost, I can anecdotally add that in a few of the relatively high-performance scenarios where I've had to model the real possibility of failure, the use of Result had a negligible effect on speed
Judson Lester
@nyarly
Jun 25 2018 19:03
I may be having a sophomore moment: I'm having a hard time imagining how https://docs.rs/cookie/0.10.1/cookie/struct.CookieJar.html is particularly useful.
All the cookies have to be 'static - so they basically have to be known at compile time?
Fredrik Portström
@portstrom
Jun 25 2018 19:05
@nyarly Seems like it's using Cow. That means you can borrow any &'static str, but you can also have owned strings that are not known on compile time.
Judson Lester
@nyarly
Jun 25 2018 19:08
i.e. the Cow is what's 'static, not the &str. I guess I need to look more into Cow
Fredrik Portström
@portstrom
Jun 25 2018 19:12
@nyarly The &str stored in Cow::Borrowed is 'static. The string you borrow from Cow has a shorter lifetime.
Judson Lester
@nyarly
Jun 25 2018 21:04
How is that possible, @portstrom ? My understanding of 'static is that it it's the lifetime of program execution. How can I put a string that e.g. I get off the wire into a Cow, and then borrow it as 'static? If it's just "from the creation of the Cow to the end of the program" ... Does it leak memory?
Fredrik Portström
@portstrom
Jun 25 2018 21:07
@nyarly You can put a 'static in Cow::Borrowed, but you cannot borrow as 'static from the Cow.
Judson Lester
@nyarly
Jun 25 2018 21:09
What I failed to realize is that Cow is an enum over Borrowed and Owned, and that the lifetime only applies to Borrowed
Fredrik Portström
@portstrom
Jun 25 2018 21:10
That's right.
Judson Lester
@nyarly
Jun 25 2018 21:14
I need to find a way to spend a lot more time in concentration with Rust.