You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
NLL: regressions due to weakness in two-phase borrows #52934
changed the title [-]NLL: régressions due to weakness in two-phase borrows [/-][+]NLL: regressions due to weakness in two-phase borrows [/+]on Aug 1, 2018
Based on the contents of rust-lang/rust-clippy#2982, it appears @pnkfelix that you now believe these to be legitimate regressions (i.e., NLL-fixed-by-NLL)? I'm inclined therefore to close this issue? Or am I wrong...
Hmm, I think I would like to have some minimized reproductions of the cases in question prior to closing. I'd like to look at just what was making them fail before and convince myself that the new behavior is not going to have problems like #38899 (that particular problem does not reoccur, I tested :)
Okay here is a somewhat minimized test. (I say "somewhat" because there are trivial ways to further reduce it that would obscure its origins within clippy and librustc. I think think this minimization represents a sweet spot in terms of inferring the relationship with the original source.)
Result of investigating case 1: The reason that the call to self.hash_expr is allowed there, AFAICT, is that self has an immutable borrow somewhere along the path from it to the AST map it borrows, and therefore a &mut self still cannot do anything to interfere with the result of the &self.cx.body(..).value.
I think case 2 is another instance of the same phenomenon: the Registry has only an immutable reference to the Session, and so the reg.register_late_lint_pass does not interfere with the ®.sess.target borrow.
Hmm I may have spoken too soon for case 2; unlike the previous analysis, changing to struct Registry<'a> { sess: &'a mut Session } does not cause the compiler to start rejecting the example. Investigating now.
Oh, I think this explains it: in both the original source and in my minimization, struct TriviallyCopyPassByRef carries no references (and has no lifetimes on its type). That might explain why changing the registry to have a &mut Session did not cause any errors to trigger.
One might reasonably wonder: "Wait, what do those examples (case 1 and 2 from my above comment) have to do with two-phase borrows."
I think the best answer to might be for me to just add two tests using revisions to illustrate the cases here, with a revision set like { borrowck=ast, borrowck=mir, borrowck=mir+two-phase-borrows }, and then that should show how the errors arise when you leave out support for two-phase-borrows.
Activity
[-]NLL: régressions due to weakness in two-phase borrows [/-][+]NLL: regressions due to weakness in two-phase borrows [/+]pnkfelix commentedon Aug 3, 2018
(its also possible that rust-lang/rust-clippy#2982 was in fact due to this oversight in the 2018 migration mode: #52967 )
nikomatsakis commentedon Aug 21, 2018
Based on the contents of rust-lang/rust-clippy#2982, it appears @pnkfelix that you now believe these to be legitimate regressions (i.e., NLL-fixed-by-NLL)? I'm inclined therefore to close this issue? Or am I wrong...
nikomatsakis commentedon Aug 21, 2018
Leaving untriaged for now.
nikomatsakis commentedon Aug 27, 2018
Nominating for discussion — probably we can just close this? I put it on the milestone too just to help us keep things tidy
nikomatsakis commentedon Aug 27, 2018
Hmm, I think I would like to have some minimized reproductions of the cases in question prior to closing. I'd like to look at just what was making them fail before and convince myself that the new behavior is not going to have problems like #38899 (that particular problem does not reoccur, I tested :)
4 remaining items
pnkfelix commentedon Sep 3, 2018
Okay here is a somewhat minimized test. (I say "somewhat" because there are trivial ways to further reduce it that would obscure its origins within clippy and librustc. I think think this minimization represents a sweet spot in terms of inferring the relationship with the original source.)
playground link
pnkfelix commentedon Sep 3, 2018
Now, having done the minimization, there are two cases to consider:
self.hash_expr(&self.cx.body(..).value)invocations on lines 20 and 23,reg.register_late_lint_pass(Box::new(Thing::new(®.sess.target)))invocation on line 45I think niko has already expressed a little concern about case 1 in a comment here on the clippy repo.
(I want to look a little more carefully at both cases before I add more notes...)
pnkfelix commentedon Sep 3, 2018
Result of investigating case 1: The reason that the call to
self.hash_expris allowed there, AFAICT, is thatselfhas an immutable borrow somewhere along the path from it to the AST map it borrows, and therefore a&mut selfstill cannot do anything to interfere with the result of the&self.cx.body(..).value.For example, this works: https://play.rust-lang.org/?gist=bd9009010499a92e0cfb9985d7bf1330&version=nightly&mode=debug&edition=2018
But if I change the latter to mutably borrow the AST map from
SpanlessHash, it stops working: https://play.rust-lang.org/?gist=b3e05fdc13eff13093541487df2bfa06&version=nightly&mode=debug&edition=2018This is enough to convince me that we aren't seeing evidence of unsoundness from case 1 in my previous comment.
(I'm going to dive into case 2 next.)
pnkfelix commentedon Sep 3, 2018
I think case 2 is another instance of the same phenomenon: the
Registryhas only an immutable reference to theSession, and so thereg.register_late_lint_passdoes not interfere with the®.sess.targetborrow.pnkfelix commentedon Sep 3, 2018
Hmm I may have spoken too soon for case 2; unlike the previous analysis, changing to
struct Registry<'a> { sess: &'a mut Session }does not cause the compiler to start rejecting the example. Investigating now.pnkfelix commentedon Sep 3, 2018
Oh, I think this explains it: in both the original source and in my minimization,
struct TriviallyCopyPassByRefcarries no references (and has no lifetimes on its type). That might explain why changing the registry to have a&mut Sessiondid not cause any errors to trigger.But if you change to a
&mut Sessionand switch back to the 2015 edition, it will: https://play.rust-lang.org/?gist=30fae44818a42cd3f931493180199743&version=nightly&mode=debug&edition=2015pnkfelix commentedon Sep 4, 2018
One might reasonably wonder: "Wait, what do those examples (case 1 and 2 from my above comment) have to do with two-phase borrows."
I think the best answer to might be for me to just add two tests using revisions to illustrate the cases here, with a revision set like { borrowck=ast, borrowck=mir, borrowck=mir+two-phase-borrows }, and then that should show how the errors arise when you leave out support for two-phase-borrows.
pnkfelix commentedon Sep 4, 2018
(I have a test written up, will post a PR soon.)
Minimized (and then greatly expanded) test of failure cases from rust…