@@ -217,10 +217,18 @@ impl UnmanagedVector {
217
217
match source {
218
218
Some ( data) => {
219
219
let ( ptr, len, cap) = {
220
- // Can be replaced with Vec::into_raw_parts when stable
221
- // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.into_raw_parts
222
- let mut data = mem:: ManuallyDrop :: new ( data) ;
223
- ( data. as_mut_ptr ( ) , data. len ( ) , data. capacity ( ) )
220
+ if data. capacity ( ) == 0 {
221
+ // we need to explicitly use a null pointer here, since `as_mut_ptr`
222
+ // always returns a dangling pointer (e.g. 0x01) on an empty Vec,
223
+ // which trips up Go's pointer checks.
224
+ // This is safe because the Vec has not allocated, so no memory is leaked.
225
+ ( std:: ptr:: null_mut :: < u8 > ( ) , 0 , 0 )
226
+ } else {
227
+ // Can be replaced with Vec::into_raw_parts when stable
228
+ // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.into_raw_parts
229
+ let mut data = mem:: ManuallyDrop :: new ( data) ;
230
+ ( data. as_mut_ptr ( ) , data. len ( ) , data. capacity ( ) )
231
+ }
224
232
} ;
225
233
Self {
226
234
is_none : false ,
@@ -261,6 +269,12 @@ impl UnmanagedVector {
261
269
pub fn consume ( self ) -> Option < Vec < u8 > > {
262
270
if self . is_none {
263
271
None
272
+ } else if self . cap == 0 {
273
+ // capacity 0 means the vector was never allocated and
274
+ // the ptr field does not point to an actual byte buffer
275
+ // (we normalize to `null` in `UnmanagedVector::new`),
276
+ // so no memory is leaked by ignoring the ptr field here.
277
+ Some ( Vec :: new ( ) )
264
278
} else {
265
279
Some ( unsafe { Vec :: from_raw_parts ( self . ptr , self . len , self . cap ) } )
266
280
}
@@ -349,7 +363,7 @@ mod test {
349
363
// Empty data
350
364
let x = UnmanagedVector :: new ( Some ( vec ! [ ] ) ) ;
351
365
assert ! ( !x. is_none) ;
352
- 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
366
+ assert_eq ! ( x. ptr as usize , 0 ) ;
353
367
assert_eq ! ( x. len, 0 ) ;
354
368
assert_eq ! ( x. cap, 0 ) ;
355
369
@@ -373,7 +387,7 @@ mod test {
373
387
// Empty data
374
388
let x = UnmanagedVector :: some ( vec ! [ ] ) ;
375
389
assert ! ( !x. is_none) ;
376
- 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
390
+ assert_eq ! ( x. ptr as usize , 0 ) ;
377
391
assert_eq ! ( x. len, 0 ) ;
378
392
assert_eq ! ( x. cap, 0 ) ;
379
393
}
0 commit comments