These are chat archives for rust-lang/rust

24th
Nov 2018
Denis Lisov
@tanriol
Nov 24 2018 08:40
If you just need to iterate over a nested structure, you don't need that workaround. What function do you want to make? fn iter_els(root: &El) -> impl Iterator<Item=&El>?
Kelly Thomas Kline
@kellytk
Nov 24 2018 09:04
If you've integrated logging of program performance data to a metrics protocol such as statsd how was your experience and did you encounter any gotchas?
Kelly Thomas Kline
@kellytk
Nov 24 2018 09:23
I was looking at Cadence but it's a client for statsd and I found Dipstick which is a client for statsd and more which is interesting
trsh
@trsh
Nov 24 2018 13:15
I sucssed to define hashMap like let mut access_rights: HashMap<&str, Vec<(&str, Vec<&str>)>> = HashMap::new();
But then when i do
access_rights.contains_key(&role.role_label)
I get
116 |                 if access_rights.contains_key(&role.role_label){
    |                                  ^^^^^^^^^^^^ the trait `std::borrow::Borrow<std::string::String>` is not implemented for `&str`
Any ideas?
Denis Lisov
@tanriol
Nov 24 2018 13:39
Do you really keep a HashMap full of borrowed strings?
David O'Connor
@David-OConnor
Nov 24 2018 13:50
@tanriol Yep - or just a vec
trsh
@trsh
Nov 24 2018 13:59
@tanriol heh, no, clear
laurent bernabé
@loloof64
Nov 24 2018 21:58
Hi everyone : I have an issue with closure and references
match logic {
            Some(game_logic) => {
                let chess_board = ChessBoard {
                    drawing_area,
                    reversed: false,
                    logic: game_logic,
                    piece_images,
                    cells_size,
                };

                chess_board.drawing_area.connect_draw(|_drawing_area, cr|{
                    ChessBoard::paint(&chess_board, cr);
                    Inhibit(false)
                });

                Some(chess_board)
            },
            _ => None
        }
In connect_draw, reported error is closure may outlive chess_board
But is there a way I can borrow chessboard as immutable instead inside the closure ?
Inside ChessBoard :
fn paint(chess_board: &ChessBoard, cr: &Context){
        ChessBoard::draw_background(cr);
        ChessBoard::draw_cells(cr, chess_board);
        ChessBoard::draw_pieces(cr, chess_board);
        ChessBoard::draw_coordinates(cr, chess_board);
        ChessBoard::draw_player_turn(cr, chess_board);
    }
The error :
error[E0373]: closure may outlive the current function, but it borrows `chess_board`, which is owned by the current function
  --> src/chess_position_trainer/graphic/chessboard.rs:64:55
   |
64 |                 chess_board.drawing_area.connect_draw(|_drawing_area, cr|{
   |                                                       ^^^^^^^^^^^^^^^^^^^ may outlive borrowed value `chess_board`
65 |                     ChessBoard::paint(&chess_board, cr);
   |                                        ----------- `chess_board` is borrowed here
help: to force the closure to take ownership of `chess_board` (and any other referenced variables), use the `move` keyword
   |
64 |                 chess_board.drawing_area.connect_draw(move |_drawing_area, cr|{
   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error
Denis Lisov
@tanriol
Nov 24 2018 22:51
The problem here is that nothing guarantees the board will still exist when the callback is executed (actually, it definitely will not). You need some kind of shared ownership like Rc so that the closure itself keeps the board from being dropped.
laurent bernabé
@loloof64
Nov 24 2018 22:52
Thank you :smile:
I was trying something like this, but still "falsy"
match logic {
            Some(game_logic) => {
                let chess_board = ChessBoard {
                    drawing_area,
                    reversed: false,
                    logic: game_logic,
                    piece_images,
                    cells_size,
                };

                let chess_board_ref = Rc::new(&chess_board);
                let chess_board_for_closure = Rc::downgrade(&chess_board_ref);

                chess_board.drawing_area.connect_draw(|_drawing_area, cr|{
                    if let Some(chess_board_ref) = chess_board_for_closure.upgrade() {
                        chess_board_ref.paint(cr);
                    }
                    Inhibit(false)
                });

                Some(chess_board)
            },
            _ => None
        }
error[E0597]: `chess_board` does not live long enough
  --> src/chess_position_trainer/graphic/chessboard.rs:67:48
   |
67 |                 let chess_board_ref = Rc::new(&chess_board);
   |                                                ^^^^^^^^^^^ borrowed value does not live long enough
...
78 |             },
   |             - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

error[E0373]: closure may outlive the current function, but it borrows `chess_board_for_closure`, which is owned by the current function
  --> src/chess_position_trainer/graphic/chessboard.rs:70:55
   |
70 |                 chess_board.drawing_area.connect_draw(|_drawing_area, cr|{
   |                                                       ^^^^^^^^^^^^^^^^^^^ may outlive borrowed value `chess_board_for_closure`
71 |                     if let Some(chess_board_ref) = chess_board_for_closure.upgrade() {
   |                                                    ----------------------- `chess_board_for_closure` is borrowed here
help: to force the closure to take ownership of `chess_board_for_closure` (and any other referenced variables), use the `move` keyword
   |
70 |                 chess_board.drawing_area.connect_draw(move |_drawing_area, cr|{
   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors
Denis Lisov
@tanriol
Nov 24 2018 22:54
You're trying to put a reference into the Rc, but you actually need to keep the whole board in there...
Tim Robinson
@1tgr
Nov 24 2018 22:54
Once your ChessBoard goes into the Rc, you can’t access it except via the Rc
laurent bernabé
@loloof64
Nov 24 2018 22:56
Thanks. I am trying to improve my code based on your explanations.
Tim Robinson
@1tgr
Nov 24 2018 22:56
Your closure refers to chess_board_ref.clone(), and your function returns Some(chess_board_ref)
laurent bernabé
@loloof64
Nov 24 2018 22:59
Ok, thanks. Trying again.
Maybe I'd better read the chapter on smart pointers of the Rust Programming Book, and then return to this issue.
laurent bernabé
@loloof64
Nov 24 2018 23:40
I think I am getting closer :
match logic {
            Some(game_logic) => {
                let chess_board = ChessBoard {
                    drawing_area,
                    reversed: false,
                    logic: game_logic,
                    cells_size,
                };

                let chess_board_ref = Rc::new(chess_board);

                chess_board_ref.drawing_area.connect_draw(|_drawing_area, cr|{
                    Rc::clone(&chess_board_ref).paint(cr);
                    Inhibit(false)
                });

                Some(chess_board_ref)
            },
            _ => None
        }
error[E0308]: mismatched types
  --> src/chess_position_trainer/graphic/chessboard.rs:72:22
   |
72 |                 Some(chess_board_ref)
   |                      ^^^^^^^^^^^^^^^ expected struct `chess_position_trainer::graphic::chessboard::ChessBoard`, found struct `std::rc::Rc`
   |
   = note: expected type `chess_position_trainer::graphic::chessboard::ChessBoard`
              found type `std::rc::Rc<chess_position_trainer::graphic::chessboard::ChessBoard>`

error: aborting due to previous error
I tried to deference Some(*chess_board_ref), but got another error that time
(Cannot move out borrowed content)