These are chat archives for rust-lang/rust

15th
Jun 2018
A Dinesh
@dineshadepu
Jun 15 2018 05:46
I am actually trying to get the mutable references of a struct. Now say I pass a struct to spring force which has several variables, I should be able to access them individually through components to run my algorithm. As in the example, Foo has x,y attributes, but Bar has x,y, r. So when I call for get_mut_parts function I should get the struct but with mutable references to the attributes.
Is this possible?
@dpogretskiy
B
Dmitriy
@dpogretskiy
Jun 15 2018 05:58
It does precisely what you say, it's just not enough for spring_force to function that way, since full info is not there
You can be more specific anywhere really and get what you want, you probably want to differentiate r as it's not in Bar, but can be in Foo
A Dinesh
@dineshadepu
Jun 15 2018 06:04
Here is an implementation with a single generic, where I have implement different traits on different structs to get mutable references. Here I have Base trait on DemDiscrete struct which gives me immutable references.
Now I am generalising it to many structs. Thats where I am stuck. Rust doesn't allow mutable mutable borrows of a struct.
@dpogretskiy This is cool
Dmitriy
@dpogretskiy
Jun 15 2018 06:07
you need to find a struct that allows you to do algorithm, but let it be concrete, logic is fine, it's just that trait dependent types have no info on what the type is.
hence it's abstract type, you can only do abstract things with it
like return it from functions, not more then that.
also you can tell that you want a lambda, that is Fn(T) -> u32 for example,
A Dinesh
@dineshadepu
Jun 15 2018 06:09
I think I will go with the final implementation you gave me @dpogretskiy . Or should I consider some other kind of structs to do this.
Dmitriy
@dpogretskiy
Jun 15 2018 06:11
not really, just as abstraction goes, you need to describe what your types have in common
not the mere fact they could be different :smile:
there are some ways, to do same thing, but they are not a lot better, not terribly worse :laughing:
A Dinesh
@dineshadepu
Jun 15 2018 06:14
Ok. I will go with the final implementation then. Thank you @dpogretskiy
Dmitriy
@dpogretskiy
Jun 15 2018 06:15

trait GetMut<'a> {
    // What to return here so that the get_mut_parts function works for any struct
    fn x_mut(&'a mut self) -> &'a mut Vec<f32>
    fn y_mut(&'a mut self) -> &'a mut Vec<f32>
    fn r_mut_opt(&'a mut self) -> Option<&'a mut Vec<f32>>
}
this would also work, but same thing really
A Dinesh
@dineshadepu
Jun 15 2018 06:15
But this makes me to write too much get_x functions
Dmitriy
@dpogretskiy
Jun 15 2018 06:15
exactly
A Dinesh
@dineshadepu
Jun 15 2018 06:15
I have to read around 20 variables in every function
so that would be bad
That made me to do the current version
Dmitriy
@dpogretskiy
Jun 15 2018 06:16
it can be a good thing, classical expression problem
trsh
@trsh
Jun 15 2018 07:34
can I somehave set a value for Struct, Once.. then lock it, so Rust doesn't cry anymore about mutability stuff, when I barrow it?
Or at least when creating it. Sometimes I perfectly know, that particular Struct value will be read-only, so there is no need to cry about mutability when I barrow it.
Dmitriy
@dpogretskiy
Jun 15 2018 08:16
    fn add2(&self){
        // However, if x is read only I can't modify it here, so no problem
    }
like this?
trsh
@trsh
Jun 15 2018 08:21
@dpogretskiy but let' say you want to edit y in add2?
What is not read only
I know one solution is to use Cell
Fredrik Portström
@portstrom
Jun 15 2018 08:24
&self.x borrows just the field x, but self.add2() borrows the entire struct, because it takes &mut self. I had this problem as well. I think you have to make functions that just take references to individual fields, not the entire struct.
trsh
@trsh
Jun 15 2018 08:25
But cell can't be used only with Values, and RefCell will allow to compile, but then panick in runtime
Sylwester Rąpała
@xoac
Jun 15 2018 08:26
this syntax would be funny fn add2(&mut self.y)
trsh
@trsh
Jun 15 2018 08:27
this also const x: i32
The example Is maybe not the best! I will edit to show the problem at very glance
trsh
@trsh
Jun 15 2018 08:35
Or not
:D
At some level it does
Fredrik Portström
@portstrom
Jun 15 2018 08:47
@trsh The mutating functions cannot take self at all. Your add2 function needs to take _y as &mut i32, not i32.
trsh
@trsh
Jun 15 2018 08:53
mkay
tnx @zolkko @portstrom
Devashish Dixit
@devashishdxt
Jun 15 2018 09:00
Hi, I'm exploring mio-extras timer and I'm not able to understand what tick_duration, num_slots and capacity mean in the documentation. https://docs.rs/mio-extras/2.0.4/mio_extras/timer/struct.Builder.html
there you go, good read btw :smile:
same thing as tokio one, i believe.
trsh
@trsh
Jun 15 2018 09:16
basically only way to provide read-only context is to pass it trough fn's
thats kind of sad
Tried to use RefCell, but that fails big time on recursions
Dmitriy
@dpogretskiy
Jun 15 2018 09:17
it depends on if your code should tell what it does, or not :laughing:
trsh
@trsh
Jun 15 2018 09:17
And don't like, as no compile errors, but later panics
Fredrik Portström
@portstrom
Jun 15 2018 09:18
RefCell also has runtime overhead and failures that are not caught by the compiler.
Dmitriy
@dpogretskiy
Jun 15 2018 09:18
that's what RefCell does
trsh
@trsh
Jun 15 2018 09:18
You have to be very shure, that codes is structured right
Dmitriy
@dpogretskiy
Jun 15 2018 09:18
with great power, comes great responsibility :smirk:
samoylovfp
@samoylovfp_gitlab
Jun 15 2018 09:36
Hello! Do I understand correctly, that pub(self) is equal to <no visible indicator>?
https://play.rust-lang.org/?gist=a8824c94bb3b3b6991513a99d91c8678&version=stable&mode=debug
Are there items for which these result in different visibility?
trsh
@trsh
Jun 15 2018 09:51
@xoac fn add2(&mut self.y) this actually would be awesome
I might sumbit a FR
Fredrik Portström
@portstrom
Jun 15 2018 09:54
@trsh That raises the question how that would work with public functions where the borrowed fields are private.
trsh
@trsh
Jun 15 2018 09:58
@portstrom only thing that changes is that inside such function you can only work with y
From self
Fredrik Portström
@portstrom
Jun 15 2018 10:00
That doesn't make sense in a public interface if y is private.
trsh
@trsh
Jun 15 2018 10:00
maybe can extend to (&mut self.x, &mut.self.y)
@portstrom but public interface has no idea of that, just like of self.. you call interface.add2()
Fredrik Portström
@portstrom
Jun 15 2018 10:02
The public interface must know what to borrow.
trsh
@trsh
Jun 15 2018 10:03
Why?
interface.x.add2()~thats what u want?
Fredrik Portström
@portstrom
Jun 15 2018 10:05
If x is private that still doesn't make sense.
trsh
@trsh
Jun 15 2018 10:07
@portstrom so when u call interface.add2(), you also have no idea of private fields what will be used inside it
Fredrik Portström
@portstrom
Jun 15 2018 10:07
You have an idea because of the signature of the function.
trsh
@trsh
Jun 15 2018 10:08
U don't see private fields, so no idea
Fredrik Portström
@portstrom
Jun 15 2018 10:08
If you have no idea of the signature, you can't use it.
trsh
@trsh
Jun 15 2018 10:09
public function has no business of private fields in interface.. that works right now like that
Dont get your point
Denis Lisov
@tanriol
Jun 15 2018 10:14
@trsh Looks like you want to split the external interface (which does not deal with private fields directly) and the actual underlying implementation...
trsh
@trsh
Jun 15 2018 10:15
@tanriol and..
@tanriol here is the problem > https://play.rust-lang.org/?gist=7b660632792e149bbc6c2b6b93fcc5ce&version=stable&mode=debug . And the solutions guys provides actually are more like workarounds (moving out of struct and pushing every needed data as param, using scope annotations {}, what is irrelevant for recursions, etc)
trsh
@trsh
Jun 15 2018 10:20
I believe it will be not an problem with nll
Denis Lisov
@tanriol
Jun 15 2018 10:21
...so that the external one uses just &mut self (as the external users don't know about the private fields), while the underlying implementation uses references to fields.
It will still be a problem with NLL.
Denis Lisov
@tanriol
Jun 15 2018 10:22
Like this
trsh
@trsh
Jun 15 2018 10:23
Im lossing you
You Just posted my first problem example.. can't see how it fits in context
Denis Lisov
@tanriol
Jun 15 2018 10:30
What NLL helps you with in your is that if you don't actually use the same reference both before and after the call, it allows you to stop the borrow early. However, if you do really need to keep the reference over the call, NLL is of no help.
Devashish Dixit
@devashishdxt
Jun 15 2018 10:31
@dpogretskiy Thanks for the paper :smile:
trsh
@trsh
Jun 15 2018 10:32
@tanriol well as u can see in playground it solved my problem
Denis Lisov
@tanriol
Jun 15 2018 10:34
...a reduced version of your problem, I guess. By the way, the same can be done without NLL by limiting the block before the call like this.
trsh
@trsh
Jun 15 2018 10:37
@tanriol now imagine recursions.. where you need to alter same val
I will create some better ex
This can be tricked in million ways
Miguel Duarte
@malduarte
Jun 15 2018 13:30
PartialEq is implemented for function pointers in form of fn(Args...) -> Ret doesn't seem to work either
        let f1 :  fn(&str, &str, &Vec<usize>) -> Result<String, String> = cipher_original;
        let f2 :  fn(&str, &str, &Vec<usize>) -> Result<String, String> = cipher_original;

        assert_eq!(f1, f2);
this fails to compile with
= note: an implementation of `std::cmp::PartialEq` might be missing for `for<'r, 's, 't0> fn(&'r str, &'s str, &'t0 std::vec::Vec<usize>) -> std::result::Result<std::string::String, std::string::String>
Miguel Duarte
@malduarte
Jun 15 2018 13:36
So... maybe I'm missing something obvious
but I can't find an easy way to assert that two function references match
this works fine though
fn add1(v : usize) -> usize {
    v + 1
}

// test block
        let f1 :  fn(v : usize) -> usize  = add1;
        let f2 :  fn(v : usize) -> usize  = add1;

        assert_eq!(f1, f2);
Miguel Duarte
@malduarte
Jun 15 2018 13:41
so maybe the issue is not really comparing function references
but maybe the parameter types are breaking this somehow
any clues?
Zakarum
@omni-viral
Jun 15 2018 13:42
Try to remove for<'r, 's, 't0> from function pointer
Miguel Duarte
@malduarte
Jun 15 2018 13:43
I can't remove something that isn't there
Zakarum
@omni-viral
Jun 15 2018 13:43
Right now you actually have
let f1 : for<'r, 's, 't0> fn(&'r str, &'s str, &'t0 Vec<usize>)
But for<> is implicit
You should add explicit lifetimes to function arguments
Miguel Duarte
@malduarte
Jun 15 2018 13:44
honest question : why should the lifetime of the function parameters make a difference on the function reference?
should be the same memory address
Zakarum
@omni-viral
Jun 15 2018 13:45
It makes no difference. Except that PartialEq is implemented for fn(Args...) -> Ret and not for for<'r, 's, 't0> fn(Args...) -> Ret
Devashish Dixit
@devashishdxt
Jun 15 2018 13:45
For me, It works if I take owned values in arguments but breaks if I take references.
Miguel Duarte
@malduarte
Jun 15 2018 13:46
Ah!
Zakarum
@omni-viral
Jun 15 2018 13:47
The thing is rustc treats &'a T and for<'a> &'a T and &'b T as completely different types due typechecking
And it is implessible to implemet anything for for<lifetimes> fn(arguments that can depends on lifetimes) -> Return type that can depend on lifetimes in generic way.
Because you can't even write for<lifetimes> fn(arguments that can depends on lifetimes) -> Return type that can depend on lifetimes in Rust in generic way
A Dinesh
@dineshadepu
Jun 15 2018 13:56
Hello all, I am writing a simple space partition (uniform grid) for my simulation of N-body problem. As one has to check for 9 neighbouring cells, and do the same operation, I have got a lot of boiler plate code. Actually I am doing it in 3D so that would be 27 cells to check. The code looks similar to this https://play.rust-lang.org/?gist=d98e6af4b29b1bdd708c0e75a677f3ca&version=stable&mode=debug , can some one help reduce the repetative code
Miguel Duarte
@malduarte
Jun 15 2018 14:02
@omni-viral I can't get it to work with function that takes references.
I'm a rust newbie though
Devashish Dixit
@devashishdxt
Jun 15 2018 14:08
@dineshadepu You can write a macro for this
trsh
@trsh
Jun 15 2018 14:27
match key {
            "json-output" => xx(&xx),
            _ => {
                panic!("Unknown worker = {}", &key);
                Box::new(ok(vec![]))
            }
        }
If I remove Box return, I got an match error, if I add it, i got warning of unreachable statement
Fredrik Portström
@portstrom
Jun 15 2018 14:33
@dineshadepu @devashishdxt Macros are a fantastic feature, but Rust is very expressive even without them. I see two ways you can deduplicate the code without macros. You can make a loop or a closure.
for neighbor in &[
    index.checked_sub(1),
    index.checked_add(1),
    index.checked_sub(grid.no_y_cells),
    index.checked_sub(grid.no_y_cells - 1),
    index.checked_sub(grid.no_y_cells + 1),
    index.checked_add(grid.no_y_cells),
    index.checked_add(grid.no_y_cells - 1),
    index.checked_add(grid.no_y_cells + 1)
] {
    if let Some(cell) = index.and_then(|index| cells.get(index)) {
        for value in cell.id {
            id_all.push(*value);
        }
    }
}
A Dinesh
@dineshadepu
Jun 15 2018 14:35
coolest ever @portstrom
Fredrik Portström
@portstrom
Jun 15 2018 14:45
Vec also has the function extend_from_slicethat would eliminate the inner loop and make the code even shorter. I don't know why LinkedList is used. Vec is usually a better choice.

Almost always it is better to use Vec or VecDeque instead of LinkedList. In general, array-based containers are faster, more memory efficient and make better use of CPU cache.

https://doc.rust-lang.org/std/collections/struct.LinkedList.html

A Dinesh
@dineshadepu
Jun 15 2018 15:02
Will extend from slice takes a reference or takes ownership of the vector
True, here I want to copy all the indices in the linked list of cell to a single linked list
Devashish Dixit
@devashishdxt
Jun 15 2018 15:02
@portstrom :+1:
A Dinesh
@dineshadepu
Jun 15 2018 15:02
I am doing a O(n) operation
If I can join them them then that would we O(9) operation
Sylwester Rąpała
@xoac
Jun 15 2018 15:05

why either Bytes or BytesMut don't implement trait Buf

I have a struct
struct { len: u16, other: u32 }

And would like to create function that can easy get this values as le

but both can be converted into Cursor
How to get the reference of a vector and append it to another vector
Devashish Dixit
@devashishdxt
Jun 15 2018 15:22
@dineshadepu You cannot take a reference of a vector and append it to another vector. A vector is a contiguous array of elements. If you want to append elements to any vector, you'll have to move them to the corresponding locations. Vec::append function in standard library does the same thing. https://doc.rust-lang.org/std/vec/struct.Vec.html#method.append
    pub fn from_le_bytes(mem: Bytes) -> MemDump {
        let addr: MemAddr;
        let mem = mem.into_buf();
        let addr = mem.get_u32_le();

        MemDump {
            addr,
            mem: mem.into(),
        }
    }
I want to extract 4 bytes and the rest use as data but this dosen't work :(
I can convert into Cursor but not back. What is a proper way to do it?
Fredrik Portström
@portstrom
Jun 15 2018 15:29
@devashishdxt You can take a reference of a vector and append to another vector, subject to lifetime requirements.
Sylwester Rąpała
@xoac
Jun 15 2018 15:29
here is my struct. Everthing using bytes crate
pub struct MemDump {
    addr: MemAddr,
    mem: Bytes,
}
Devashish Dixit
@devashishdxt
Jun 15 2018 15:29
Yes. But, won’t that move the elements?
stdlib docs says so
Fredrik Portström
@portstrom
Jun 15 2018 15:30
Just taking a reference won't do anything with the elements.
Devashish Dixit
@devashishdxt
Jun 15 2018 15:32
Oh. Append function works with mutable reference of both vectors
Turing Zhu
@Turing-Chu
Jun 15 2018 15:51
what does the mean of turbofish in rust or in english?I never meet this word before and can not find it’s means in dictionary.
Fredrik Portström
@portstrom
Jun 15 2018 15:52
@Turing-Chu As I've understood it, it just refers to what the token looks like.
Sylwester Rąpała
@xoac
Jun 15 2018 15:52
ok I force it compile bit I don't like it much
    pub fn from_le_bytes(mem: &[u8]) -> MemDump {
        let addr = &mem[0..4];
        let addr: MemAddr = addr.into_buf().get_u32_le();

        MemDump {
            addr,
            mem: mem[4..].into(),
        }
    }
Turing Zhu
@Turing-Chu
Jun 15 2018 15:53
thanks let me look at it。
Michal 'vorner' Vaner
@vorner
Jun 15 2018 19:18
I'm playing with something and now I have to wonder… there are things that are Send, but not Sync (eg. RefCell). Are there any of the reverse ones, something that is Sync, but not Send? Could there be or does Sync imply Send?
Fredrik Portström
@portstrom
Jun 15 2018 19:46
I wonder why there are so many different crates for accessing LMDB and how to choose.
https://crates.io/crates/lmdb
https://crates.io/crates/lmdb-zero
https://crates.io/crates/lmdb-rs
Denis Lisov
@tanriol
Jun 15 2018 20:17
@vorner These are rare, but possible. An example that can be Sync but not Send is MutexGuard.
Not exactly sure, most likely it means that you can access data behind it (if it is Sync itself) from any thread, but the guard must be dropped from the same thread (unlocking the mutex from a different thread can be undefined behaviour).
Zakarum
@omni-viral
Jun 15 2018 20:41
Funny that MutexGuard is Sync only since 1.19
Denis Lisov
@tanriol
Jun 15 2018 21:12
@omni-viral It's the other way round: by mistake it was Sync even for T: !Sync between 1.0 and 1.19 (see #41622)