You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Borrow checker false dropped while still borrowed #38915
use std::ffi::OsString;use std::io::{ResultasIoResult};use std::path::Path;fnmain(){let paths:Vec<OsString> = vec!["filename".into()];// Switching these two lines appeases our lord and savior the borrow checkerlet f = std::fs::rename;let dests = paths.clone();// ---------------------------let pairs = paths.iter().zip(dests.iter());// ----- borrow occurs herefoo(f, pairs);}// `dests` does not live long enough.// ^ `dests` dropped here while still borrowedfnfoo<P,I>(f:fn(P,P) -> IoResult<()>,pairs:I)whereP:AsRef<Path>,I:Iterator<Item=(P,P)>,{for(src, dest)in pairs {let _ = f(src, dest);}}
Looking at @philipc's example, I believe the problem is that the type of the local variable f is actually the specialized type (since Rust does not support generics as first-class values). If you try to write out the specialized type, you get:
fn(&'a i32)
for some unknown 'a. The problem is that the presence of 'a affects not just the argument but also the function pointer itself, so the function pointer cannot outlive 'a either.
If we could somehow specialize for<T> fn(T) as for<'a> fn(&'a i32) (is this sound?), then this could be worked around by giving the local variable f the correct type annotation.
Triage: now compiles on 2018 edition.
2015 errors:
error[E0597]: `dests` does not live long enough
--> src/main.rs:11:34
|
11 | let pairs = paths.iter().zip(dests.iter());
| ^^^^^ borrowed value does not live long enough
...
14 | }
| - `dests` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error: aborting due to previous error
Activity
durka commentedon Jan 9, 2017
That's bizarre. Somehow the borrow checker thinks that
fcontains a borrow ofdests. Removing the call tofooalso eliminates the error.letheed commentedon Jan 9, 2017
Exactly. I have a hard time figuring out what is happening here; I'm not familiar with the compiler's internals.
philipc commentedon Jan 9, 2017
Simplified a bit more:
Rufflewind commentedon Oct 30, 2017
Looking at @philipc's example, I believe the problem is that the type of the local variable
fis actually the specialized type (since Rust does not support generics as first-class values). If you try to write out the specialized type, you get:for some unknown
'a. The problem is that the presence of'aaffects not just the argument but also the function pointer itself, so the function pointer cannot outlive'aeither.If we could somehow specialize
for<T> fn(T)asfor<'a> fn(&'a i32)(is this sound?), then this could be worked around by giving the local variablefthe correct type annotation.letheed commentedon Nov 27, 2017
@Rufflewind That was a long time ago but I remember trying to use
for<'a>because I something like that, but to no avail.memoryruins commentedon Jan 30, 2019
Triage: now compiles on 2018 edition.
2015 errors:
rustc: 1.32.0Auto merge of #59114 - matthewjasper:enable-migate-2015, r=<try>
Auto merge of #59114 - matthewjasper:enable-migate-2015, r=pnkfelix
Auto merge of #59114 - matthewjasper:enable-migate-2015, r=pnkfelix