Re: [rust-dev] RFC about std::option and std::result API
Would a ruby-style ok?/ok work to replace is_ok/ok? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC about std::option and std::result API
I would love it if '?' was allowed at the end of any identifier, to make it natural to name boolean variables, methods, constants, etc. Having to say is_xxx is ugly IMO. A lint option ensuring this is only applied to boolean typed constructs could help reduce abuse, if this is seen as an issue. On Nov 2, 2013 8:02 AM, Steve Klabnik st...@steveklabnik.com wrote: Would a ruby-style ok?/ok work to replace is_ok/ok? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC about std::option and std::result API
A '?' suffix for boolean methods would be fantastic. On Sat, Nov 2, 2013 at 4:40 AM, Oren Ben-Kiki o...@ben-kiki.org wrote: I would love it if '?' was allowed at the end of any identifier, to make it natural to name boolean variables, methods, constants, etc. Having to say is_xxx is ugly IMO. A lint option ensuring this is only applied to boolean typed constructs could help reduce abuse, if this is seen as an issue. On Nov 2, 2013 8:02 AM, Steve Klabnik st...@steveklabnik.com wrote: Would a ruby-style ok?/ok work to replace is_ok/ok? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- Andrés Osinski http://www.andresosinski.com.ar/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC about std::option and std::result API
I am generally in favor of this proposal. It seems to be a reasonable way forward. It is unclear to me how many types would benefit from this approach of having methods for each variant, but `Result` certainly does. With respect to possible confusion between `is_ok()` and `ok()` -- I think that the presence of a boolean return type should help with that. (That is, if you write `if foo.ok() { ... }` the compiler will catch it readily enough) Some of the methods on `Result`, however, can't be implemented in terms of this approach. For example, `chain` and `chain_err` really need to keep the `Result` return type. But I guess that's clear enough. One specific comment on your message: - There was talk about making `Result` use an `~Error` trait object instead of a generic type `E`, which could invalidate most of this email. However, this could also just mean that you usually will see `ResultT, ~Error` in the wild, for which this proposal still applies. Additionally, even if the Pattern becomes useless for Result, the problem still exists for any other newtype variant enums, so I'd like to see it get used anyway. It is not clear to me why moving to a `~Error` object would have any effect on this proposal. `err()` would just return `Option~Error` in that case, right? Niko ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] How would you map one vector to a vector of a different element type?
Hi, I have a ~[~str]. I have code that will turn a ~str into a Portuint. I want to end up with a [Portuint]. (or ~ or @ or whatever. I just want to be able to iterate over the Ports later.) Since I'm not sure what looping construct to use, I tried with a for-each loop. ~~~ let ports = for s in myvect.iter() { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ As you might, expect I got an error: error: mismatched types: expected `()` but found `std::comm::Portuint` (expected () but found struct std::comm::Port) From this, I take it that for loops must return `()`, rather than an actual value. When I searched for a map function in the documentation, I only found a Map type. How would you map one vector to a vector of a different element type? Thanks, Leah ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How would you map one vector to a vector of a different element type?
I would think: let ports = do myvect.iter().map { |e| something(e) } On Sat, 2 Nov 2013, Leah Hanson wrote: Hi, I have a ~[~str]. I have code that will turn a ~str into a Portuint. I want to end up with a [Portuint]. (or ~ or @ or whatever. I just want to be able to iterate over the Ports later.) Since I'm not sure what looping construct to use, I tried with a for-each loop. ~~~ let ports = for s in myvect.iter() { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ As you might, expect I got an error: error: mismatched types: expected `()` but found `std::comm::Portuint` (expected () but found struct std::comm::Port) From this, I take it that for loops must return `()`, rather than an actual value. When I searched for a map function in the documentation, I only found a Map type. How would you map one vector to a vector of a different element type? Thanks, Leah -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How would you map one vector to a vector of a different element type?
Thanks, Scott, I think that's closer. However, now I'm having trouble with my pointer types. Using the element inside a spawn means that I need to capture the owned string in the right way so that the compiler allows me to give it to the other task. This version: ~~~ let ports = do myvect.iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ gives me pointer-type related errors: - error: cannot move out of dereference of pointer - cchan.send(fun(*s)) - error: cannot borrow immutable local variable as mutable - when I iterate over the Ports later - error: cannot capture variable of type `~str`, which does not fulfill `Send`, in a bounded closure - cchan.send(fun(*s)) I also tried a version with |s| and cchan.send(fun(s)), which gave me different errors: - error: cannot move out of captured outer variable in a heap closure - cchan.send(fun(*s)) - error: cannot move out of dereference of pointer - on the |s| - error: cannot borrow immutable local variable as mutable - when I iterate over the Ports later I'm very new to Rust. What do I need to do to let the compiler know that I'm not going to use anything in the first vec anymore? That I just want the ~str pointers directly? (I put the |s| outside the {} because putting it inside seemed to confuse things -- in that case, rustc expected an identifier instead of the `let` that comes next, so I assumed that `do v.iter().map {|s| ...}` is a syntax error.) Thanks, Leah On Sat, Nov 2, 2013 at 3:23 PM, Scott Lawrence byt...@gmail.com wrote: I would think: let ports = do myvect.iter().map { |e| something(e) } On Sat, 2 Nov 2013, Leah Hanson wrote: Hi, I have a ~[~str]. I have code that will turn a ~str into a Portuint. I want to end up with a [Portuint]. (or ~ or @ or whatever. I just want to be able to iterate over the Ports later.) Since I'm not sure what looping construct to use, I tried with a for-each loop. ~~~ let ports = for s in myvect.iter() { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ As you might, expect I got an error: error: mismatched types: expected `()` but found `std::comm::Portuint` (expected () but found struct std::comm::Port) From this, I take it that for loops must return `()`, rather than an actual value. When I searched for a map function in the documentation, I only found a Map type. How would you map one vector to a vector of a different element type? Thanks, Leah -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How would you map one vector to a vector of a different element type?
You’re trying to move the ~strs out of the vector. You’ll need to use `move_iter`: ~~~ let ports = do myvect.move_iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(s)) } pport }.to_owned_vec(); ~~~ Also note the use of `to_owned_vec`. `map` lazily returns a `Map` iterator - you need to explicitly drain it. (Note I haven’t tried compiling this) ~Brendan On 3 Nov 2013, at 7:04 am, Leah Hanson astriea...@gmail.com wrote: Thanks, Scott, I think that's closer. However, now I'm having trouble with my pointer types. Using the element inside a spawn means that I need to capture the owned string in the right way so that the compiler allows me to give it to the other task. This version: ~~~ let ports = do myvect.iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ gives me pointer-type related errors: • error: cannot move out of dereference of pointer • cchan.send(fun(*s)) • error: cannot borrow immutable local variable as mutable • when I iterate over the Ports later • error: cannot capture variable of type `~str`, which does not fulfill `Send`, in a bounded closure • cchan.send(fun(*s)) I also tried a version with |s| and cchan.send(fun(s)), which gave me different errors: • error: cannot move out of captured outer variable in a heap closure • cchan.send(fun(*s)) • error: cannot move out of dereference of pointer • on the |s| • error: cannot borrow immutable local variable as mutable • when I iterate over the Ports later I'm very new to Rust. What do I need to do to let the compiler know that I'm not going to use anything in the first vec anymore? That I just want the ~str pointers directly? (I put the |s| outside the {} because putting it inside seemed to confuse things -- in that case, rustc expected an identifier instead of the `let` that comes next, so I assumed that `do v.iter().map {|s| ...}` is a syntax error.) Thanks, Leah On Sat, Nov 2, 2013 at 3:23 PM, Scott Lawrence byt...@gmail.com wrote: I would think: let ports = do myvect.iter().map { |e| something(e) } On Sat, 2 Nov 2013, Leah Hanson wrote: Hi, I have a ~[~str]. I have code that will turn a ~str into a Portuint. I want to end up with a [Portuint]. (or ~ or @ or whatever. I just want to be able to iterate over the Ports later.) Since I'm not sure what looping construct to use, I tried with a for-each loop. ~~~ let ports = for s in myvect.iter() { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ As you might, expect I got an error: error: mismatched types: expected `()` but found `std::comm::Portuint` (expected () but found struct std::comm::Port) From this, I take it that for loops must return `()`, rather than an actual value. When I searched for a map function in the documentation, I only found a Map type. How would you map one vector to a vector of a different element type? Thanks, Leah -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How would you map one vector to a vector of a different element type?
Thanks, Brendan. :) You’re trying to move the ~strs out of the vector. You’ll need to use `move_iter`: Is this moving about moving memory around or about promising the compiler that I won't use those elements of the vector again? ~~~ let ports = do myvect.move_iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(s)) } pport }.to_owned_vec(); There is still a problem because something (I guess the `do spawn {...}`) is a heap closure. - error: cannot move out of captured outer variable in a heap closure - cchan.send(fun(s)) I think that this error message is complaining because I'm trying to move s, the ~str that the `do spawn {...}` closes over, to a new task. And I'm not allowed to move it because it is apparently a heap closure. Is there some other kind of closure that does work here? Or some way to make this not a closure? Thanks, Leah On Sat, Nov 2, 2013 at 4:24 PM, Brendan Zabarauskas bjz...@yahoo.com.auwrote: You’re trying to move the ~strs out of the vector. You’ll need to use `move_iter`: ~~~ let ports = do myvect.move_iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(s)) } pport }.to_owned_vec(); ~~~ Also note the use of `to_owned_vec`. `map` lazily returns a `Map` iterator - you need to explicitly drain it. (Note I haven’t tried compiling this) ~Brendan On 3 Nov 2013, at 7:04 am, Leah Hanson astriea...@gmail.com wrote: Thanks, Scott, I think that's closer. However, now I'm having trouble with my pointer types. Using the element inside a spawn means that I need to capture the owned string in the right way so that the compiler allows me to give it to the other task. This version: ~~~ let ports = do myvect.iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ gives me pointer-type related errors: • error: cannot move out of dereference of pointer • cchan.send(fun(*s)) • error: cannot borrow immutable local variable as mutable • when I iterate over the Ports later • error: cannot capture variable of type `~str`, which does not fulfill `Send`, in a bounded closure • cchan.send(fun(*s)) I also tried a version with |s| and cchan.send(fun(s)), which gave me different errors: • error: cannot move out of captured outer variable in a heap closure • cchan.send(fun(*s)) • error: cannot move out of dereference of pointer • on the |s| • error: cannot borrow immutable local variable as mutable • when I iterate over the Ports later I'm very new to Rust. What do I need to do to let the compiler know that I'm not going to use anything in the first vec anymore? That I just want the ~str pointers directly? (I put the |s| outside the {} because putting it inside seemed to confuse things -- in that case, rustc expected an identifier instead of the `let` that comes next, so I assumed that `do v.iter().map {|s| ...}` is a syntax error.) Thanks, Leah On Sat, Nov 2, 2013 at 3:23 PM, Scott Lawrence byt...@gmail.com wrote: I would think: let ports = do myvect.iter().map { |e| something(e) } On Sat, 2 Nov 2013, Leah Hanson wrote: Hi, I have a ~[~str]. I have code that will turn a ~str into a Portuint. I want to end up with a [Portuint]. (or ~ or @ or whatever. I just want to be able to iterate over the Ports later.) Since I'm not sure what looping construct to use, I tried with a for-each loop. ~~~ let ports = for s in myvect.iter() { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ As you might, expect I got an error: error: mismatched types: expected `()` but found `std::comm::Portuint` (expected () but found struct std::comm::Port) From this, I take it that for loops must return `()`, rather than an actual value. When I searched for a map function in the documentation, I only found a Map type. How would you map one vector to a vector of a different element type? Thanks, Leah -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How would you map one vector to a vector of a different element type?
Instead of `do spawn` try `do spawn_with(s) |s| { ... }`. Then the closure won't close over s, but rather take it as an argument, allowing it to move it out. Cheers On Sat, Nov 2, 2013 at 5:05 PM, Leah Hanson astriea...@gmail.com wrote: Thanks, Brendan. :) You’re trying to move the ~strs out of the vector. You’ll need to use `move_iter`: Is this moving about moving memory around or about promising the compiler that I won't use those elements of the vector again? ~~~ let ports = do myvect.move_iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(s)) } pport }.to_owned_vec(); There is still a problem because something (I guess the `do spawn {...}`) is a heap closure. - error: cannot move out of captured outer variable in a heap closure - cchan.send(fun(s)) I think that this error message is complaining because I'm trying to move s, the ~str that the `do spawn {...}` closes over, to a new task. And I'm not allowed to move it because it is apparently a heap closure. Is there some other kind of closure that does work here? Or some way to make this not a closure? Thanks, Leah On Sat, Nov 2, 2013 at 4:24 PM, Brendan Zabarauskas bjz...@yahoo.com.auwrote: You’re trying to move the ~strs out of the vector. You’ll need to use `move_iter`: ~~~ let ports = do myvect.move_iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(s)) } pport }.to_owned_vec(); ~~~ Also note the use of `to_owned_vec`. `map` lazily returns a `Map` iterator - you need to explicitly drain it. (Note I haven’t tried compiling this) ~Brendan On 3 Nov 2013, at 7:04 am, Leah Hanson astriea...@gmail.com wrote: Thanks, Scott, I think that's closer. However, now I'm having trouble with my pointer types. Using the element inside a spawn means that I need to capture the owned string in the right way so that the compiler allows me to give it to the other task. This version: ~~~ let ports = do myvect.iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ gives me pointer-type related errors: • error: cannot move out of dereference of pointer • cchan.send(fun(*s)) • error: cannot borrow immutable local variable as mutable • when I iterate over the Ports later • error: cannot capture variable of type `~str`, which does not fulfill `Send`, in a bounded closure • cchan.send(fun(*s)) I also tried a version with |s| and cchan.send(fun(s)), which gave me different errors: • error: cannot move out of captured outer variable in a heap closure • cchan.send(fun(*s)) • error: cannot move out of dereference of pointer • on the |s| • error: cannot borrow immutable local variable as mutable • when I iterate over the Ports later I'm very new to Rust. What do I need to do to let the compiler know that I'm not going to use anything in the first vec anymore? That I just want the ~str pointers directly? (I put the |s| outside the {} because putting it inside seemed to confuse things -- in that case, rustc expected an identifier instead of the `let` that comes next, so I assumed that `do v.iter().map {|s| ...}` is a syntax error.) Thanks, Leah On Sat, Nov 2, 2013 at 3:23 PM, Scott Lawrence byt...@gmail.com wrote: I would think: let ports = do myvect.iter().map { |e| something(e) } On Sat, 2 Nov 2013, Leah Hanson wrote: Hi, I have a ~[~str]. I have code that will turn a ~str into a Portuint. I want to end up with a [Portuint]. (or ~ or @ or whatever. I just want to be able to iterate over the Ports later.) Since I'm not sure what looping construct to use, I tried with a for-each loop. ~~~ let ports = for s in myvect.iter() { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ As you might, expect I got an error: error: mismatched types: expected `()` but found `std::comm::Portuint` (expected () but found struct std::comm::Port) From this, I take it that for loops must return `()`, rather than an actual value. When I searched for a map function in the documentation, I only found a Map type. How would you map one vector to a vector of a different element type? Thanks, Leah -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list
Re: [rust-dev] How would you map one vector to a vector of a different element type?
Le 02/11/2013 21:05, Leah Hanson a écrit : Thanks, Brendan. :) You’re trying to move the ~strs out of the vector. You’ll need to use `move_iter`: Is this moving about moving memory around or about promising the compiler that I won't use those elements of the vector again? ~str is an owned string that can only have one owner. If you move it (give away ownership) you can not use it anymore. The compiler verifies that. This is why move_iter() consumes a vector (takes ownership), while iter() only gives you references ( pointers) to the elements. This allows the memory to be freed when the owner disappears, without garbage collection or reference counting. ~~~ let ports = do myvect.move_iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(s)) } pport }.to_owned_vec(); There is still a problem because something (I guess the `do spawn {...}`) is a heap closure. * error: cannot move out of captured outer variable in a heap closure o cchan.send(fun(s)) I think that this error message is complaining because I'm trying to move s, the ~str that the `do spawn {...}` closes over, to a new task. And I'm not allowed to move it because it is apparently a heap closure. Is there some other kind of closure that does work here? Or some way to make this not a closure? I’m not sure, but you may need to use spawn_with to move something into a task: do spawn_with(s) |s| { ... } -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Checking error at opening file
How to check an error at opening a file but without closing its file descriptor? use std::path; use std::rt::io; use std::rt::io::file; let filename = /some/path; let f = file::open(path::Path::new(filename), io::Open, io::Read); ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC about std::option and std::result API
On 11/02/2013 04:34 PM, Niko Matsakis wrote: I am generally in favor of this proposal. It seems to be a reasonable way forward. It is unclear to me how many types would benefit from this approach of having methods for each variant, but `Result` certainly does. With respect to possible confusion between `is_ok()` and `ok()` -- I think that the presence of a boolean return type should help with that. (That is, if you write `if foo.ok() { ... }` the compiler will catch it readily enough) That's my thinking too, we're not using a statically typed language for nothing after all. Some of the methods on `Result`, however, can't be implemented in terms of this approach. For example, `chain` and `chain_err` really need to keep the `Result` return type. But I guess that's clear enough. Right, `and` and `or` (which is what we call `chain` and `chain_err` these days) will still need to be implemented on `Result` directly, just like `map` and `map_err`. In fact, the only methods that would actually fall away on todays `Result` would be `expect`, `expect_err`, a lone `get_ref` and the iterator constructors. I'll send an mail containing a working patch in a follow up to this thread. One specific comment on your message: - There was talk about making `Result` use an `~Error` trait object instead of a generic type `E`, which could invalidate most of this email. However, this could also just mean that you usually will see `ResultT, ~Error` in the wild, for which this proposal still applies. Additionally, even if the Pattern becomes useless for Result, the problem still exists for any other newtype variant enums, so I'd like to see it get used anyway. It is not clear to me why moving to a `~Error` object would have any effect on this proposal. `err()` would just return `Option~Error` in that case, right? Well, that would still work, that much is true. However the `as_ref` and `as_mut_ref` adapters might pose some problems. Worst case we'll need to have `ok_ref`, `ok_mut`, `err_ref` and `err_mut` adapters instead, which would be unfortunate, but still better than duplicating all of `Option`s composable API across `Result`. Kimundi ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC about std::option and std::result API
I prepared a patch that renames everything as proposed with the exception of Option's unwrap - get change here: https://github.com/Kimundi/rust/commit/752912f75f6334da87a476fffc2475a3dfa5639d I touches ~ 300 lines, most of them being the unwrap - get and unwrap_err - err_get fallout. In fact, only a few singular places actually needed to call a `ok()`, `err()` or `as_ref` adapter at all, most just unwrapped or mapped. I discovered another issue though: Right now we require a ToStr bound on Results error type E. Ignoring for a moment that ToStr is on the way out, the idea behind that bound is that the unwrapping functions could provide a useful error message in the common unwrap an Err value case. Changing Result to use composition through as_ref() and ok() complicates that goal: - The first problem is that ok(self) - OptionT throws away the Error type, which means you'd be only ever be able to see the informative error message if you use the shorthand get() and err_get() methods, which leads to inconsistency. - The second, more interesting problem arises with as_ref. By turning ResultT, E into ResultT, E, we changed the self type so that now an ToStr bound on E is necessary. This could be solved by a generic ToStr impl of T for all T: ToStr, however that could decrease usability of ToStr, as users might now get seemingly random prefixes all over the place in their to_str() outputs. The good news is that those two issues might cancel each other out: If it gets decided that a composable, Option-API-leveraging interface is more important for Result than potentially more usable error messages in case of unwrapping an Err value, then we can just remove the ToStr bound and provide consistent, if generic, error messages. The patch above takes that approach for simplicity. Kimundi ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Checking error at opening file
This api is a little in flux (hopefully #10179 will land soon), but I'm not quite sure what you mean about keeping the file descriptor open. If there was an error opening the file, then a file descriptor was never allocated and there's nothing to keep open. Regardless, once my pull request lands, your example would look something like: use std::rt::io; use std::rt::io::File; match io::result(|| File::open(Path::new(/some/path)) { Ok(file) = { /* file was successfully opened, it existed */ } Err(e) = { /* file couldn't be opened, error contained in e */ } } On Sat, Nov 2, 2013 at 5:34 PM, John Mija jon...@proinbox.com wrote: How to check an error at opening a file but without closing its file descriptor? use std::path; use std::rt::io; use std::rt::io::file; let filename = /some/path; let f = file::open(path::Path::new(filename), io::Open, io::Read); ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev