These are chat archives for rust-lang/rust

17th
Jun 2018
Farzeen
@happycoder97
Jun 17 2018 12:56
Why is it needed to specify the lifetime of &u8 here? Is there any reason not to assume that, if unspecified, the lifetime of all reference contained in a struct variable is more than the lifetime of the variable?
struct Test(&u8);

impl Test {
    fn print(&self) {
        println!("{}", self.0);
    }
}

fn main() {
    let num: u8 = 100;
    {
        let test = Test(&num);
        test.print();
    }
}
Fredrik Portström
@portstrom
Jun 17 2018 12:59
@happycoder97 Users of the struct can specify different lifetimes, so you need to make it explicit that the struct takes a lifetime variable.
Zakarum
@omni-viral
Jun 17 2018 13:03
if unspecified, the lifetime of all reference contained in a struct variable is more than the lifetime of the variable?
This is the case when it is specified
And lifetime parameter on struct makes it impossible to have instance of that type with bigger lifetime than parameter
Sylwester Rąpała
@xoac
Jun 17 2018 19:43
is there a way to say that some function from struct must me used?
Denis Lisov
@tanriol
Jun 17 2018 19:44
@xoac What exactly do you mean? There are different ways for different cases :-)
Sylwester Rąpała
@xoac
Jun 17 2018 19:45
I want return builder and have one obligatory function. if that function is not used this is point less. I can panic on build(). but I would prefer at compiletime
must_use is just for returning type
Denis Lisov
@tanriol
Jun 17 2018 19:48
How about passing the argument of that function either to the function that returns the builder or to build itself?
MyBuilder.some_option().build_for_required_argument(req)
Sylwester Rąpała
@xoac
Jun 17 2018 19:49
I think this a good solution
Denis Lisov
@tanriol
Jun 17 2018 19:52
There's also the parametric solution for more complex cases where builder is created as Builder<Incomplete>, but build is defined for Builder<Complete> and the function you need converts it to complete.
Sylwester Rąpała
@xoac
Jun 17 2018 21:24
thx
for now I used build that require specify argument.
I have builders/mod.r builders/frame.rs builders/head.rs I want head to by private but used in frame.rs it is possible? Or I need to combine this 2 files?
Fredrik Portström
@portstrom
Jun 17 2018 21:27
You can builders::head public only to builders but not to the crate root.
Sylwester Rąpała
@xoac
Jun 17 2018 21:28
how to achive that?
Fredrik Portström
@portstrom
Jun 17 2018 21:28
Make things public in builders/frame.rs, but in builders/mod.rs, put mod frame, not pub mod frame.
Sylwester Rąpała
@xoac
Jun 17 2018 21:29
you mean mod head? Frame should be public. Thx for help
Fredrik Portström
@portstrom
Jun 17 2018 21:30
yes
Denis Lisov
@tanriol
Jun 17 2018 21:30
There's also the pub(path) version like pub(builders), IIRC.
Jerry Tegno
@jearbear
Jun 17 2018 21:42

Hi I was wondering if I could help with this particular snippet. In particular this compiles:

    let uris: Vec<Uri> = match rx.recv() {
        Some(body) => match Document::from_read(&*body) {
            Ok(doc) => doc.find(Class("hdrlnk"))
                .into_iter()
                .filter_map(|tag| tag.attr("href"))
                .filter_map(|s| s.parse().ok())
                .collect(),
            Err(_) => Vec::new(),
        },
        None => Vec::new(),
    };

But not this (doc doesn't live long enough)

    let uris: Vec<Uri> = rx.recv()
        .into_iter()
        .filter_map(|body| Document::from_read(&*body).ok())
        .flat_map(|doc| doc.find(Class("hdrlnk")))
        .filter_map(|tag| tag.attr("href"))
        .filter_map(|s| s.parse().ok())
        .collect();
I somewhat get that doc doesn't outlive the closure that it's defined in, but I was wondering if it's possible to specify that I want each closure to pass on ownership.
In particular, the compiler is saying that doc doesn't outlive the closure in flat_map, but needs to live until the collect() at the end, which kind of makes sense to me. But I'm wondering if there's thus a bit cleaner of a way to keep all of the logic in the happy path and avoid the nested matching in the working example.
Sylwester Rąpała
@xoac
Jun 17 2018 21:53
have u tried move |doc|?
Jerry Tegno
@jearbear
Jun 17 2018 21:53
Yup! Same problems
I actually tried adding move just about everywhere :sweat_smile:
Fredrik Portström
@portstrom
Jun 17 2018 21:54
There's nothing to move at that point. The document is created after the closure is created.
Jerry Tegno
@jearbear
Jun 17 2018 21:54
I guess I should also specify that doc.find(Class("hdrlnk")) itself will return an iterator hence the flat_map. I don't know if that adds any complications
Fredrik Portström
@portstrom
Jun 17 2018 22:03
Also if you could find a way to move the document, the borrow checker doesn't allow the document to be moved while borrowed, just as it doesn't allow the document to be dropped while borrowed.
Jerry Tegno
@jearbear
Jun 17 2018 22:04
Ah that does make sense
Jerry Tegno
@jearbear
Jun 17 2018 22:25

Interestingly enough, doing:

    rx.recv()
        .into_iter()
        .filter_map(|body| Document::from_read(&*body).ok())
        .flat_map(|doc| {
            doc.find(Class("hdrlnk"))
                .filter_map(|tag| tag.attr("href"))
                .filter_map(|s| s.parse().ok())
                .collect::<Vec<_>>()
        })
        .collect()

Also works. I'm assuming this is thanks to the intermmediate .collect