-
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
Indexing via index
method and [idx]
sugar works differently in async
blocks/functions
#72956
Comments
Self-assigning for mentoring (if someone is interested in working on this, please feel free to claim). |
May be related to #30127 |
@tmandry I am interested in solving this issue or the related issue that you mentioned. I am still fresh in the desugaring process, so I would like to receive your mentoring instruction, if this issue has not been taken. Thank you! |
@dingxiangfei2009 Sorry, I just saw this. You're welcome to pick this up! I'm going to un-assign myself since I haven't had time to look into it. If you're still interested, say |
We did talk about this issue in a recent meeting about this code. Notes are here and should be helpful to anyone interested in picking this up. |
@rustbot claim |
@dingxiangfei2009 Are you still planning to work on this? |
@tmandry Sorry for taking long on this. However, I find it actually harder than I thought. Please allow me to unassign myself first, and propose a concrete plan before working on this. |
No problem. It definitely seems challenging. Feel free to drop by the Zulip stream if you want to talk something out. |
@rustbot claim I started debugging this. The diff of working vs. broken HIR:
The variable I also checked MIR dumps. I'm not sure which MIR file to look at in this sea of files, but in one of the files I see this in the working version:
which becomes this in the failing version
In both cases
|
Ignore my comment above, the changes in HIR are following the changes in the original source so they make sense. |
Sigh.. I just realized that this has nothing to do with MIRs as the error is generated before MIR generation. I was confused because I saw that MIRs are generated for this program, so thought that it should pass type checking etc. and the error is generated after some of the MIR passes. In reality the error is generated in type checking, but we continue with compilation (even with the error) and generate MIR. So I think the bug should be in lowering (from AST to HIR) or type checking. (I'm actively, but somewhat slowly, working on this) |
@rustbot claim |
Note to anyone following this thread who carefully read the link given at this comment above:
someone who read all that stuff and understood it will likely not reap much insight from what I wrote below. (I didn't read it all carefully enough myself before I started my own investigation.) having said that, if you didn't read that or didn't grok it, maybe my notes below will be enlightening. I looked at this a bit today, and (re)discovered something interesting: the expressions In particular, the r-value lifetime rules encoded in rust/compiler/rustc_passes/src/region.rs Lines 643 to 680 in efd0483
The difference being implemented there is that when you have The above explanation may appear a bit abstract. Here's something concrete: a playground showing the compiler accepting one variant and rejecting another, precisely due to this scoping difference: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=9a3a0cb2ac1c7f1e1ac14129dd5a10ab And, in case you (like me at first) think that this might just be a case of our region/borrow-checking rules being overly conservative: Here's another concrete example: a playground showing the difference in the runtime semantics for the two forms. They are truly not synonymous: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=fb37502951f0faa22e17ce9f58c80d7f I note this mainly as a way to say "one should not always expect I am not, however, intending to imply that this issue should just be closed as a "wont fix". I do believe we can put some nicer handling of this case in. I expect it is very common to do (Nonetheless, we cannot "fix" this for 100% of the cases. And even the simple cases might be hard to do properly; e.g. note that just special casing |
This might have potential: compiler/rustc_passes/src/region.rs
--- INDEX/compiler/rustc_passes/src/region.rs
+++ WORKDIR/compiler/rustc_passes/src/region.rs
@@ -676,6 +676,12 @@ fn record_rvalue_scope<'tcx>(
| hir::ExprKind::Unary(hir::UnOp::Deref, ref subexpr)
| hir::ExprKind::Field(ref subexpr, _)
| hir::ExprKind::Index(ref subexpr, _) => {
+ // rust#72956: do not artificially extend `var` region in `let x = var[i];`.
+ if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = subexpr.kind {
+ if let hir::def::Res::Local(_) = path.res {
+ return;
+ }
+ }
expr = &subexpr;
}
_ => { (At least, it seems to handle my reduction of the case written on this issue.) The comment in there might need work. I am still trying to grok the interplay between |
Also, if there is a soundness or backwards compatibility issue with the hypothesized diff to |
(one last note: if anyone's watching this and wants to chime in, feel free to join the zulip topic that I created for it.) |
My co-worker stumbled upon this curious case where failing typecheck can be made to succeed only by making "equivalent" lowerings to code. In particular the following snippet fails to compile because there's a
!Send
type being retained across the yield point:Failing code example
This snippet will fail with the following error (playground):
suggesting that a
&peach
is being retained across the yield pointbaz(r).await
. What is curious, however, that lowering the indexing operation to a method call onIndex
will make code build (playground):Succeeding code example
I’m not sure quite yet whether its incorrect that we successfully build the latter example or incorrect in that we retain an immutable reference in the former example.
The text was updated successfully, but these errors were encountered: