@@ -216,10 +216,18 @@ impl UnmanagedVector {
216216 match source {
217217 Some ( data) => {
218218 let ( ptr, len, cap) = {
219- // Can be replaced with Vec::into_raw_parts when stable
220- // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.into_raw_parts
221- let mut data = mem:: ManuallyDrop :: new ( data) ;
222- ( data. as_mut_ptr ( ) , data. len ( ) , data. capacity ( ) )
219+ if data. capacity ( ) == 0 {
220+ // we need to explicitly use a null pointer here, since `as_mut_ptr`
221+ // always returns a dangling pointer (e.g. 0x01) on an empty Vec,
222+ // which trips up Go's pointer checks.
223+ // This is safe because the Vec has not allocated, so no memory is leaked.
224+ ( std:: ptr:: null_mut :: < u8 > ( ) , 0 , 0 )
225+ } else {
226+ // Can be replaced with Vec::into_raw_parts when stable
227+ // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.into_raw_parts
228+ let mut data = mem:: ManuallyDrop :: new ( data) ;
229+ ( data. as_mut_ptr ( ) , data. len ( ) , data. capacity ( ) )
230+ }
223231 } ;
224232 Self {
225233 is_none : false ,
@@ -260,6 +268,12 @@ impl UnmanagedVector {
260268 pub fn consume ( self ) -> Option < Vec < u8 > > {
261269 if self . is_none {
262270 None
271+ } else if self . cap == 0 {
272+ // capacity 0 means the vector was never allocated and
273+ // the ptr field does not point to an actual byte buffer
274+ // (we normalize to `null` in `UnmanagedVector::new`),
275+ // so no memory is leaked by ignoring the ptr field here.
276+ Some ( Vec :: new ( ) )
263277 } else {
264278 Some ( unsafe { Vec :: from_raw_parts ( self . ptr , self . len , self . cap ) } )
265279 }
@@ -348,7 +362,7 @@ mod test {
348362 // Empty data
349363 let x = UnmanagedVector :: new ( Some ( vec ! [ ] ) ) ;
350364 assert ! ( !x. is_none) ;
351- assert_eq ! ( x. ptr as usize , 0x01 ) ; // We probably don't get any guarantee for this, but good to know where the 0x01 marker pointer can come from
365+ assert_eq ! ( x. ptr as usize , 0 ) ;
352366 assert_eq ! ( x. len, 0 ) ;
353367 assert_eq ! ( x. cap, 0 ) ;
354368
@@ -372,7 +386,7 @@ mod test {
372386 // Empty data
373387 let x = UnmanagedVector :: some ( vec ! [ ] ) ;
374388 assert ! ( !x. is_none) ;
375- assert_eq ! ( x. ptr as usize , 0x01 ) ; // We probably don't get any guarantee for this, but good to know where the 0x01 marker pointer can come from
389+ assert_eq ! ( x. ptr as usize , 0 ) ;
376390 assert_eq ! ( x. len, 0 ) ;
377391 assert_eq ! ( x. cap, 0 ) ;
378392 }
0 commit comments