From 107cf981d5f122bd8770987eb2d3dfea5b7429e1 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 19 Jul 2024 17:43:33 -0400 Subject: [PATCH] Explain why the new setup can't deadlock --- compiler/rustc_middle/src/mir/interpret/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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; }