about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-08-01 16:49:27 +0200
committerGitHub <noreply@github.com>2022-08-01 16:49:27 +0200
commit58042bffaccb8df5e65c9f86f3b5eec8da193773 (patch)
tree07db07cf2f9c11786c5d73de632ef956ad201c45
parent1f5d8d49eb6111931091f700d07518cd2b80bc18 (diff)
parentd9f28b7b701321d24ff9930b3f7b5d93b6fd671f (diff)
Rollup merge of #99340 - GoldsteinE:fix-localdefid-debug-ice, r=lcnr
Fix ICE in Definitions::create_def

`Debug` implementation for `LocalDefId` uses global `Definitions`. Normally it’s ok, but we can’t do it while holding a mutable reference to `Definitions`, since it causes ICE or deadlock (depending on whether `parallel_compiler` is enabled).

This PR effectively copies the `Debug` implementation into the problematic method. I don’t particularly love this solution (since it creates code duplication), but I don’t see any other options.

This issue was discovered when running `rustdoc` with `RUSTDOC_LOG=trace` on the following file:
```rust
pub struct SomeStruct;

fn asdf() {
    impl SomeStruct {
        pub fn qwop(&self) {
            println!("hidden function");
        }
    }
}
```

I’m not sure how to create a test for this behavior.
-rw-r--r--compiler/rustc_hir/src/definitions.rs7
-rw-r--r--compiler/rustc_middle/src/ty/context.rs4
2 files changed, 8 insertions, 3 deletions
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 5f8801cc4e2..c2c551e78a4 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -338,7 +338,12 @@ impl Definitions {
 
     /// Adds a definition with a parent definition.
     pub fn create_def(&mut self, parent: LocalDefId, data: DefPathData) -> LocalDefId {
-        debug!("create_def(parent={:?}, data={:?})", parent, data);
+        // We can't use `Debug` implementation for `LocalDefId` here, since it tries to acquire a
+        // reference to `Definitions` and we're already holding a mutable reference.
+        debug!(
+            "create_def(parent={}, data={data:?})",
+            self.def_path(parent).to_string_no_crate_verbose(),
+        );
 
         // The root node must be created with `create_root_def()`.
         assert!(data != DefPathData::CrateRoot);
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 2714493b9fc..541763e294f 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1459,11 +1459,11 @@ impl<'tcx> TyCtxt<'tcx> {
         };
 
         format!(
-            "{}[{}]{}",
+            "{}[{:04x}]{}",
             crate_name,
             // Don't print the whole stable crate id. That's just
             // annoying in debug output.
-            &(format!("{:08x}", stable_crate_id.to_u64()))[..4],
+            stable_crate_id.to_u64() >> 8 * 6,
             self.def_path(def_id).to_string_no_crate_verbose()
         )
     }