These are chat archives for rust-lang/rust

2nd
Jul 2018
Zakarum
@omni-viral
Jul 02 2018 09:55

entry but takes impl ToOwned<T>

@portstrom I didn't see one. But I think this is a good idea for optimization with clonable keys (like strings)

Fredrik Portström
@portstrom
Jul 02 2018 09:58
@omni-viral Thanks for telling. Maybe I should write an experimental implementation when I get the opportunity.
Zakarum
@omni-viral
Jul 02 2018 09:59
You could start with discussion on https://internals.rust-lang.org
Or somewhere around
Denis Lisov
@tanriol
Jul 02 2018 10:26
@portstrom Have you seen rust-lang/rfcs#1769?
Fredrik Portström
@portstrom
Jul 02 2018 10:39
@tanriol I hadn't. Now I have. It's a really interesting proposal. Too bad they couldn't solve the last issues and merge it.
Zakarum
@omni-viral
Jul 02 2018 12:34
Is there good reason why I can impl ExtenTrait<LocalType> for ExternType
while can't impl ExternTrait for ExternType<LocalType>?
For second one I get "impl doesn't use types inside crate"
while it obviously use
I see that this is intent behaviour according to orphan rules.
  • the type that is implementing the trait is foreign
  • all of the parameters being passed to the trait (if there are any) are also foreign.
But why parameters passed to the type implementing the trait don't count?
Ingvar Stepanyan
@RReverser
Jul 02 2018 13:29
Probably because original crate can implement impl<T> ExternTrait for ExternType<T> and you'll get conflicts (basically same reason as with parameter-less version of ExternType)
Zakarum
@omni-viral
Jul 02 2018 13:30
It can implement impl<T, U> ExternTrait<T> for U and I will get same conflicts with allowed variant
Ingvar Stepanyan
@RReverser
Jul 02 2018 13:34
Indeed, I always found this motivation weak for the same reason.
But AFAIK that's the official rules.
Zakarum
@omni-viral
Jul 02 2018 13:35
I guess that the crate that expose ExternTrait can see from the rules if change will break something.
e.g. adding impl<T> ExternTrait for ExternType<T> shouldn't be breaking change.
while adding impl<T, U> ExternTrait<T> for U is breaking change and requires major version bump
Sylwester Rąpała
@xoac
Jul 02 2018 14:15
is () marked Send?
Zakarum
@omni-viral
Jul 02 2018 15:03
Should be
tsoernes
@tsoernes
Jul 02 2018 15:06
Any helpful 'rules' for when to pass a reference of a struct vs. defining the struct with reference fields?
In the former option, fields are consumed when creating the struct thus making it impractical to use as an approach to clustering/gathering function arguments
In the latter option that problem is avoided although function signatures become 'misleadning', as an actual struct is passed which contains only references
Ingvar Stepanyan
@RReverser
Jul 02 2018 15:14
It really depends on whether logically that struct owns the data or just references it. There is no rule for "all the fields should be like this".
Basically "do you want this data to be dropped/lost when that struct disappears or should it be just referenced from the struct but live independently".
Kelly Thomas Kline
@kellytk
Jul 02 2018 15:17
Can VS Code Rust-specific settings be automatically generated which conform to the official Rust style guide?
Ingvar Stepanyan
@RReverser
Jul 02 2018 15:19
Do you mean indentation or something else?
Kelly Thomas Kline
@kellytk
Jul 02 2018 15:33
Yes things like indentation
Ingvar Stepanyan
@RReverser
Jul 02 2018 15:58
If it's just indentation (I can't think of anything else related to style in vscode config), you can set it once globally in your own settings.
Put "[rust]": { ... } in your VSCode settings and override anything you want inside of it.
Maik Klein
@MaikKlein
Jul 02 2018 16:25
Does anyone know why libc::c_void is an enum and not ()? https://rust-lang.github.io/libc/x86_64-unknown-linux-gnu/libc/enum.c_void.html
Okay it is explained in the source code
    // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
    // more optimization opportunities around it recognizing things like
    // malloc/free.
tsoernes
@tsoernes
Jul 02 2018 16:31
I'm unsure how to handle lifetimes in this for-loop. Perhaps State, which is just a logical and convenient struct for grouping arguments, should be have fields with references??
let env = Env::new();
let frep = f(&env.grid);
let event = env.next();
state = State {
    grid: env.grid.clone(),
    frep: frep,
    event: event.clone(),
};
action = agent.get_action(state);
for t in 0..K {
    // This transitions env.grid_{t} to env.grid_{t+1}. 
    let (reward, next_event) = env.step(event, action);
    next_state = State {
        grid: env.grid,
        frep: f(&env.grid),
        event: next_event.clone(),
    };
    // 'update' does not need to consume any arguments, but must have
    // access to state before `step` was executed.
    agent.update(state, action, reward, next_state);
    // Want 'state' and everything in it do die/drop here

    // 'get_action' does not need to consume 'next_state'
    action = agent.get_action(next_state);
    event = next_event;
    state = next_state;
}
Steve Loveless
@turboladen
Jul 02 2018 17:37
Hi all… I’m doing some wasm-bindgen and haven’t been able to determine if it’s possible to define a method in Rust that can accept any JS type—can anyone confirm one way or the other? Really I just want to accept a String or my own struct, so I tried using an enum, but the compiler nicely told me that’s not possible. TIA
It shows examples of using JsValue for accepting, well, any JS value.
Steve Loveless
@turboladen
Jul 02 2018 17:43
I did.
I couldn’t see a way to get to the inner value from that
it seems like i need acces to the JsValue’s index (or whatever that inner field is), but it’s private
Steve Loveless
@turboladen
Jul 02 2018 17:50
I can call as_string() on the JsValue param to fetch if it’s a string, but don’t know how to get at the data if it’s my own struct.
Ingvar Stepanyan
@RReverser
Jul 02 2018 17:51
Oh, I see, you want to convert it to Rust type after you received it? I believe you'd have to use FromWasmAbi manually for that, but never tried it.
You might be better off exposing two separate strongly typed methods and choosing between them in a JS wrapper.
ousado
@ousado
Jul 02 2018 17:54
@turboladen if you absolutely have to do that, it's simpler to do on the JS side
Steve Loveless
@turboladen
Jul 02 2018 17:55
aha ok. @RReverser i sorta gave that a go but wasn’t quite sure what i was doing.
ousado
@ousado
Jul 02 2018 17:56
but if you have the choice, then just don't
Steve Loveless
@turboladen
Jul 02 2018 17:56
@ousado ok yeah, i was using stdweb before wasm-bindgen and was able to use its macro for handing this in JS. it seems like to do this in JS, i’d have to manually edit the wasm-bindgen-generated JS, which isn’t really ideal. …unless i’m missing something
i’m wrapping a rust library in wasm so our frontend devs can use the wrapper; they’re the ones asking for a single constructor method, so i’m just trying to appease

You might be better off exposing two separate strongly typed methods and choosing between them in a JS wrapper.

yeah that’s what i’m doing now and the frontend guys aren’t really into it

ousado
@ousado
Jul 02 2018 17:59
it's pretty sad how pervasive this is in the JS world
Steve Loveless
@turboladen
Jul 02 2018 17:59
yeah, it feels kinda icky
Ingvar Stepanyan
@RReverser
Jul 02 2018 18:09
On the other hand, I really wish Rust would support disjoint unions without explicitly named variants (which would help here too).
Steve Loveless
@turboladen
Jul 02 2018 18:10
fwiw, @RReverser if I try implementing FromWasmAbi, the compiler tells me it’s a duplicate definition. When I print out the wasm-bindgen macro generated stuff, i see that it’s already generated an impl of that. The first param is js: u32, which I’m guessing is the index of the JsValue (?), but i’m not sure how to get that value
Ingvar Stepanyan
@RReverser
Jul 02 2018 18:13
Oh I didn't mean to try to implement it, but rather call its method.
So if you know the type of the value, you can use it to convert from JsValue to your struct.
Steve Loveless
@turboladen
Jul 02 2018 18:13
aah gotcha. trying that now!
Ingvar Stepanyan
@RReverser
Jul 02 2018 18:13
And to get the index (although not sure if it helps) you can correspondingly use IntoWasmAbi on JsValue.
Steve Loveless
@turboladen
Jul 02 2018 18:14
ah ok. yeah i think i read the FromWasmAbi code incorrectly
Steve Loveless
@turboladen
Jul 02 2018 18:38
@RReverser i feel like i’m getting there… it looks like i need to pass in a GlobalStack to from_abi, but i’m not totally sure where i get that from—do you know? It seems like there’s some global one around, but i’m not sure what that is
Ingvar Stepanyan
@RReverser
Jul 02 2018 18:39
I'm not sure either... Maybe you can just implemented FromWasmAbi on your enum and then just pass arguments down to the variant?
Seems like it would be easier.
(As then you would already have the stack passed to you.)
Steve Loveless
@turboladen
Jul 02 2018 18:41
aah i think that makes sense. i’ll give that a go. thanks for lending your brain :)
Ingvar Stepanyan
@RReverser
Jul 02 2018 18:44
Haha, no worries.
Ingvar Stepanyan
@RReverser
Jul 02 2018 19:36
@turboladen How is it going? FWIW I just tried this approach locally myself and it seems to work (although not too straightforward indeed).
Joseph Lenton
@joe-askattest
Jul 02 2018 19:39
Hey, I'm trying to pass an Option<String> into an Option<&str>. The compiler is not happy with this idea. Is there a short way to get this to work?
i.e. foo( maybe_string.map(String::as_ref) ) (which I tried and couldn't get working).
I could deconstruct it and call the function twice; once with the string and once when it's none. I'm looking for a short and sweet answer however.
Ingvar Stepanyan
@RReverser
Jul 02 2018 19:41
You need .as_ref() first to convert &Option<String> to Option<&String> and then .map(String::as_ref) will work as expected
(or String::as_str which is the same)
Joseph Lenton
@joe-askattest
Jul 02 2018 19:42
Thanks, I'll try that.
It works! Thanks very much.
Steve Loveless
@turboladen
Jul 02 2018 20:30
@RReverser just got back from lunch. at it again. still figuring out how to implement IntoWasmAbi for my enum
this seems like something that’ll eventually be baked in to wasm-bindgen (fingers crossed at least that it does), so i’m hopeful that if i do figure this out that it won’t have to live super long
any chance you could post a gist/play of your local implementation?
Fredrik Portström
@portstrom
Jul 02 2018 22:49
@turboladen Wouldn't it be simplest to write your own JS module that goes in front of the bindgen generated module? This module can detect the type (horrible thought of weak typing) and then delegate it to the correct strongly typed function.
tsoernes
@tsoernes
Jul 02 2018 23:21
Maybe I'm going about this problem the wrong way:
pub trait Agent {
    fn new<A: Agent>(alpha: f64) -> A;
    ..
}

struct SomeAgent {
    alpha: f64,
}

impl Agent for SomeAgent {
    fn new<SomeAgent>(alpha: f64) -> SomeAgent {
        SomeAgent {
            alpha: alpha,
        }
    }
    ...
}
I want the trait to have a generic method of instantiating structs which implement the trait (the new method)
But I can't get the implementation to compile
Steve Loveless
@turboladen
Jul 02 2018 23:48
@portstrom when i was using stdweb instead of wasm-bindgen, i had this, which worked just fine—is this what you’re talking about in concept?
js! {
    window.Unit = class Unit {
        constructor(stringOrUnit) {
            if (typeof stringOrUnit === "string" || stringOrUnit instanceof String) {
                this._internal = @{new_unit}(stringOrUnit);
            } else {
                this._internal = stringOrUnit;
            }
        }
tsoernes
@tsoernes
Jul 02 2018 23:55
Another question: Is it possible to instantiate a default value here?
pub fn argpmax1<N: Ord, Default>(arr: &Array1<N>) -> (usize, N) {
    // no function or associated item named `default` found for type `Default`
    // in the current scope (function or associated item not found in `Default`) (rust-cargo)
    // items from traits can only be used if the trait is implemented and in scope (rust-cargo)
    let def: N = Default::default();
    arr.indexed_iter().fold(
        (0, def),
        |(amax, max), (idx, &elem)| {
            if elem > max {
                (idx, elem)
            } else {
                (amax, max)
            }
        },
    )
}