Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign uprustc fails to produce lifetime and closure related compiler error. #29793
Comments
huonw
added
A-lifetimes
I-nominated
T-compiler
A-compiler
I-unsound 💥
labels
Nov 12, 2015
mitchmindtree
referenced this issue
Nov 12, 2015
Merged
Fix WidgetMatrix use in all_widgets example #624
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
agreed, seems wrong. sigh. |
This comment has been minimized.
This comment has been minimized.
|
triage: P-high |
rust-highfive
added
P-high
and removed
I-nominated
labels
Nov 12, 2015
nikomatsakis
self-assigned this
Nov 12, 2015
This comment has been minimized.
This comment has been minimized.
|
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? |
This comment has been minimized.
This comment has been minimized.
|
assigning to self to try to help niko with his plate of stuff |
pnkfelix
assigned
pnkfelix
and unassigned
nikomatsakis
Nov 19, 2015
This comment has been minimized.
This comment has been minimized.
|
Okay, I've done something much like what @arielb1 described, namely adding a new I should have a PR up shortly, assuming my |
mitchmindtree commentedNov 12, 2015
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,colandrowvalues.@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.