From 4f89b4ad7c155bd5930080c23dab52725667fcff Mon Sep 17 00:00:00 2001 From: Mikael Mayer Date: Thu, 24 Oct 2024 08:58:11 -0500 Subject: [PATCH] Fix: Object::from_ref no longer forgetting to increment the strong count. Fixes #5851 I haven't been able to produce consistently any program that could exhibit the issue this PR is solving, the only hint I had that this happened was the report of #5851, which I reasoned manually must come from this function that is being skipped. By making it opaque to the compiler, we prevent optimizations that would skip the strong count from increasing. Alternative to this would be to pass &Rc instead of &Self, which is what https://github.com/dafny-lang/dafny/tree/fix-object-safety-rust does, but &Rc does not make traits object-safe, which means we can't yet use them in the code. I tried also passing a second arguments so that we directly have a `Rc<>` and don't need to recover it from the &T, but `this: Rc` again makes the trait not object-safe, and `this: Rc` causes an issue because we can't create this argument when what we have is only the trait, and trait upcast to Any is currently unsound in Rust. This PR is the best workaround I found so far. --- Source/DafnyRuntime/DafnyRuntimeRust/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/DafnyRuntime/DafnyRuntimeRust/src/lib.rs b/Source/DafnyRuntime/DafnyRuntimeRust/src/lib.rs index 13745ff9c0..75621f33af 100644 --- a/Source/DafnyRuntime/DafnyRuntimeRust/src/lib.rs +++ b/Source/DafnyRuntime/DafnyRuntimeRust/src/lib.rs @@ -3508,7 +3508,8 @@ impl AsRef for Object { fn increment_strong_count(data: *const T) { // SAFETY: This method is called only on values that were constructed from an Rc unsafe { - Rc::increment_strong_count(data); + // Black box avoids the compiler wrongly inferring that increment strong count does nothing since the data it was applied to can be traced to be borrowed + ::std::hint::black_box(Rc::increment_strong_count(data)); } }