These are chat archives for rust-lang/rust

9th
Apr 2018
Josh
@joshlemer
Apr 09 2018 00:42

Hey I was wondering how I can call a trait's impl for a specific type? Like if I want

Default::i32:default();

this is not correct obviously, but how could I specify "the Defaultimplementatin for i32's ::default() function"?

or my other guess was like Default<i32>::default()
Josh
@joshlemer
Apr 09 2018 00:49
actually my real world example is this

trait Monoid {
    fn zero() -> Self;
    fn combine(left: &Self, right: &Self) -> Self;
}

impl Monoid for i32 {
    fn zero() -> i32 {
        0
    }
    fn combine(left: &i32, right: &i32) -> i32 {
        left + right
    }
}

fn main() {
    println!("{}", <i32 as Monoid>::zero()); // doesn't compile
}
Josh
@joshlemer
Apr 09 2018 00:56
Woah weird, you're right, it just comes out horribly in intelliJ!
Selection_030.jpg

I have a question, is this the idiomatic way to encode typeclasses? or would you typically have a type parameter like

trait Monoid<T> {
  ...
}

?

Russell Cohen
@rcoh
Apr 09 2018 01:00
traits in Rust are typeclasses
(mostly)
You generally don't need the type parameter because you have access to the Self type
Josh
@joshlemer
Apr 09 2018 01:03
ok thanks
How do you typically encode multiple implementations of a typeclass?
like in different parts of the application you might want

impl Monoid for i32 {
    fn zero() -> i32 {
        0
    }
    fn combine(left: &i32, right: &i32) -> i32 {
        left + right
    }
}
impl Monoid for i32 {
    fn zero() -> i32 {
        1
    }
    fn combine(left: &i32, right: &i32) -> i32 {
        left * right
    }
}
but of course that doensn't work. Is there standard practice of wrapping things in a struct or something like that?
I could see it coming up also for multiple like implementations of JsonEncoding or similar things
Russell Cohen
@rcoh
Apr 09 2018 01:06
I think you would do something like
trait Add : Monoid {}
trait Multi : Monoid {}
impl Add for i32 { ... }
you could also do something like
trait Monoid<Action> {
}
impl Monoid<Action::Add> for i32 {
}
I'm not sure if one is more idiomatic
Josh
@joshlemer
Apr 09 2018 01:08
ohhh, ok for first example, you would still at call site specify Monoid but in your imports, you only import either Add or Multi?
and that's the selection, the import
dunno if that works (what I'm describing)
Russell Cohen
@rcoh
Apr 09 2018 01:12
ah no. You would explicitly accept a Monoid<Action::Add> as an argument
oh sorry you said for the first example
Josh
@joshlemer
Apr 09 2018 01:14
hmm I don't think what I described will work, probably
Russell Cohen
@rcoh
Apr 09 2018 01:17
A third option is something like:
struct Addable<T> {
   x: T
}
and wrap you're i32s in addable if you wanted them to add
impl Monoid for Addable<i32> {
    ...
}
Josh
@joshlemer
Apr 09 2018 01:27
Right
Restioson
@Restioson
Apr 09 2018 10:19
@joshlemer wouldn't the zero fn make more sense as identity?
in that particular case
I'm trying out criterion, yet I can't get it to find my function. I have examples/foo.rs which calls a function (public) from crate::mod, yet it complains that it cant be found. Adding an extern crate also doesn't work
Dylan DPC
@Dylan-DPC
Apr 09 2018 10:28
@Restioson can you share some code?
Restioson
@Restioson
Apr 09 2018 10:36
@Dylan-DPC sure
#[macro_use]
extern crate criterion;
//extern crate buddy_allocator_workshop;

use criterion::Criterion;
use buddy_allocator_workshop::buddy_allocator_tree;

fn rb_tree_vecs(c: &mut Criterion) {
    let mut allocator = buddy_allocator_tree::BuddyAllocator::<Vec<*const Block>>::new();
    allocator.create_top_level(0);

    c.bench_function(
        "rb_tree_vecs 10 blocks",
        |b| b.iter(|| allocator.allocate_exact(block_size).unwrap())
    );
}

criterion_group!(benches, rb_tree_vecs);
criterion_main!(benches);
examples/bench.rs
Dylan DPC
@Dylan-DPC
Apr 09 2018 10:36
looks fine to me
Restioson
@Restioson
Apr 09 2018 10:36
error[E0432]: unresolved import `buddy_allocator_tree`
 --> benches\rb_tree.rs:6:5
  |
6 | use buddy_allocator_tree;
  |     ^^^^^^^^^^^^^^^^^^^^ no `buddy_allocator_tree` in the root
Dylan DPC
@Dylan-DPC
Apr 09 2018 10:37
what is buddy_allocator_tree?
Restioson
@Restioson
Apr 09 2018 10:37
trying to import from here
image.png
Dylan DPC
@Dylan-DPC
Apr 09 2018 10:37
do you have a mod buddy_allocator_tree; in your code?
Restioson
@Restioson
Apr 09 2018 10:37
in main.rs
pub mod buddy_allocator_tree;
Dylan DPC
@Dylan-DPC
Apr 09 2018 10:38
so why are you doing use buddy_allocator_workshop::buddy_allocator_tree; then?
Restioson
@Restioson
Apr 09 2018 10:38
:think:
so, is it namespaced under the crate root then?
not above?
error[E0432]: unresolved import `buddy_allocator_tree`
 --> benches\rb_tree.rs:6:5
  |
6 | use buddy_allocator_tree;
  |     ^^^^^^^^^^^^^^^^^^^^ no `buddy_allocator_tree` in the root
still doesn't work...
I tried adding extern crate buddy_allocator_workshop; yet complains that it can't find crate
i added a cargo.toml with [dependencies.buddy_allocator_workshop] path = "../"
also no beans
Restioson
@Restioson
Apr 09 2018 11:19
Anyone know?
Boris-Chengbiao Zhou
@Bobo1239
Apr 09 2018 11:24
just use buddy_allocator_tree;?
Restioson
@Restioson
Apr 09 2018 11:37
Doesn't work
See above the error
Boris-Chengbiao Zhou
@Bobo1239
Apr 09 2018 11:39
i'm blind...; you're in benches so you'll need an extern crate <your_crate_name>; and use <your_crate_name>::buddy_allocator_tree;
Dylan DPC
@Dylan-DPC
Apr 09 2018 11:55
oh ya didn't consider that :D
Restioson
@Restioson
Apr 09 2018 12:29
I tried that a while ago, still doesn't work
:l
error[E0463]: can't find crate for `buddy_allocator_workshop`
 --> benches\rb_tree.rs:3:1
  |
3 | extern crate buddy_allocator_workshop;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
@Bobo1239
Denis Lisov
@tanriol
Apr 09 2018 12:34
Do you have lib.rs?
Restioson
@Restioson
Apr 09 2018 12:34
No, I'm trying to benchmark a binary
Do I need a lib.rs and a main.rs??
Denis Lisov
@tanriol
Apr 09 2018 12:35
Looks like that.
Restioson
@Restioson
Apr 09 2018 12:35
Will cargo get confused though?
like, which is the crate root?
Denis Lisov
@tanriol
Apr 09 2018 12:35
You may have to specify explicitly which one you want to build.
I'd probably use a library crate and a binary that uses it for prototyping some library-like functionality.
Restioson
@Restioson
Apr 09 2018 12:37
well
I just created a blank lib.rs and it's fine now
Michal 'vorner' Vaner
@vorner
Apr 09 2018 12:38
Having both main.rs and lib.rs is quite common. It builds the binary and the library is considered to be its dependency. This is done to allow integration tests (so you can do extern crate my_crate in them). The main.rs is usually just a wrapper and all the functionality is in lib.rs.
Restioson
@Restioson
Apr 09 2018 12:39
oh, here it appears to be the other way
idk i'll see
Michal 'vorner' Vaner
@vorner
Apr 09 2018 12:39
Benchmarks are likely to be very similar to the integration tests
Restioson
@Restioson
Apr 09 2018 12:39
@vorner btw interesting blogpost
Michal 'vorner' Vaner
@vorner
Apr 09 2018 12:39
The lib can't really pull anything from the binary.
Oh, that blog post didn't really go as expected :-|. Seems like many people read something very different than what I thought I wrote.
Restioson
@Restioson
Apr 09 2018 12:40
huh
I agreed mostly
Songbird0
@Songbird0
Apr 09 2018 12:47

Hi there,

I would like to write a plugin-based system. Does someone have a bunch of plugin-based system implementations written in Rust (respositories or anything else)?
I just need of example.

Restioson
@Restioson
Apr 09 2018 12:48
so, like, plugins?
dynamically loaded
Songbird0
@Songbird0
Apr 09 2018 12:48
Yes
Restioson
@Restioson
Apr 09 2018 12:49
Might look into dll/so loading crates
Songbird0
@Songbird0
Apr 09 2018 12:49
Ok, I'll look over here, thanks!
Have you a name for .so loading crate(s)?
Denis Lisov
@tanriol
Apr 09 2018 12:59
libloading
Songbird0
@Songbird0
Apr 09 2018 13:00
Pretty intuitive, huh. Thanks @tanriol!
Sebastian Blei
@iamsebastian
Apr 09 2018 15:11

Erm ... How can I access the value of the match at _? I do not get it ... *grml

match age.parse().unwrap_or(-1) {
  // Bigger than 126 is an invalid age.
  invalid if invalid > 126 => -1,
  _ => value?
}

Thought about something like e if _ =>, but that's not correct.

Denis
@mexus
Apr 09 2018 15:26
just give it a name instead of an underscore :)
like value => value?,
well probably you don't want a question mark there
Dylan DPC
@Dylan-DPC
Apr 09 2018 15:30
why do you need it as _ then :P
Sebastian Blei
@iamsebastian
Apr 09 2018 15:38
@mexus Oh my ... tomatoes on the eyes. Thanks. Time to knock off.
Songbird0
@Songbird0
Apr 09 2018 15:41
@iamsebastian That's ok. We didn't see anything. :p
Sebastian Blei
@iamsebastian
Apr 09 2018 15:42
:smile: :clap:
Bryan Burgers
@bryanburgers
Apr 09 2018 16:28
Im trying to call libc::msgrcv which has as a parameter a msgp: *mut c_void. How do I call this so that I can get the result out?
According to man, that is a pointer to
struct msgbuf {
       long mtype;       /* message type, must be > 0 */
       char mtext[1];    /* message data */
};
And to be honest, I’m not even sure what type to make mtext in the strict I’m trying to create.
Bryan Burgers
@bryanburgers
Apr 09 2018 16:34
struct MsgBuf {
  mtype: libc::c_long,
  mtext: ?
}

unsafe {
  let r = libc::msgrcv(id, ???, 2048, 1, 0o4000);
}
Ingvar Stepanyan
@RReverser
Apr 09 2018 17:50
First example found on google basically says that this structure is dynamically sized according to the text you want to fit http://www.cs.kent.edu/~ruttan/sysprog/lectures/shmem/msqueues.html
Since there's no easy way to allocate such structure in Rust (not just define), you'll need to define own structure like msgbuf but with fixed-size buffer in place of mtext
Like, array of 1024 bytes or something (as much as you actually want to receive)
Then you can either create a placeholder value directly on stack or in the heap, and pass mutable pointer to it to the msgrcv
Serhii Plyhun
@snuk182
Apr 09 2018 17:59

Hi all, need a help from someone with macos cocoa experience
https://github.com/snuk182/crash_on_llvm6 (a NSApplication with attached delegate, implemented with Rust)
this code runs perfectly at fresh stable and nighties till 2018-03-16. starting from 2018-03-16 and on it crashes with fatal runtime error: allocator memory exhausted
the question is - is this something related to the nightly bug or I'm doing something wrong at building Cocoa application?

The reason is bang type stabilization tomaka/winit#428

Ingvar Stepanyan
@RReverser
Apr 09 2018 18:00
@bryanburgers This is what your example would look like then:
extern crate libc;

use std::mem;

struct MsgBuf {
    mtype: libc::c_long,
    mtext: [u8; 2048],
}

// ...
unsafe {
    let mut buf: MsgBuf = mem::uninitialized();
    let r = libc::msgrcv(id, &mut buf as *mut _ as _, mem::size_of_val(&buf.mtext), 1, 0o4000);
    // ...
};
Bryan Burgers
@bryanburgers
Apr 09 2018 18:06
Ah, perfect. I tried to do various &mut buf as ... things, and kept getting slapped by the compiler.
I still don't understand &mut buf as *mut _ as _, though. Two as?
Ingvar Stepanyan
@RReverser
Apr 09 2018 18:08
Yeah, dark magic which is unfortunately somewhat common when dealing with FFI (others write it differently, but I kind of got used to this as the most concise way)
&mut buf -> *mut _ says "convert mutable reference to my type to a mutable pointer (automatically of the same type), and second as _ says convert my mutable pointer to whatever target type is (that is, *mut void)
You can't convert mutable reference to incompatible pointer type directly, but you can convert one pointer to other pointer, hence two as
Bryan Burgers
@bryanburgers
Apr 09 2018 18:19
Thanks, @RReverser. I got it to work. Well, after I fixed the other problem with FFI: I had two libc functions that return an i32 as a handleish-thing, and I was passing the wrong one to msgrcv.
And that makes more sense.
Russell Cohen
@rcoh
Apr 09 2018 19:28
It's impossible to do multi-level matching with match in Rust, right? eg. In Scala you can do:
myType match {
   case MyType(NestedType(a, b, c), AnotherType(d)) => ...
}
But if that's available in Rust, I haven't seen it. I think you need another match?
match my_type {
   MyType(a, b) => match a {
      NestedType(c, d, e) => ...
   }
}
Is that correct, or am I missing something?
Russell Cohen
@rcoh
Apr 09 2018 19:34
boom! I'm glad I asked :-)