-
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
Lifetime inference related regression in latest nightly. #30519
Comments
Minimized: fn main() {
let foo = &mut true;
(|| {
let bar = &mut *foo;
(move |b: bool| *bar = b)
});
} cc @rust-lang/compiler triage: I-nominated |
The code in the example would be broken if I can't get such a "live" example to compile, though. |
This is probably related to the soundness fix that @pnkfelix landed, which required the return types of closures to outlive the call site. |
#30341, more specifically. |
Could someone provide a self-contained environment to compile the |
I've decided that both the original and minified code ought NOT to compile. Both examples, as @arielb1 pointed out, only ever compiled due to a bug. However, it's possible that if we improved closure kind inference, the minified snippet perhaps COULD compile. Let me elaborate. The high-level reason that this code is being rejected is because the outer closure might be called more than once -- in the original code, it most certainly is -- and each call borrows data from the environment and returns it. Those references could well overlap with one another -- and in the minified example, they certainly would, since the data being re-borrowed is just the same value Let me give a more detailed look in terms of the minified example. First, let me define a few terms:
Intuitively, the inner closure (the one being returned), by capturing However, the outer closure does not move In terms of the closure desugaring, the outer closure contains no moves, and hence is an Therefore, to make this particular code snippet compile, we really need an This is a bit of a corner case in the inference, actually. It is impossible to fix in general, but this particular example could be made to work, given a shift in strategy. Currently, we select whether a closure should be
But in this case, the strategy of #2 is insufficient: this is because while it does not move any upvars, it does loan an upvar out for a duration that is longer than the closure call itself. This also requires an Still, it's plausible we could determine that the closure is only ever called once (or, in this case, not ever), and use THAT information to select |
The move-vs-reborrow case is a pretty annoying issue with the borrow checker in general (see @gankro's struggles against it when implementing linked list iterators). I would prefer a more general solution. |
I don't disagree, but the compiler is enforcing the current type system here correctly, afaict. |
current hypothesis is that this represents a bug fix. Nonetheless, triaging as P-medium to investigate and confirm that hypothesis. triage: P-medium |
I can confirm that the minimized example successfully built before #30341 landed. Now attempting to confirm that it did NOT build afterwards. |
OK, confirmed that it did not build afterwards. So this is a bug fix due to #30341. On that basis, I'm inclined to close the issue. Feel free to let me know if you disagree with that assessment! UPDATE: correct from did build to did not build. :) |
Sorry @nikomatsakis , did you mean to say that it did not build afterwards? |
@mitchmindtree yes, corrected, thanks. |
Ok great! Thanks a lot for the thorough explanation on the issue, it's given me enough understanding so that I should be able to easily adjust the original example. |
Travis failed to build one of conrod's examples using the latest nightly due to the following error.
The area of the example code that fails is here.
It was able to build this same example without any problems using the rustc 1.5 stable.
The text was updated successfully, but these errors were encountered: