(I’m just starting off with rust, so please be patient)

Is there an idiomatic way of writing the following as a one-liner, somehow informing rustc that it should keep the PathBuf around?

// nevermind the fully-qualified names
// they are there to clarify the code
// (that's what I hope at least)

let dir: std::path::PathBuf = std::env::current_dir().unwrap();
let dir: &std::path::Path   = dir.as_path();

// this won't do:
// let dir = std::env::current_dir().unwrap().as_path();

I do understand why rust complains that “temporary value dropped while borrowed” (I mean, the message says it all), but, since I don’t really need the PathBuf for anything else, I was wondering if there’s an idiomatic to tell rust that it should extend its life until the end of the code block.

  • Sibbo@sopuli.xyz
    link
    fedilink
    arrow-up
    6
    ·
    3 months ago

    I think you already used a pretty nice way, which is using shadowing. If one variable is only used for the creation of another, simply shadowing it keeps your namespace clean.

    Sometimes it doesn’t make sense to give the shadowed variable the same name, because that name doesn’t describe its content very well. But in this case it seems like that is not a concern.

  • Max-P@lemmy.max-p.me
    link
    fedilink
    arrow-up
    5
    ·
    3 months ago

    I don’t think you can, and I think it makes sense: it would be weird for the compiler to unexpectedly generate hidden variables for you.

    For all the compiler knows, the temporary variable could hold a file handle, a database transaction, a Mutex, or other side effects in their Drop implementation that would make when it’s dropped matter. Or it could just be a very large struct you might not expect to keep around until the end of the function (or even, the end of the program if that’s a main loop).

    So you should be aware of it, and thus you need the temporary variable like you did even if you just immediately shadow it. But at least you know you’re holding on to it until the end of the function.

    • Ephera@lemmy.ml
      link
      fedilink
      arrow-up
      2
      ·
      3 months ago

      Yeah, it occasionally bothers me, too, that I have to pull out an assignment, but in terms of the mental model, I do think, it’s absolutely vital to always have ownership associated with a concrete variable slot.

  • BB_C
    link
    fedilink
    arrow-up
    3
    arrow-down
    1
    ·
    edit-2
    3 months ago

    There is a general mechanism in Rust that allows language users to add their own sugar. It’s called macros 😉

    macro_rules! keep {
        (let $id:ident = $expr:expr => $($tt:tt)+) => {
            let $id = $expr;
            let $id = $id$($tt)+;
        }
    }
    
    fn main() {
        keep!{ let path = std::env::current_dir().unwrap() => .as_path() };
        println!("{path:?}");
    }
    

    You can remove let from the macro’s fragment specifier and invocation.

    • Ephera@lemmy.ml
      link
      fedilink
      arrow-up
      11
      ·
      3 months ago

      While macros are cool and it’s good to keep them as an option in the back of the mind, it should be clarified that you’re not supposed to immediately reach for macros for small things you don’t quite like about the language.

      Excessive macro use makes it impossible for others (including your future self) to read your code and there’s often good reasons why it’s designed like it is.

      • BB_C
        link
        fedilink
        arrow-up
        2
        arrow-down
        8
        ·
        3 months ago

        you’re not supposed to immediately reach for macros

        correct

        for small things you don’t quite like about the language.

        incorrect

        Excessive macro use makes it impossible for others (including your future self) to read your code

        N/A. the macro above is trivial.

        impossible for others to read your code and there’s often good reasons why it’s designed like it is.

        fiction

        • kelvie@lemmy.ca
          link
          fedilink
          arrow-up
          6
          ·
          3 months ago

          Oof, this brings back PTSD for a lot of us that have worked with developers like this ☝️

          • slowcakes
            link
            fedilink
            arrow-up
            1
            arrow-down
            1
            ·
            2 months ago

            Well, all developers give each other ptsd, never seen a clean code base in my career. They all turn to shit, because 90% developers don’t care, because it will be someone else’s problem later.

            That said, yeah don’t do weird custom code, where you have to keep context in your head to understand the code.

  • _hovi_@lemmy.world
    link
    fedilink
    arrow-up
    2
    ·
    3 months ago

    As someone else said I think the shadowing works well here.

    I do also wanna mention that depending on why you need this conversion, you could use impl AsRef<std::path::Path> for your function signature so it can accept &PathBuf or &Path. Then, just use that argument with e.g. p.as_ref() to get a &Path in the function body

  • anlumo@feddit.org
    link
    fedilink
    English
    arrow-up
    2
    ·
    3 months ago

    This is a limitation of the current borrow checker. I think there are some efforts going on to improve on this situation, but right now that’s what we have to work with.

    The borrow checker can keep unnamed values around for a single expression, but not beyond that.

  • IsoSpandy@lemm.ee
    link
    fedilink
    arrow-up
    1
    ·
    3 months ago

    There is a to_owned() thingy I use that for path buf shenanigans. Basically the value you create is a pointer reference short of. To_owned allocates it on memory.