Temp value dropped while borrowed

In the below code, I cannot understand why I'm getting this error: After all, it is just one consecutive sequence of calls, so there is no chance that the temp value will be accessed after that.

let file_name = PathBuf::from(output_file)
        .file_name()
        .ok_or(ZipError::FileNotFound)?
        .to_str()
        .ok_or(ZipError::FileNotFound)?;
error[E0716]: temporary value dropped while borrowed
  --> src/internals/ops/ops_utils/zip.rs:18:21
   |
18 |     let file_name = PathBuf::from(output_file).file_name();
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^            - temporary value is freed at the end of this statement
   |                     |
   |                     creates a temporary which is freed while still in use
19 |     let file_name = file_name
   |                     --------- borrow later used here
   |
   = note: consider using a `let` binding to create a longer lived value

It is because the file_name value borrows from the PathBuf, but the PathBuf is destroyed at the semicolon, whihc makes it invalid to use the file name afterwards. Consider keeping the PathBuf alive:

let path = PathBuf::from(output_file);
let file_name = path
        .file_name()
        .ok_or(ZipError::FileNotFound)?
        .to_str()
        .ok_or(ZipError::FileNotFound)?;

Or converting the filename into an owned type such as String.

let file_name = PathBuf::from(output_file)
        .file_name()
        .ok_or(ZipError::FileNotFound)?
        .to_str()
        .ok_or(ZipError::FileNotFound)?
        .to_string();

Note that FileNotFound is not really the appropriate error to use for to_str here.

2 Likes

Hi and thank you.
But the semicolon is at the end of those calls... I still don't get it...

OK, I get it! Thanks.

Do you not use the file name at all?

Yes, I just understood that a sec ago :slight_smile:
Once again, thank you for your time and help.

1 Like