about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Kimock <kimockb@gmail.com>2024-07-19 17:43:33 -0400
committerBen Kimock <kimockb@gmail.com>2024-07-21 12:31:25 -0400
commit107cf981d5f122bd8770987eb2d3dfea5b7429e1 (patch)
treea161a0558f5f64fd7ce37a4f71f06851ef839164
parent3623c76acb42bbf31fa9323276f2ac7fd936693d (diff)
downloadrust-107cf981d5f122bd8770987eb2d3dfea5b7429e1.tar.gz
rust-107cf981d5f122bd8770987eb2d3dfea5b7429e1.zip
Explain why the new setup can't deadlock
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs14
1 files changed, 13 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 5f2b23e4d82..7d0a944064a 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -206,9 +206,21 @@ impl<'s> AllocDecodingSession<'s> {
             (alloc_kind, decoder.position())
         });
 
+        // We are going to hold this lock during the entire decoding of this allocation, which may
+        // require that we decode other allocations. This cannot deadlock for two reasons:
+        //
+        // At the time of writing, it is only possible to create an allocation that contains a pointer
+        // to itself using the const_allocate intrinsic (which is for testing only), and even attempting
+        // to evaluate such consts blows the stack. If we ever grow a mechanism for producing
+        // cyclic allocations, we will need a new strategy for decoding that doesn't bring back
+        // https://github.com/rust-lang/rust/issues/126741.
+        //
+        // It is also impossible to create two allocations (call them A and B) where A is a pointer to B, and B
+        // is a pointer to A, because attempting to evaluate either of those consts will produce a
+        // query cycle, failing compilation.
+        let mut entry = self.state.decoding_state[idx].lock();
         // Check the decoding state to see if it's already decoded or if we should
         // decode it here.
-        let mut entry = self.state.decoding_state[idx].lock();
         if let State::Done(alloc_id) = *entry {
             return alloc_id;
         }