These are chat archives for rust-lang/rust

8th
Jun 2018
VJ
@00imvj00
Jun 08 2018 00:27
@omni-viral and can we early drop static variable?
Zakarum
@omni-viral
Jun 08 2018 06:02
  1. Just like you did it. funcname::<'lifetime>
  1. static X: Mutex<Option<T>> = ... and then X.lock().take()
How to go around
I need to populate that m. This just an narrowed example
Denis Lisov
@tanriol
Jun 08 2018 07:48
@trsh Don't see any good ways, at least without NLL. Are you sure you really need this?
trsh
@trsh
Jun 08 2018 07:51
@tanriol yes. Whats NLL?
Fredrik Portström
@portstrom
Jun 08 2018 07:51
@trsh I don't understand why you make references of everything, and even references of references. Removing all the & signs, the code works: https://play.rust-lang.org/?gist=0e55df6f6420eb3df4165deaa0c296f6
Denis Lisov
@tanriol
Jun 08 2018 07:52
Non-lexical lifetimes, a future change in lifetime rules. It will be much more flexible, but at the moment it's nightly only.
trsh
@trsh
Jun 08 2018 07:53
@portstrom in my real code I am looping a vector
And parts for vector are references
Fredrik Portström
@portstrom
Jun 08 2018 07:54
@trsh It would be helpful to have some example code that is more similar to the real code.
Denis Lisov
@tanriol
Jun 08 2018 07:54
Could you please show or describe the real problem your code is trying to solve?
trsh
@trsh
Jun 08 2018 07:58
Well its long. I can paste a fragment that gives me headaches > https://pastebin.com/kqCGRZzt
error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> manu/src/applications/api/sockets/workers/processor/engine.rs:53:19
   |
53 |         let out = self.back_process(&nn);
   |                   ^^^^ mutable borrow starts here in previous iteration of loop
...
63 |     }
   |     - mutable borrow ends here
If I could undrestand the problem
..
Denis Lisov
@tanriol
Jun 08 2018 08:02
What's the signature of self.back_process?
trsh
@trsh
Jun 08 2018 08:06
fn back_process(&mut self, node: &Value) -> &Vec<Option<Value>> {
I narrowed the code down > https://pastebin.com/XNk0TH3y
Denis Lisov
@tanriol
Jun 08 2018 08:13
(a) at least in the current state, the function does not need to take &mut self as it does not mutate anything
trsh
@trsh
Jun 08 2018 08:14
@tanriol sorry I removed part accidentally > self.nodes_output.insert(*id, new_outputs);
The point is that I do need it mutable
Seems like when I want to return recursively a reference, eveything goes to hell
Denis Lisov
@tanriol
Jun 08 2018 08:18
What's the type of nodes_output?
trsh
@trsh
Jun 08 2018 08:18
nodes_output: HashMap<u64, Vec<Option<Value>>>,
Fredrik Portström
@portstrom
Jun 08 2018 08:20
@trsh There are some things that make the code more difficult to read, such as looping through a range of numbers and using as an index when you could do for input in inputs.iter() { and for c in connections.iter() {, and making a reference for nid and out_index just to dereference it on the next line, when you could simply remove the & and *.
trsh
@trsh
Jun 08 2018 08:21
@portstrom yeah, Im working on that. See last link
Denis Lisov
@tanriol
Jun 08 2018 08:21
So your idea is that nodes_output is append-only, Vecs inside are not mutated at all and thus keeping the references shall be safe. The problem is that the compiler does not know that.
When you call a method on &mut self, it assumes that could do anything... including, for example, dropping all data from node_outputs, which would make the references invalid.
trsh
@trsh
Jun 08 2018 08:23
hmm
So what could be the solution? I partly understood the point
Denis Lisov
@tanriol
Jun 08 2018 08:26
Is this part expected to be performance critical?
Fredrik Portström
@portstrom
Jun 08 2018 08:26
What type are self.nodes and self.nodes_output?
trsh
@trsh
Jun 08 2018 08:27
btw if I remove out_data.push(val);, the code compiles. The problem is that in 1st loop, the reference is barowed and not ready for next loops. as the compiler says
Fredrik Portström
@portstrom
Jun 08 2018 08:28
There's surely a solution, if I just get enough information to reproduce the error in the playground.
Denis Lisov
@tanriol
Jun 08 2018 08:28
The problem is that you collect references in out_data while, possibly, mutating underlying data.
trsh
@trsh
Jun 08 2018 08:29
@tanriol perf is critical :/
Denis Lisov
@tanriol
Jun 08 2018 08:29
The most trivial is to make nodes_output: HashMap<u64, Vec<Arc<Option<Value>>>> and clone the Arcs, but may be a performance problem if this code is hot.
trsh
@trsh
Jun 08 2018 08:30
Maybe I have to write code 0 and do it otherwise
Denis Lisov
@tanriol
Jun 08 2018 08:46
An alternate option with a tiny bit of unsafe (probably safe, but I don't know enough to be absolutely sure) is to make a wrapper around HashMap<Vec<T>> that can only be indexed to a slice, not a reference to the Vec, but allows insertion with &self
...looks like Aovec from the aovec crates already is such a wrapper.
trsh
@trsh
Jun 08 2018 08:50
Or passing the hashmap as param for the function
ugly and simple
Fredrik Portström
@portstrom
Jun 08 2018 08:51
I would probably go with passing a mutable reference to the hash map to the function.
Denis Lisov
@tanriol
Jun 08 2018 08:53
Does it actually work? I doubt so.
trsh
@trsh
Jun 08 2018 08:54
I think yes, but having moving problems value used here after move
When I pass let out = self.back_process(nn, ss); ss is moved so can't use later in code
Fredrik Portström
@portstrom
Jun 08 2018 08:55
I would like to show in the sandbox how it works if I could just get the type of self.nodes and the missing code that creates new_outputs.
trsh
@trsh
Jun 08 2018 08:55
I can reproduce in small example
Fredrik Portström
@portstrom
Jun 08 2018 08:56
I recommend using serde_derive rather than working on serde_json::Value. https://github.com/serde-rs/json#parsing-json-as-strongly-typed-data-structures
trsh
@trsh
Jun 08 2018 08:56
nodes is nodes: Option<&'a Value>,
@portstrom par of data will be static (predictable), par dynamic
So I cant glue it to a struct, I guess
Denis Lisov
@tanriol
Jun 08 2018 08:59
You're trying to keep references into a HashMap and mutate it at the same time. Not gonna fly. If it did, I'd consider it a bug.
Fredrik Portström
@portstrom
Jun 08 2018 09:02
Derived deserializers allow mixing predictable fields with unpredictable fields. I just can't find the documentation for that feature right now.
trsh
@trsh
Jun 08 2018 09:04
Maybe have to ditch the HashMap
ghh
Then I will need todo loops, to find the index
trsh
@trsh
Jun 08 2018 09:05
tnx
will read about Aovec
Zakarum
@omni-viral
Jun 08 2018 09:07
What's the best way to match on either lifetime parameter or type parameter inside < > in macro?
trsh
@trsh
Jun 08 2018 09:14
@tanriol is there a way to get the value from Vec as non-reference? make a copy?
Michal 'vorner' Vaner
@vorner
Jun 08 2018 09:14
.clone()
trsh
@trsh
Jun 08 2018 09:15
@vorner so clone allocates new memory?
Dmitriy
@dpogretskiy
Jun 08 2018 09:15
if you clone value it depends
Michal 'vorner' Vaner
@vorner
Jun 08 2018 09:15
It can. It depends on what type it is called on. For example, .clone on Arc just increases the reference count.
Fredrik Portström
@portstrom
Jun 08 2018 09:18
trsh
@trsh
Jun 08 2018 09:20
@portstrom good point
tnx
@vorner tnx for info
Will try to fix that code now
Btw I only use hashTree for fast index lookup. Maybe there something as fast as and even better.
?
Mutable hashMap keeping references
Denis Lisov
@tanriol
Jun 08 2018 09:44
You're not keeping references to something the HashMap owns in this example.
Fredrik Portström
@portstrom
Jun 08 2018 09:46
I see you have IDs for everything. You could put IDs instead of references in all data structures, and that would solve the problem of self-referencing data structures.
trsh
@trsh
Jun 08 2018 09:46
@tanriol can u quick make the example throw that error. so i better understand?
Denis Lisov
@tanriol
Jun 08 2018 09:52
trsh
@trsh
Jun 08 2018 09:55
Gotcha, tnx
If I barrow the reference of hashMap, I can further mess with it
trsh
@trsh
Jun 08 2018 10:42
@portstrom id based approach works like a charm. Instead of reference I pass id, and do not need to barrow references in loop
trsh
@trsh
Jun 08 2018 10:49
I mean other problems arrise, but getting further
:D
trsh
@trsh
Jun 08 2018 12:09
I mean besides removing brackets :D
Michal 'vorner' Vaner
@vorner
Jun 08 2018 12:18
@trsh: That thing looks somewhat suspicious and you probably want to avoid this situation in your design. But if you really need to do something like that, you need to either have something like Rc instead of „plain“ data, or put the i outside into an option, or like this:
trsh
@trsh
Jun 08 2018 12:24
Ok, clear tnx
trsh
@trsh
Jun 08 2018 13:19
@vorner still I dont understand. If this > https://play.rust-lang.org/?gist=4cf7320195675955ee7f3a11d1961951&version=stable&mode=debug > is bad design. How do I do it correctly. How do I fill hashMap with references?
Whats the correct Rust Way?
you can do this
in both cases you don't fill hashmap with references, since values are just copied into it
Zakarum
@omni-viral
Jun 08 2018 13:27
@trsh You you actually need to fill HashMap with references you must ensure that HasMap is dropped before any of referenced values
@dpogretskiy In your example you make HashMap<usize, &i32>
Dmitriy
@dpogretskiy
Jun 08 2018 13:28
@omni-viral yeah, my bad, i was too fast :smile:
use std::collections::HashMap;

fn main(){
    let gg: Vec<i32> = vec![1,2,3];
    let mut ss: HashMap<usize, &i32> = HashMap::new();

    for i in 0..gg.len() {
      let v = &gg[i];
      ss.insert(i, v);
    }
}
Zakarum
@omni-viral
Jun 08 2018 13:28
If you will replace iter() with into_iter() then it will br HashMap<usize, i32>
Dmitriy
@dpogretskiy
Jun 08 2018 13:29
this actually works
Zakarum
@omni-viral
Jun 08 2018 13:29
This is the same as example above that uses collect
Dmitriy
@dpogretskiy
Jun 08 2018 13:29
since scope item are dropped in reverse create order
Zakarum
@omni-viral
Jun 08 2018 13:29
But written manually
@dpogretskiy Not entirely. They have scope started at let and ended simulteneously
Drop wil be executed in any order
Dmitriy
@dpogretskiy
Jun 08 2018 13:31
but it doesn't compile that way, funny enough
use std::collections::HashMap;

fn main(){
    let gg: Vec<i32> = vec![1,2,3];

    let refs = gg.iter().enumerate().collect::<HashMap<usize, &i32>>();
    println!("{:?}", refs);
}
so this also works
Tom Sellman
@tsellman
Jun 08 2018 13:34
@omni-viral is this note in the original compiler error incorrect then? "= note: values in a scope are dropped in the opposite order they are created"
Zakarum
@omni-viral
Jun 08 2018 13:35
Maybe something changed :/
Maybe I mess that up with struct fields drop order...
Zakarum
@omni-viral
Jun 08 2018 13:44
Anyway HashMap::drop never tries to dereference stored references. So it is safe to drop it last
trsh
@trsh
Jun 08 2018 13:45
Hmmm
And what in the hell did the order change for a magic?
Dropping happens in reverse to definitions?
From error I concluded, that the LOOP is int's own scope, and all references are dropped in the end of it
Dmitriy
@dpogretskiy
Jun 08 2018 13:57
nah, it's only vec is dropped prior to hash map, which is a lifetime error
i mean, there can be some awkward stuff in Drop definition, so there should be strict rule on drop order.
and creation order vs reverse create order makes sense, since there is higher probability of predicating new values on older ones, and not reverse :)
Btw thanks for the input
The vector I want to put in hash is dependent on some index.
Dmitriy
@dpogretskiy
Jun 08 2018 14:20
use std::collections::HashMap;

fn get_big_vec(index: i32) -> Vec<i32> {
    vec![1, 2, 3]
}

fn main() {
    let vecs = (0..2)
        .map(|id| get_big_vec(id).to_vec())
        .collect::<Vec<_>>();
    let ss = vecs.iter()
        .flat_map(|v| v.iter().enumerate())
        .collect::<HashMap<usize, &i32>>();

    println!("{:?}", ss);
}
it depends on where you wan't to enumerate them
on top level or bottom level
use std::collections::HashMap;

fn get_big_vec(index: i32) -> Vec<i32> {
    vec![1, 2, 3]
}

fn main() {
    let vecs = (0..2)
        .map(|id| get_big_vec(id).to_vec())
        .collect::<Vec<_>>();

    let ss = vecs.iter()
        .flat_map(|v| v.iter())
        .enumerate()
        .collect::<HashMap<usize, &i32>>();

    println!("{:?}", ss);
}
{0: 1, 2: 3, 5: 3, 3: 1, 4: 2, 1: 2}
this is last one
if enumerate is inside you get {1: 2, 0: 1, 2: 3} as you start from 0 for each vec you get from get_big_vec(id)
look at flat_map closely, it's very useful when you deal with nested stuff
trsh
@trsh
Jun 08 2018 14:25
Gotchya! And loops stay the same
Dmitriy
@dpogretskiy
Jun 08 2018 14:25
yeah, you just need to pin your vecs in place before you do anything with them
trsh
@trsh
Jun 08 2018 14:26
Will try this in my project
Lesson learned
I come from python, js, ts.. so its bit alien to me.. even after a lot of reading and expirmenting
@dpogretskiy SPASIBO pacan! :D
Dmitriy
@dpogretskiy
Jun 08 2018 14:27
take your time, it's somewhat alien to all mortals :laughing:
trsh
@trsh
Jun 08 2018 14:28
I apologies if your not from rus, just your name...
Dmitriy
@dpogretskiy
Jun 08 2018 14:28
I am, what can i say, nice meme breh
:smile:
Ash
@ashthespy
Jun 08 2018 14:42

Hello again! I have a question about the source of the documentation on docs.rs.

For example - I am using the futures crate (futures = "0.1.8") but the docs don't seem to match the available functions.

Even though I believe I am using 0.1.8 when I attempt Sender::poll_complete() the compiler complains that it's not implemented,
Dmitriy
@dpogretskiy
Jun 08 2018 15:07
So you do something like Sended::poll_complete(&mut sender)
or something like sender.poll_complete()
where sender happens to be mut
pub struct Sender;

trait Poll {
    fn poll_complete(&mut self) -> Result<(), ()>;
}

impl Poll for Sender {
    fn poll_complete(&mut self) -> Result<(), ()> {
        Ok(())
    }
}

fn main() {
    let mut sender = Sender;

    Sender::poll_complete(&mut sender);
    sender.poll_complete();
}
Dmitriy
@dpogretskiy
Jun 08 2018 15:12
both of those are valid, but Sender::poll_complete(); doesn't exists
If not just check Cargo.lock for exact versions of your libraries
trsh
@trsh
Jun 08 2018 15:15
@dpogretskiy still it all goes to hell if you must work with pointers > https://play.rust-lang.org/?gist=b72c916468b7c7a8fdccb8d0345cdbd9&version=stable&mode=debug
Dmitriy
@dpogretskiy
Jun 08 2018 15:15
yeah, as i said, you need to pin your vectors in place first
don't create references to them in lambdas, cause then literally anything can happen to that vectors :)
Fredrik Portström
@portstrom
Jun 08 2018 15:25
@trsh You're creating a reference to a value that is discarded at the end of the closure and moving the reference out of the closure. That's not something that should be done.
Ash
@ashthespy
Jun 08 2018 15:54
@dpogretskiy thanks for the tip with the cargo.lock!
Ash
@ashthespy
Jun 08 2018 16:03
How does one poke the sender to actually send something?
Ash
@ashthespy
Jun 08 2018 16:12

When I call it form my

thread::spawn(move || {

}

I end up with a

thread '<unnamed>' panicked at 'no Task is currently running', /home/ash/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-0.1.17/src/task_impl/mod.rs:44:9
dovreshef
@dovreshef
Jun 08 2018 21:04
Where can see usage of failure with errorkind? I'm having a hard understanding it