These are chat archives for rust-lang/rust

6th
Jul 2017
stevensonmt
@stevensonmt
Jul 06 2017 01:04
@tanriol just got home to try your suggestion and that's fixed it. Thanks.
isaacg1
@isaacg1
Jul 06 2017 05:56
Hi, I'm getting a borrow checking error that I don't completely understand.
Joonas Koivunen
@koivunej
Jul 06 2017 05:57
@isaacg1 what's the error...?
isaacg1
@isaacg1
Jul 06 2017 05:57
Without the commented out collect line, the flatmap fails, saying that the return from row_to_string doesn't live long enough.
error[E0597]: borrowed value does not live long enough
   --> src/main.rs:955:17
    |
951 |                     row_to_string(row)
    |                     ------------------ temporary value created here
...
955 |                 })
    |                 ^ temporary value dropped here while still borrowed
956 |                 .collect();
    |                          - temporary value needs to live until here

error[E0597]: `row_index` does not live long enough
   --> src/main.rs:953:49
    |
953 |                         .map(|(char_index, _)| (row_index, char_index))
    |                              -----------------  ^^^^^^^^^ does not live long enough
    |                              |
    |                              capture occurs here
954 |                         //.collect::<Vec<(usize, usize)>>()
955 |                 })
    |                 - borrowed value only lives until here
956 |                 .collect();
    |                          - borrowed value needs to live until here

error: aborting due to 2 previous errors

error: Could not compile `text`.
Joonas Koivunen
@koivunej
Jul 06 2017 05:58
if you wrap your error paste above in three ``` (backticks) it'll display much more readabliy; you can edit your message afterwards, nice
isaacg1
@isaacg1
Jul 06 2017 05:59
I was just having trouble inserting the newline, fixed it.
Joonas Koivunen
@koivunej
Jul 06 2017 05:59
so what is the signature of match_indices?
fn match_indices<'a, P>(&'a self, pat: P) -> MatchIndices<'a, P> where
    P: Pattern<'a>,
Joonas Koivunen
@koivunej
Jul 06 2017 06:00
oh sorry, haven't used that ...
isaacg1
@isaacg1
Jul 06 2017 06:01
No problem
Joonas Koivunen
@koivunej
Jul 06 2017 06:02
but yeah, flat_map is always giving me problems as well
isaacg1
@isaacg1
Jul 06 2017 06:02
It seems like maybe match_indices is borrowing its argument, which is a String, and then that borrow isn't living long enough to reach the collect?
Joonas Koivunen
@koivunej
Jul 06 2017 06:03
yes, almost finished typing my complex explanation of that
isaacg1
@isaacg1
Jul 06 2017 06:03
I see, flat_map needs the iterator inside to live longer than it's currently living.
I would not have guessed it, but I can see it.
Joonas Koivunen
@koivunej
Jul 06 2017 06:04
also correct ... I cannot immediatedly see how to work around this issue. using flat_map is usually nice only if you get the iterator out of the mapped value (by destructing it for example, into_iter() etc)
if you need to avoid the collecting to a Vec, I can think of a fold that would allow you to fill a single Vec of all those matches, but you'll probably lose some readability
isaacg1
@isaacg1
Jul 06 2017 06:06
No, it's not performance critical. Just annoying.
Joonas Koivunen
@koivunej
Jul 06 2017 06:06
yeah, I've definetly hit that feeling when trying to use flat_map
i wonder if supporting this would really require something alike self-referrential structs in Rust. hopefully someone wiser will come along and show a simple fix to this issue
isaacg1
@isaacg1
Jul 06 2017 06:13
I don't think I understand the situation well enough to know why it can't work without the collect.
Joonas Koivunen
@koivunej
Jul 06 2017 06:15
i think it's just like you said; there is nothing keeping the string alive as long as you need the MatchIndices<'a, P> to be alive.. this wouldn't be a problem if the match_indices function was defined fn match_indices<'a, P: Pattern<'a>>(self, pat: P) -> MatchIndices<'a, P> but you cannot define such methods for a str as it has no size (I believe)
isaacg1
@isaacg1
Jul 06 2017 06:18
I see, it would have to be defined directly on String, which they don't like to do.
Well, thanks for your help regardless.
Joonas Koivunen
@koivunej
Jul 06 2017 06:20
you're welcome!
Zakarum
@omni-viral
Jul 06 2017 06:31
@isaacg1 If you could define fn row_to_string<'a>(row: &'a Row) -> &'a String there wouldn't be any issue
or fn row_to_string<'a>(row: &'a Row) -> &'a S for arbitrary S where S: AsRef<str>
isaacg1
@isaacg1
Jul 06 2017 06:39
I see. But that's not possible, since row_to_string creates a fresh string.
Zakarum
@omni-viral
Jul 06 2017 06:40
You mean row does not contain the string data in contigous memory?
isaacg1
@isaacg1
Jul 06 2017 06:41
Yes, that's what I mean, it doesn't
Joonas Koivunen
@koivunej
Jul 06 2017 16:36
@isaacg1 just occured to me: what if you first map the row into String then .flat_map over it? as in
self.core.rows.iter()
  .map(row_to_string)
  .enumerate()
  .flat_map(|(row_index, row_as_string)| row_as_string.match_indices(query).map(|(char_index, _)| (row_index, char_index)))
  .collect()
nevermind, same issue...