-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
rustc fails to produce lifetime and closure related compiler error. #29793
Comments
I'm looking into this, trying to get a reasonably accurate reproduction and have come across this: fn main() {
let x = Some(|x: usize, y: usize| {
|t: bool| if t { x } else { y }
});
// If the following line is uncommented, it doesn't compile
//use_(x);
}
fn use_<G, F: FnMut(usize, usize) -> G>(f: Option<F>) {
if let Some(mut f) = f {
let _ = f(1, 2);
}
} https://play.rust-lang.org/?gist=b4a25867408e0056c8f3&version=stable Which I believe is related. |
Woo! Took me a while, but here is a minimal(-ish) reproduction (while still being similar to the original example): struct WrapA<F>(Option<F>);
impl<F> WrapA<F> {
fn new() -> WrapA<F> {
WrapA(None)
}
fn set(mut self, f: F) -> Self {
self.0 = Some(f);
self
}
}
struct WrapB<F>(Option<F>);
impl<F> WrapB<F> {
fn new() -> WrapB<F> {
WrapB(None)
}
fn set(mut self, f: F) -> Self {
self.0 = Some(f);
self
}
}
trait DoStuff : Sized {
fn handle(self);
}
impl<F, T> DoStuff for WrapA<F>
where F: FnMut(usize, usize) -> T, T: DoStuff {
fn handle(mut self) {
if let Some(ref mut f) = self.0 {
let x = f(1, 2);
let _foo = [0usize; 16];
x.handle();
}
}
}
impl<F> DoStuff for WrapB<F> where F: FnMut(bool) -> usize {
fn handle(mut self) {
if let Some(ref mut f) = self.0 {
println!("{}", f(true));
}
}
}
impl<F, T> WrapA<F>
where F: FnMut(usize, usize) -> T, T: DoStuff {
fn handle_ref(&mut self) {
if let Some(ref mut f) = self.0 {
let x = f(1, 2);
}
}
}
fn main() {
let mut w = WrapA::new().set(|x: usize, y: usize| {
WrapB::new().set(|t: bool| if t { x } else { y })
})
w.handle(); // This works
// w.handle_ref(); // This doesn't
} https://play.rust-lang.org/?gist=330b4ee92fecd1c8f499&version=stable
Nope, just double-checked and it's actually inherent vs. trait methods. Making an identical |
I decided to go back to my simple case: fn main() {
let _x = |x: usize, y: usize| {
|t: bool| if t { x } else { y }
}; This compiles (and probably shouldn't), while the following doesn't (which is expected): fn main() {
let _x = |x: usize, y: usize| {
let x = x;
let y = y;
|t: bool| if t { x } else { y }
}; This suggests to me that the lifetimes associated with the Also /cc @rust-lang/compiler |
agreed, seems wrong. sigh. |
triage: P-high |
The issue is that: I am not sure of the best way to fix this. Maybe add an actual "root" region wrapping a closure, instead of using the DestructionScope? |
assigning to self to try to help niko with his plate of stuff |
Okay, I've done something much like what @arielb1 described, namely adding a new I should have a PR up shortly, assuming my |
Ensure borrows of fn/closure params do not outlive invocations. Does this by adding a new CallSiteScope to the region (or rather code extent) hierarchy, which outlives even the ParameterScope (which in turn outlives the DestructionScope of a fn/closure's body). Fix #29793 r? @nikomatsakis
This fixes the tests for issue rust-lang#29793
We ran into this in conrod, where one of the widgets would produce different behaviour depending on whether it was compiled in debug or release.
The related conrod issue is here.
This comment describes the strange behaviour more precisely.
This comment demonstrates the fix used.
@huonw and @Aatch helped to point out that the difference in behaviour seemed to be due to the fact that rustc was failing to produce an error relating to the lifetimes of the
demo
,col
androw
values.@Aatch shared a simplified example of what error we should have received here.
Edit: I should mention, this bug was found in:
rustc 1.4.0 (8ab8581f6 2015-10-27)
rustc 1.6.0-nightly (5b4986fa5 2015-11-08)
rustc 1.5.0-beta.2 (b0f440163 2015-10-28)
on both windows and osx.
The text was updated successfully, but these errors were encountered: