-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Lifetimes bug on beta 1.31: the associated type may not live long enough #55756
Comments
visiting for T-compiler triage. P-high. Assigning to self for initial investigation. |
Based on crater run, looks like this also affects: |
Bisected against when https://source.that.world/source/evm-rs.git stopped building. Successfully built: rustc 1.30.0-nightly (4141a40 2018-09-25) |
Heres the bors merge record from that time frame: % git log 4141a40..ae7fe84 --format=oneline --author=bors |
The most obvious culprit to my eye is PR #54453. That PR might have been intended to be restricted to NLL, I'm not sure (it touches code outside of rustc_mir, certainly). It does seem like the crate in question is not opting into NLL nor the 2018 editon. Update: of course they aren't opting into NLL. This issue is tagged NLL-fixed-by-NLL |
Here is a reduced test case (play): #![crate_type="lib"]
pub trait Database<'a> {
type Guard: 'a;
}
pub struct Stateful<'a, D: 'a>(&'a D);
impl<'b, D: for <'a> Database<'a>> Stateful<'b, D> {
pub fn callee<'a>(&'a self) -> <D as Database<'a>>::Guard {
unimplemented!()
}
pub fn caller<'a>(&'a self) -> <D as Database<'a>>::Guard {
let state = self.callee();
unimplemented!()
}
} |
I am not sure if I'm going to have time to look into this further before I go on leave (for ~2 weeks), and yet it seems like a potentially important thing to address. Unassigning self. |
I have now confirmed that PR #54453 is what injected this regression. |
I did a bit of investigation. Some internal notes: In the reduced test case, anyway, the problem seems to arise precisely because we are now a bit more flexible than we used to be. In particular, the type of
and we used to convert that into a rule that There is a workaround therefore of adding an explicit type annotation (playground): ...
let state: <D as Database<'a>>::Guard = self.callee();
... I remember that when I was doing this I had some "contingency plans" for handling this scenario should it be a problem. I'll try to remember what they were =) |
Also, it's interesting that NLL makes this test case pass. Off hand, I'm not sure entirely sure why that is. |
OK, so I investigated NLL a bit. The reason is actually somewhat interesting. NLL introduces an additional liveness check -- it says:
This rule is much "cruder" than the outlives check here. In particular, if you have a variable We could adopt a similar distinction in lexical region checking with relative ease -- basically a "live at" relation that is more conservative than outlives. I'm not sure how well justified it is though. (This is a bit weird because of eager normalization: if we were able to normalize |
@nikomatsakis says they know what the problem is and hope to have a fix soon (today). |
Hmm, so, I have a fix. Though looking more closely at the test, I think I see a nicer fix. The problem is that we now observe two potentially applicable rules when trying to find bounds for
Because of this, we decide to take no action to influence inference, which means that My current fix basically overrides this with a coarser rule (one which works fine, however, in this example). A smarter fix would be to observe that the first rule (the one talking about I am trying to decide which approach is lowest risk -- the current fix, as I wrote, actually makes us compatible with how NLL is handling things. I am planning to overhaul this whole setup in the not-that-distinct future, since the current solver is essentially "unnecessarily stupid". Some options:
Given the deadline, I'm leaning towards the first path. |
…es, r=eddyb remove "approx env bounds" if we already know from trait Alternative to rust-lang#55988 that fixes rust-lang#55756 -- smaller fix that I cannot see having (correctness) repercussions beyond the test at hand, and hence better for backporting. (Famous last words, I know.) r? @eddyb
Testing the more conservative fix from #56043: |
btw, in the future, we would definitely appreciate bug reports against nightly! That is indeed part of the point of nightly, to help us find regressions before they make it into beta =) |
I don't know how to test the final two cases that @Mark-Simulacrum cited -- I guess I need to checkout some github repositories? -- but based on the logs they seem like the same root problem and hence I expect it is fixed. |
Yes, you'd need to build https://github.com/ETCDEVTeam/sputnikvm-dev and https://github.com/TheWaWaR/cita-create-genesis to check them locally. |
…es, r=eddyb remove "approx env bounds" if we already know from trait Alternative to rust-lang#55988 that fixes rust-lang#55756 -- smaller fix that I cannot see having (correctness) repercussions beyond the test at hand, and hence better for backporting. (Famous last words, I know.) r? @eddyb
@Mark-Simulacrum
|
Sure, I understand I should've report it once encountered. Would be less stressful for both parties. Thanks for fixing the issue! |
A reduced test case (play):
Error diagnostic output in details block below
Original bug report
Versions
rustc 1.31.0-beta.4 (04da282 2018-11-01)
cargo 1.31.0-beta (efb7972a0 2018-10-24)
Expected behavior
Everything compiling correctly like it does on stable 1.30
Actual behavior
A lot of lifetime-related errors:
It has been an issue in nightly 1.31 for a long time now, but I haven't reported the issue while it was just nightly. Now the regression is in beta channel and may land in stable, breaking existing code.
My own findings on the subject: regression is related to an old lifetime system, it's not reproducible with
nll
feature on, so onnightly
the code can be compiled withnll
, but not without it. Same holds for beta now exceptnll
isn't quite there yet.The subjected codebase: https://github.com/ETCDEVTeam/sputnikvm/tree/master/stateful
The text was updated successfully, but these errors were encountered: