These are chat archives for rust-lang/rust

18th
Jun 2018
David James
@xpe
Jun 18 2018 01:05
Hello, I have a question about figuring out a type to accomodate a struct having a particular trait: https://play.rust-lang.org/?gist=2449c373d4f4668fffc437ffbb3ac2f7&version=stable&mode=debug
Same version, condensed:
struct A;
struct B;
trait Walk { fn walk(self); }
impl Walk for A { fn walk(self) { println!("A walks"); } }
impl Walk for B { fn walk(self) { println!("B walks"); } }
fn main() {
    let random = 42; // chosen randomly
    let person = if rand > 39 { A } else { B }; // compiler error
    person.walk();
}
The second line in main doesn't compile. I'd like to find a way to tell the type system "you only need something that implements Walk".
Robert
@rw
Jun 18 2018 03:39
Hello! Would someone please help me debug a mutability lifetime issue? I have a function that calls functions on a mutable object, then I want it to release the mutable reference to the caller. Unfortunately, the error is only the vaguely-helpful "cannot borrow x as mutable more than once at a time". I've tried a number of things, and I don't know if NLL or something else is the way to do what I'm trying to do. I have a playground program to replicate the issue: https://play.rust-lang.org/?gist=efe9c55820da529a5b8f26fbf37d76b8&version=stable&mode=debug Thanks!
Robert
@rw
Jun 18 2018 03:50
@xpe If you are fine using trait objects, here is your code working: https://play.rust-lang.org/?gist=67c44596bc0bf1c4c702e917b5066ac0&version=stable&mode=debug
Kelly Thomas Kline
@kellytk
Jun 18 2018 03:52
I'm cross-compiling the ring crate on macOS for FreeBSD and I'm encountering an error I would appreciate help with: --- stderr
/Users/kellytk/cloned-repos/ring/target/x86_64-unknown-freebsd/debug/build/ring-0866268820b88bb7/out/aes-x86_64-elf.S:3:1: error: unknown directive
.type _x86_64_AES_encrypt,@function
David James
@xpe
Jun 18 2018 03:55
After reading over documentation about enums and traits, here is the simplest correction that does what I need to my example above:
struct A;
struct B;
trait Walk { fn walk(); }
impl Walk for A { fn walk() { println!("A walks"); } }
impl Walk for B { fn walk() { println!("B walks"); } }
fn main() {
    let random = 42; // chosen randomly
    if random > 39 { A::walk(); } else { B::walk(); }
}
Joseph Murphy
@JMurph2015
Jun 18 2018 06:48
Hi guys! So I'm doing some FFI work and I was wondering how to express that a reference field should be assumed valid for the lifetime of a struct?
For reference I'm working on https://github.com/rpi-ws281x/rpi-ws281x-rust
red75prime
@red75prime
Jun 18 2018 08:06
@JMurph2015 In stable rust you can't keep a reference to a part of a struct in the same struct. If you move the struct, the reference becomes invalid . Add an accessor function fn leds(&self) -> &[u8]
Paul Masurel
@fulmicoton
Jun 18 2018 08:16
@rw the problem comes from the use of the 'a lifetime on your reference
is that possible in your case?
Robert
@rw
Jun 18 2018 08:21
@fulmicoton thank you so much! would you please use the updated example i used in the forum thread? here's the link: https://play.rust-lang.org/?gist=9854d989a2d010466ec7fa0f50b8e7d6&version=stable&mode=debug
but I don't know if this makes sense in your case.

Basically you want
fn f<'a>(x: &mut Inner<'a>) {

not
fn f<'a>(x: &'a mut Inner<'a>) {

Robert
@rw
Jun 18 2018 08:26
@fulmicoton does that translate to:
fn f<'a, 'b>(x: &'b mut Inner<'a>) {
with 'b unrestricted?
Paul Masurel
@fulmicoton
Jun 18 2018 08:27
yes
so 'b exactly is the time of your function call.
Robert
@rw
Jun 18 2018 08:28
and this is what makes it work farther up the stack:
struct Outer<'a: 'b, 'b> {
    x: &'b mut Inner<'a>,
}
let me try it in my original code :-)
Paul Masurel
@fulmicoton
Jun 18 2018 08:28
yes
(we don't have 'b: 'a imply Outer<'b>: Outer<'a> apparently... I'm not entirely sure why...)
Robert
@rw
Jun 18 2018 08:32
how would you summarize the concept you used to solve the problem?
Paul Masurel
@fulmicoton
Jun 18 2018 08:33
Hmmmm...
I can try but I actually don't understand it that well.
Hmm actually I will do a shitty job :)
Basically have empathy for the compiler :)
Paul Masurel
@fulmicoton
Jun 18 2018 08:38
One key thing is that it applies very local rules to enforce check lifetimes.
So only the prototype of your function call was relevant here.
In other words first, mentally realize that the compiler is choking on this: https://play.rust-lang.org/?gist=01d9d593cd02b77b13af8595c2fe72d8&version=undefined&mode=undefined
Then the lifetime 'a of your InnerData is the same as the scope defined by your main function.
Paul Masurel
@fulmicoton
Jun 18 2018 08:44
When you call f, you were passing a reference that had the same lifetime.
This function f for instance, could have perfectly decided to take the reference and store it in a Vec<&'a Inner<'a>> ... That would have been legal.
Paul Masurel
@fulmicoton
Jun 18 2018 08:50
That's the job of the borrow checker to make enforce that this kind of stuff does not happen. By giving the reference a life time of 'a you are giving f the right to have fun with your reference of for a lifetime of 'a. In other words you are not giving any good reasons to the compiler that the borrow will be released when f returns.
What I don't know however... is whether it is possible to downcast Outer<'a> to Outer<'b> somehow when 'a: 'b
and if this is not possible, whether it is logically unsafe or not
Function fn f<'a>(&'a mut Inner<'a>) is invariant over 'a, so it mutably borrows Inner<'a> for its entire lifetime 'a, and not for a smaller time
Robert
@rw
Jun 18 2018 09:07
@fulmicoton that's helpful, thank you! i'll keep on truckin' :-)
@red75prime thanks, i just read that article; what does this sentence mean? "This is the general theme of variance vs invariance: if variance would allow you to store a short-lived value into a longer-lived slot, then you must be invariant."
red75prime
@red75prime
Jun 18 2018 09:12
If you were able to push &'a str (that is reference to some local variable) into Vec<&'static str>, then you could have use after free.
Vec<&'a T> is invariant over 'a, so you can push only &'static str into Vec<&'static str>
Robert
@rw
Jun 18 2018 09:33
@fulmicoton results look good -- thanks again friend!
Sylwester Rąpała
@xoac
Jun 18 2018 09:41
Isn't it strange?
245 | /         self.inner.poll_flush().map_err(|e| {
246 | |             error!("{}", e);
247 | |             Err(())
248 | |         })?;
    | |___________^ the trait `std::convert::From<std::result::Result<_, ()>>` is not implemented for `()`
Ok in map_err I should just return () :P
Zakarum
@omni-viral
Jun 18 2018 11:33

Vec<&'a T> is invariant over 'a

No. Vec<&'a T> is variant over 'a as it may accept &'b T where 'b: 'a as well.

@red75prime
trsh
@trsh
Jun 18 2018 12:03
Can I use regex in a regular match statement
?
trsh
@trsh
Jun 18 2018 12:09
Also Im very terrible at regexes, if someone can help me to write one to capture 0 inside of "[0]", i would highly appreciate it. :)
Denis Lisov
@tanriol
Jun 18 2018 12:10
@trsh In the guard clause you can.
Fredrik Portström
@portstrom
Jun 18 2018 12:11
@trsh /^\[(0)]$/ Can you be more specific?
Sylwester Rąpała
@xoac
Jun 18 2018 12:11
and look for regular expresion graph to understand how it really works
Paul Masurel
@fulmicoton
Jun 18 2018 12:26
@red75prime Oh yes you are right. thanks.
dovreshef
@dovreshef
Jun 18 2018 12:36
Can anybody direct me to some examples of failure usage in the wild? I don't understand all the different types. What is the different between errorkind and error? Should I have all my errors as errorkind and just one error?
trsh
@trsh
Jun 18 2018 12:41
@portstrom ended up with this > Regex::new(r#"^\[(\d+)\]$"#)
Any critics?
trsh
@trsh
Jun 18 2018 12:50
It's good, never mind
@tanriol whats guard clause?
@xoac tnx
Fredrik Portström
@portstrom
Jun 18 2018 14:05
@trsh That's fine if you allow numbers to start with zero, for example [0000042].
Fredrik Portström
@portstrom
Jun 18 2018 14:12
@trsh Oh, and unlike other languages, in Rust regular expressions match Unicode characters by default. You may want to change \d to [0-9]. Check this: http://play.rust-lang.org/?gist=daa22b14f2b30d74ac40db75a9df9a07
These are the characters matched by \d: https://www.fileformat.info/info/unicode/category/Nd/list.htm
trsh
@trsh
Jun 18 2018 14:49
Ok tnx for the info
I do not want to start with zeros
It has to be positive integer
Fredrik Portström
@portstrom
Jun 18 2018 14:51
To allow only integers greater than zero: r#"^\[([1-9][0-9]*)]$"#
To allow the number zero but no other numbers starting with zero: r#"^\[(0|[1-9][0-9]*)]$"#
trsh
@trsh
Jun 18 2018 14:53
wow, tnx
Denis Lisov
@tanriol
Jun 18 2018 15:01
@trsh See the book
trsh
@trsh
Jun 18 2018 15:10
ok tnx
James McCoy
@jamessan
Jun 18 2018 15:14
Don't use regular expressions when there are better ways to do it :) https://www.xkcd.com/1171/
A Dinesh
@dineshadepu
Jun 18 2018 16:27
Hi, can I embed another toml file in another toml file
like #include
trsh
@trsh
Jun 18 2018 16:37
How do i supress "is never read" warning? Allow dead code, doesn't work
Denis Lisov
@tanriol
Jun 18 2018 16:38
Variables that start with _ don't cause this warning :-)
trsh
@trsh
Jun 18 2018 16:39
The joke is that variable is Read
But Rust seems to not get it
David Raifaizen
@craftytrickster
Jun 18 2018 16:39
depends
#![allow(dead_code)]  //is for crate level

#[allow(dead_code)] // for regular structs/ functions, etc
Denis Lisov
@tanriol
Jun 18 2018 16:40
Example?
dead_code is for functions never called and things like that.
trsh
@trsh
Jun 18 2018 16:41
Dont have time right now sorry, Big code, have to extract
David Raifaizen
@craftytrickster
Jun 18 2018 16:41
how are you doing allow dead code, because it sohuld work
can you paste the example here
trsh
@trsh
Jun 18 2018 16:42
#[allow(dead_code)]
pub fn json_extract_worker(...
Should work
David Raifaizen
@craftytrickster
Jun 18 2018 16:43
and yet it complains that json_extract_worker is unused?
trsh
@trsh
Jun 18 2018 16:43
Complains about variables inside
That are unused
David Raifaizen
@craftytrickster
Jun 18 2018 16:43
ah
generally i just dont have unused variables, or i just use _ so i never really have that problem
trsh
@trsh
Jun 18 2018 16:44
Yeah I added _ at start
as @tanriol told
tnx
trsh
@trsh
Jun 18 2018 18:19
So Im been using for now futures.join, and it works well. The problem is that when one joined future fails it all stops and fails. I want instead, when all futures are complete, get an vec of results to handle errors manually and do not stop all. Looking into doc, and can find what i need. Maybe somone knows right away?
Denis Lisov
@tanriol
Jun 18 2018 18:26
I'd suggest then
trsh
@trsh
Jun 18 2018 18:30
@tanriol join_all + then has exactly the problem im speaking about
if i join a,b,c futures and a fails, everything stops
b,c will never be resolved
@craftytrickster dont think so, i a fails, it will stop and step into closure
David Raifaizen
@craftytrickster
Jun 18 2018 18:34
im struggling with tokio/futures myself, so im probably not the best person to answer :)
last guess, maybe you can use the recover method
trsh
@trsh
Jun 18 2018 18:36
Isnt recover for panics!
?
David Raifaizen
@craftytrickster
Jun 18 2018 18:36
i think that is catch_unwind
https://docs.rs/futures/0.2.1/futures/trait.FutureExt.html#method.recover makes it look like it is converting the err into a value
ive never used it though
trsh
@trsh
Jun 18 2018 18:48
@craftytrickster so what u mean with recover
?
trsh
@trsh
Jun 18 2018 19:02
What i can do is wrap a,b,c into another futures, resolve with then and set the results I want for the Joined fut
Eugene Tolmachev
@et1975
Jun 18 2018 20:24
Hi folks, is there a way to specify concrete override for a generic?
impl<E> From<E> for DeserializationError<E> {
    fn from(err : E) -> DeserializationError<E> {
        DeserializationError::Other(err)
    }
}

impl From<heapless::BufferFullError> for DeserializationError<heapless::BufferFullError> {
    fn from(err : heapless::BufferFullError) -> DeserializationError<heapless::BufferFullError> {
        DeserializationError::WouldOverflow
    }
}

This gives me:

conflicting implementation for serializer::DeserializationError<heapless::BufferFullError>

Denis Lisov
@tanriol
Jun 18 2018 21:05
@trsh I mean that with my_future.then(|res| Ok(res)) you can go from Future<Item=T, Error=E> to Future<Item=Result<T, E>, Error=_> which always resolves "successfully" and does not terminate join_all
@et1975 Not yet, specialization is planned and partially implemented, but still unstable.
Eugene Tolmachev
@et1975
Jun 18 2018 21:09
@tanriol thx, is it in nightly by any chance? Any links?
Denis Lisov
@tanriol
Jun 18 2018 21:19
The tracking issue is rust-lang/rust#31844, but beware - some uses of specialization may be unsound. However, it's used in the standard library, so some of them are ok :-)
Eugene Tolmachev
@et1975
Jun 18 2018 21:20
:+1:
Denis Lisov
@tanriol
Jun 18 2018 21:21
I'd at least look at #40582 and #33017 to know what to expect.
Eugene Tolmachev
@et1975
Jun 18 2018 21:23
thanks
Denis Lisov
@tanriol
Jun 18 2018 21:23
Some of the problems are likely to be solved only after chalk work (new implementation of the trait system) is ready.
Kevin Watters
@kevinw
Jun 18 2018 22:17
anyone familiar with osx build magic? i'm debugging a problem with a sub-dependency (coreaudio-sys) and I'm getting the following error: //Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AudioToolbox.framework/Headers/AudioUnit.h:12:10: fatal error: 'TargetConditionals.h' file not found
i can see that the file exists at: ./Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/TargetConditionals.h
but it looks like the paths aren't setup correctly
Kevin Watters
@kevinw
Jun 18 2018 23:12
ah nevermind, looks like i needed to install xcode's commandline tools