diff --git a/crates/libs/windows/src/core/hstring.rs b/crates/libs/windows/src/core/hstring.rs index 65c50b51bc..611293f33a 100644 --- a/crates/libs/windows/src/core/hstring.rs +++ b/crates/libs/windows/src/core/hstring.rs @@ -1,6 +1,6 @@ use super::*; -/// A WinRT string ([HSTRING](https://docs.microsoft.com/en-us/windows/win32/winrt/hstring)), +/// A WinRT string ([HSTRING](https://docs.microsoft.com/en-us/windows/win32/winrt/hstring)) /// is reference-counted and immutable. #[repr(transparent)] pub struct HSTRING(*mut Header); @@ -53,27 +53,6 @@ impl HSTRING { std::os::windows::ffi::OsStringExt::from_wide(self.as_wide()) } - /// Clear the contents of the string and free the memory if `self` holds the - /// last reference to the string data. - pub fn clear(&mut self) { - if self.is_empty() { - return; - } - - unsafe { - // This flag indicates a "fast pass" string created by some languages where the - // header is allocated on the stack. Such strings must never be freed. - let header = self.0; - debug_assert!((*header).flags & REFERENCE_FLAG == 0); - - if (*header).count.release() == 0 { - heap_free(self.0 as RawPtr); - } - } - - self.0 = core::ptr::null_mut(); - } - /// # Safety /// len must not be less than the number of items in the iterator. unsafe fn from_wide_iter>(iter: I, len: u32) -> Self { @@ -128,7 +107,23 @@ impl Clone for HSTRING { impl Drop for HSTRING { fn drop(&mut self) { - self.clear(); + if self.is_empty() { + return; + } + + unsafe { + let header = std::mem::replace(&mut self.0, core::ptr::null_mut()); + // This flag indicates a "fast pass" string created by some languages where the + // header is allocated on the stack. "Fast pass" strings can only ever be used + // as non-owned input params and as such `drop` will never be called. This check + // just ensures the Rust translation never accidentally modeled "fast pass" input + // params as owned `HSTRING` types which would be a bug in the translation. + debug_assert!((*header).flags & REFERENCE_FLAG == 0); + + if (*header).count.release() == 0 { + heap_free(header as RawPtr); + } + } } } diff --git a/crates/tests/core/tests/hstrings.rs b/crates/tests/core/tests/hstrings.rs index 7f117e033f..d856551502 100644 --- a/crates/tests/core/tests/hstrings.rs +++ b/crates/tests/core/tests/hstrings.rs @@ -7,7 +7,7 @@ fn hstring_works() { assert!(empty.is_empty()); assert!(empty.is_empty()); - let mut hello = HSTRING::from("Hello"); + let hello = HSTRING::from("Hello"); assert!(!hello.is_empty()); assert!(hello.len() == 5); @@ -16,10 +16,6 @@ fn hstring_works() { assert!(rust.len() == 5); let hello2 = hello.clone(); - hello.clear(); - assert!(hello.is_empty()); - hello.clear(); - assert!(hello.is_empty()); assert!(!hello2.is_empty()); assert!(hello2.len() == 5);