about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2023-11-08 13:55:21 +0100
committerJosh Stone <jistone@redhat.com>2023-11-09 11:50:40 -0800
commit9425991f0abe1cace3ccd95770a1220a5970436a (patch)
tree96403f3361b25a2198a49c73dce5df3e464833c2
parentc1eb5771f82256b4d5f916629584c18827f59006 (diff)
downloadrust-9425991f0abe1cace3ccd95770a1220a5970436a.tar.gz
rust-9425991f0abe1cace3ccd95770a1220a5970436a.zip
generator layout: ignore fake borrows
(cherry picked from commit a42eca42df821a1d6e74a931195a00258f94bd6a)
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs9
-rw-r--r--compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs2
-rw-r--r--tests/ui/generator/witness-ignore-fake-reads.rs34
3 files changed, 42 insertions, 3 deletions
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index 3ad9d3d4264..749cdba0607 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -5,7 +5,8 @@ use rustc_middle::mir::*;
 use crate::{AnalysisDomain, GenKill, GenKillAnalysis};
 
 /// A dataflow analysis that tracks whether a pointer or reference could possibly exist that points
-/// to a given local.
+/// to a given local. This analysis ignores fake borrows, so it should not be used by
+/// borrowck.
 ///
 /// At present, this is used as a very limited form of alias analysis. For example,
 /// `MaybeBorrowedLocals` is used to compute which locals are live during a yield expression for
@@ -91,13 +92,17 @@ where
         self.super_rvalue(rvalue, location);
 
         match rvalue {
-            Rvalue::AddressOf(_, borrowed_place) | Rvalue::Ref(_, _, borrowed_place) => {
+            // We ignore fake borrows as these get removed after analysis and shouldn't effect
+            // the layout of generators.
+            Rvalue::AddressOf(_, borrowed_place)
+            | Rvalue::Ref(_, BorrowKind::Mut { .. } | BorrowKind::Shared, borrowed_place) => {
                 if !borrowed_place.is_indirect() {
                     self.trans.gen(borrowed_place.local);
                 }
             }
 
             Rvalue::Cast(..)
+            | Rvalue::Ref(_, BorrowKind::Shallow, _)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::Use(..)
             | Rvalue::ThreadLocalRef(..)
diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
index d435d3ee69b..1164dcf29da 100644
--- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
+++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
@@ -4,7 +4,7 @@
 //!
 //!   - [`AscribeUserType`]
 //!   - [`FakeRead`]
-//!   - [`Assign`] statements with a [`Shallow`] borrow
+//!   - [`Assign`] statements with a [`Fake`] borrow
 //!
 //! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType
 //! [`Assign`]: rustc_middle::mir::StatementKind::Assign
diff --git a/tests/ui/generator/witness-ignore-fake-reads.rs b/tests/ui/generator/witness-ignore-fake-reads.rs
new file mode 100644
index 00000000000..ccf9ce8b49e
--- /dev/null
+++ b/tests/ui/generator/witness-ignore-fake-reads.rs
@@ -0,0 +1,34 @@
+// check-pass
+// edition: 2021
+
+// regression test for #117059
+struct SendNotSync(*const ());
+unsafe impl Send for SendNotSync {}
+// impl !Sync for SendNotSync {} // automatically disabled
+
+struct Inner {
+    stream: SendNotSync,
+    state: bool,
+}
+
+struct SendSync;
+impl std::ops::Deref for SendSync {
+    type Target = Inner;
+    fn deref(&self) -> &Self::Target {
+        todo!();
+    }
+}
+
+async fn next() {
+    let inner = SendSync;
+    match inner.state {
+        true if false => {}
+        false => async {}.await,
+        _ => {}
+    }
+}
+
+fn is_send<T: Send>(_: T) {}
+fn main() {
+    is_send(next())
+}