-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Passing a Fn
to an fn
now requires explicit lifetimes for the Fn
and all references passed to it when invoked
#25310
Comments
Or this might be an intentional breakage from #24461. |
I don't see |
This is a regression from Rust 1.0 |
There is also this approach to working around the problem: use a use std::env;
use std::ffi::OsString;
fn foo<F>(bar: &F) -> Option<OsString>
where F: for <'r> Fn(&'r str) -> Option<OsString>
{
bar("HOME")
}
fn main() {
println!("{:?}", foo(&|x|env::var_os(x)));
} |
Playpen of the failing-on-nightly-but-not-stable version, for reference: http://is.gd/UIC7SX (playpen is now on a nightly new enough to reproduce the failure, despite the inline comment) |
Nominating because @bluss suggested this was a stable regression. |
(Just noticed I hadn't included the error message)
|
Hmm. I do think that this should work. If you edit the example to use a crate-local fn, for example, it does work: http://is.gd/vaEi9C use std::env;
use std::ffi::{OsStr, OsString};
fn test<K:?Sized>(_: &K) -> Option<OsString> where K: AsRef<OsStr> { None }
/* Explicit lifetimes are required by rust-2015-05-11 nightly (newer than playpen) */
fn foo<'a, F>(bar: &'a F) -> Option<OsString>
where F: Fn(&str) -> Option<OsString>
{
bar("HOME")
}
fn main() {
println!("{:?}", foo(&test));
} |
triage: P-high I'm going to mark this as P-high because I agree it is a regression. My guess would be that perhaps it is related to #24615 or some of the other recent changes to trait selection, but I'll have to dive in and trace it out. |
So, I've tracked down the origin, but the code in question has landed in stable already. The cause was commit 9b88cd1. This modified the definition of @@ -197,7 +197,7 @@ pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsRef<OsStr>
/// }
/// ```
#[stable(feature = "env", since = "1.0.0")]
-pub fn var_os<K: ?Sized>(key: &K) -> Option<OsString> where K: AsRef<OsStr> {
+pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
let _g = ENV_LOCK.lock();
os_imp::getenv(key.as_ref())
} One effect of this definition is that let x = var_os;
x(..);
x(..); vs var_os(..);
var_os(..); In this case, the code was capturing a single reference to I'm going to close this, since the code has made it to stable and doesn't seem to have caused dramatic impact, but it's an interesting regression vector. cc @rust-lang/libs <-- this should be kept in mind in the future. |
Ah, I see @pnkfelix suggested the second change already. The reason that this works is that it is equivalent to making one reference to |
Playpen: http://is.gd/LYhXZx
Might be caused by: #25212
I'm unsure if this is an actual issue that can be fixed, but figured I'd open an issue in case it was.
The text was updated successfully, but these errors were encountered: