These are chat archives for rust-lang/rust

26th
Feb 2019
Sam Johnson
@sam0x17
Feb 26 01:18

Ok so I have a field that represents a boxed closure like so:

pub on_limit: Box<FnMut(StreamState) -> usize>

I can trigger the closure like so:

impl Stream {
    pub fn trigger_limit(&mut self) {
        let state = StreamState {
            remaining_bytes: 0,
            limit: 0,
            total_bytes_in: 0,
            total_bytes_out: 0
        };
        (self.on_limit)(state);
    }
}

My question is how can I mutate other variables in the scope where the closure is created, e.g.:

fn main() {
    let mut st = Stream::new();
    let mut some_variable = 33;
    st.on_limit = Box::new(|state| {
        println!("{}", state.total_bytes_in);
        some_variable = 35;
        return 0;
    });
    st.trigger_limit();
}

^ that complains that some_variable is dropped while still borrowed.

like I need that closure to fire in a way that can mutate things external to st -- otherwise there is no point to having a callback in the first place
Zakarum
@omni-viral
Feb 26 05:56
Box<FnMut(StreamState) -> usize> is actually Box<FnMut(StreamState) -> usize + 'static>
But your closure captures some_variable (non-static variable) by reference and hence can't be 'static
@sam0x17
You can add lifetime parameter to boxed closure Box<FnMut(StreamState) -> usize + 'a>. You'd have to add it to Stream type of course
This will ensure that Stream that holds closure that captures some_variable by reference cannot live longer that some_variable. If it could then you would be able call closure after some_variable is dropped which is invalid.
Sam Johnson
@sam0x17
Feb 26 06:48
gotcha, I'l try that thanks @omni-viral
Is this line basically just a type alias? Is the purpose to add iteration support to the struct?
Denis Lisov
@tanriol
Feb 26 14:49
This line is an associated type binding. It is required because you need to declare the specific output type in your trait implementation. Yes, this trait seems to exist for some kind of iteration only.
Brian Knapp
@knappador
Feb 26 16:47
I've got a channel I'm receiving on that launches a thread and then stores the handle and uses it to switch on to not launch more than one instance of the same thread target. In my debugging, I'm always receiving the message on the same thread, thread 0. I should be able to not use a mutex on the value that keeps more than one target from launching, but given some delay, I get a segfault (because two instances should not be allowed to start up). Are channel messages not processed synchronously?
Kelly Thomas Kline
@kellytk
Feb 26 21:20
To replace sequences of 2+ "." with a single "." in String is a regex the most direct API available?
Ichoran
@Ichoran
Feb 26 21:22
I would use replace; the pattern can be a string literal, not just a regex.
Kelly Thomas Kline
@kellytk
Feb 26 21:23
How could replace match 2+ (unknown at compile-time) instances of a character?
Ichoran
@Ichoran
Feb 26 21:24
Oh, you mean replace the entire block of dots with one single thing?
Kelly Thomas Kline
@kellytk
Feb 26 21:25
Yes
Ichoran
@Ichoran
Feb 26 21:25
Yeah, I'd think regex is the easiest way to go unless you need it insanely fast, in which case you'd walk through it manually (maybe in place).
Kelly Thomas Kline
@kellytk
Feb 26 21:26
There is no API to apply regex in std correct?
I could use retain to walk it as you suggest
Ichoran
@Ichoran
Feb 26 21:30
Yeah, you need the regex crate.
Is there a problem including the crate? It's pretty easy then.
Kelly Thomas Kline
@kellytk
Feb 26 21:33
Thanks
Ichoran
@Ichoran
Feb 26 21:33
They both seem approximately equally easy, if you can choose your starting datatype:
David Holroyd
@dholroyd
Feb 26 22:24
I have a newtype wrapper around u16, and I would like to define some constants using this type; however I would also like construction of the type to always be via new(), because really only the values 0x000..0x1fff should be allowed, and the purpose of the wrapper type is to enforce that
I think that this means I can't have my constants, because a const function can't fail (at the moment?)
...I mean that I can't make new() a const function, and have it panic on bad inputs
is that correct / is there some other trick to allow constants of this type (including constants defined in other crates)
David Holroyd
@dholroyd
Feb 26 22:29
    pub fn new(pid: u16) -> Pid {
        assert!(pid <= Self::MAX_VALUE);
        Pid(pid)
    }