Support converting C `OutPoint`s to `bitcoin` `OutPoint`s
[ldk-c-bindings] / lightning-c-bindings / src / c_types / mod.rs
1 //! This module contains standard C-mapped types for types not in the original crate.
2
3 /// Auto-generated C-mapped types for templated containers
4 pub mod derived;
5
6 use bitcoin::Transaction as BitcoinTransaction;
7 use bitcoin::hashes::Hash;
8 use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;
9 use bitcoin::secp256k1::key::SecretKey as SecpSecretKey;
10 use bitcoin::secp256k1::Signature as SecpSignature;
11 use bitcoin::secp256k1::Error as SecpError;
12 use bitcoin::secp256k1::recovery::RecoveryId;
13 use bitcoin::secp256k1::recovery::RecoverableSignature as SecpRecoverableSignature;
14 use bitcoin::bech32;
15
16 use std::convert::TryInto; // Bindings need at least rustc 1.34
17
18 /// Integer in the range `0..32`
19 #[derive(PartialEq, Eq, Copy, Clone)]
20 #[allow(non_camel_case_types)]
21 #[repr(C)]
22 pub struct u5(u8);
23
24 impl From<bech32::u5> for u5 {
25         fn from(o: bech32::u5) -> Self { Self(o.to_u8()) }
26 }
27 impl Into<bech32::u5> for u5 {
28         fn into(self) -> bech32::u5 { bech32::u5::try_from_u8(self.0).expect("u5 objects must be in the range 0..32") }
29 }
30
31 #[derive(Clone)]
32 #[repr(C)]
33 /// Represents a valid secp256k1 public key serialized in "compressed form" as a 33 byte array.
34 pub struct PublicKey {
35         /// The bytes of the public key
36         pub compressed_form: [u8; 33],
37 }
38 impl PublicKey {
39         pub(crate) fn from_rust(pk: &SecpPublicKey) -> Self {
40                 Self {
41                         compressed_form: pk.serialize(),
42                 }
43         }
44         pub(crate) fn into_rust(&self) -> SecpPublicKey {
45                 SecpPublicKey::from_slice(&self.compressed_form).unwrap()
46         }
47         pub(crate) fn is_null(&self) -> bool { self.compressed_form[..] == [0; 33][..] }
48         pub(crate) fn null() -> Self { Self { compressed_form: [0; 33] } }
49 }
50
51 #[repr(C)]
52 /// Represents a valid secp256k1 secret key serialized as a 32 byte array.
53 pub struct SecretKey {
54         /// The bytes of the secret key
55         pub bytes: [u8; 32],
56 }
57 impl SecretKey {
58         // from_rust isn't implemented for a ref since we just return byte array refs directly
59         pub(crate) fn from_rust(sk: SecpSecretKey) -> Self {
60                 let mut bytes = [0; 32];
61                 bytes.copy_from_slice(&sk[..]);
62                 Self { bytes }
63         }
64         pub(crate) fn into_rust(&self) -> SecpSecretKey {
65                 SecpSecretKey::from_slice(&self.bytes).unwrap()
66         }
67 }
68
69 #[repr(C)]
70 #[derive(Clone)]
71 /// Represents a secp256k1 signature serialized as two 32-byte numbers
72 pub struct Signature {
73         /// The bytes of the signature in "compact" form
74         pub compact_form: [u8; 64],
75 }
76 impl Signature {
77         pub(crate) fn from_rust(pk: &SecpSignature) -> Self {
78                 Self {
79                         compact_form: pk.serialize_compact(),
80                 }
81         }
82         pub(crate) fn into_rust(&self) -> SecpSignature {
83                 SecpSignature::from_compact(&self.compact_form).unwrap()
84         }
85         // The following are used for Option<Signature> which we support, but don't use anymore
86         #[allow(unused)] pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
87         #[allow(unused)] pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
88 }
89
90 #[repr(C)]
91 #[derive(Clone)]
92 /// Represents a secp256k1 signature serialized as two 32-byte numbers as well as a tag which
93 /// allows recovering the exact public key which created the signature given the message.
94 pub struct RecoverableSignature {
95         /// The bytes of the signature in "compact" form plus a "Recovery ID" which allows for
96         /// recovery.
97         pub serialized_form: [u8; 68],
98 }
99 impl RecoverableSignature {
100         pub(crate) fn from_rust(pk: &SecpRecoverableSignature) -> Self {
101                 let (id, compact_form) = pk.serialize_compact();
102                 let mut serialized_form = [0; 68];
103                 serialized_form[0..64].copy_from_slice(&compact_form[..]);
104                 serialized_form[64..].copy_from_slice(&id.to_i32().to_le_bytes());
105                 Self { serialized_form }
106         }
107         pub(crate) fn into_rust(&self) -> SecpRecoverableSignature {
108                 let mut id = [0; 4];
109                 id.copy_from_slice(&self.serialized_form[64..]);
110                 SecpRecoverableSignature::from_compact(&self.serialized_form[0..64],
111                                 RecoveryId::from_i32(i32::from_le_bytes(id)).expect("Invalid Recovery ID"))
112                         .unwrap()
113         }
114 }
115
116 #[repr(C)]
117 #[derive(Copy, Clone)]
118 /// Represents an error returned from libsecp256k1 during validation of some secp256k1 data
119 pub enum Secp256k1Error {
120         /// Signature failed verification
121         IncorrectSignature,
122         /// Badly sized message ("messages" are actually fixed-sized digests; see the MESSAGE_SIZE constant)
123         InvalidMessage,
124         /// Bad public key
125         InvalidPublicKey,
126         /// Bad signature
127         InvalidSignature,
128         /// Bad secret key
129         InvalidSecretKey,
130         /// Bad recovery id
131         InvalidRecoveryId,
132         /// Invalid tweak for add_assign or mul_assign
133         InvalidTweak,
134         /// tweak_add_check failed on an xonly public key
135         TweakCheckFailed,
136         /// Didn't pass enough memory to context creation with preallocated memory
137         NotEnoughMemory,
138 }
139 impl Secp256k1Error {
140         pub(crate) fn from_rust(err: SecpError) -> Self {
141                 match err {
142                         SecpError::IncorrectSignature => Secp256k1Error::IncorrectSignature,
143                         SecpError::InvalidMessage => Secp256k1Error::InvalidMessage,
144                         SecpError::InvalidPublicKey => Secp256k1Error::InvalidPublicKey,
145                         SecpError::InvalidSignature => Secp256k1Error::InvalidSignature,
146                         SecpError::InvalidSecretKey => Secp256k1Error::InvalidSecretKey,
147                         SecpError::InvalidRecoveryId => Secp256k1Error::InvalidRecoveryId,
148                         SecpError::InvalidTweak => Secp256k1Error::InvalidTweak,
149                         SecpError::TweakCheckFailed => Secp256k1Error::TweakCheckFailed,
150                         SecpError::NotEnoughMemory => Secp256k1Error::NotEnoughMemory,
151                 }
152         }
153 }
154
155 #[repr(C)]
156 #[allow(missing_docs)] // If there's no docs upstream, that's good enough for us
157 #[derive(Clone, Copy, PartialEq)]
158 /// Represents an IO Error. Note that some information is lost in the conversion from Rust.
159 pub enum IOError {
160         NotFound,
161         PermissionDenied,
162         ConnectionRefused,
163         ConnectionReset,
164         ConnectionAborted,
165         NotConnected,
166         AddrInUse,
167         AddrNotAvailable,
168         BrokenPipe,
169         AlreadyExists,
170         WouldBlock,
171         InvalidInput,
172         InvalidData,
173         TimedOut,
174         WriteZero,
175         Interrupted,
176         Other,
177         UnexpectedEof,
178 }
179 impl IOError {
180         pub(crate) fn from_rust(err: std::io::Error) -> Self {
181                 match err.kind() {
182                         std::io::ErrorKind::NotFound => IOError::NotFound,
183                         std::io::ErrorKind::PermissionDenied => IOError::PermissionDenied,
184                         std::io::ErrorKind::ConnectionRefused => IOError::ConnectionRefused,
185                         std::io::ErrorKind::ConnectionReset => IOError::ConnectionReset,
186                         std::io::ErrorKind::ConnectionAborted => IOError::ConnectionAborted,
187                         std::io::ErrorKind::NotConnected => IOError::NotConnected,
188                         std::io::ErrorKind::AddrInUse => IOError::AddrInUse,
189                         std::io::ErrorKind::AddrNotAvailable => IOError::AddrNotAvailable,
190                         std::io::ErrorKind::BrokenPipe => IOError::BrokenPipe,
191                         std::io::ErrorKind::AlreadyExists => IOError::AlreadyExists,
192                         std::io::ErrorKind::WouldBlock => IOError::WouldBlock,
193                         std::io::ErrorKind::InvalidInput => IOError::InvalidInput,
194                         std::io::ErrorKind::InvalidData => IOError::InvalidData,
195                         std::io::ErrorKind::TimedOut => IOError::TimedOut,
196                         std::io::ErrorKind::WriteZero => IOError::WriteZero,
197                         std::io::ErrorKind::Interrupted => IOError::Interrupted,
198                         std::io::ErrorKind::Other => IOError::Other,
199                         std::io::ErrorKind::UnexpectedEof => IOError::UnexpectedEof,
200                         _ => IOError::Other,
201                 }
202         }
203         pub(crate) fn to_rust(&self) -> std::io::Error {
204                 std::io::Error::new(match self {
205                         IOError::NotFound => std::io::ErrorKind::NotFound,
206                         IOError::PermissionDenied => std::io::ErrorKind::PermissionDenied,
207                         IOError::ConnectionRefused => std::io::ErrorKind::ConnectionRefused,
208                         IOError::ConnectionReset => std::io::ErrorKind::ConnectionReset,
209                         IOError::ConnectionAborted => std::io::ErrorKind::ConnectionAborted,
210                         IOError::NotConnected => std::io::ErrorKind::NotConnected,
211                         IOError::AddrInUse => std::io::ErrorKind::AddrInUse,
212                         IOError::AddrNotAvailable => std::io::ErrorKind::AddrNotAvailable,
213                         IOError::BrokenPipe => std::io::ErrorKind::BrokenPipe,
214                         IOError::AlreadyExists => std::io::ErrorKind::AlreadyExists,
215                         IOError::WouldBlock => std::io::ErrorKind::WouldBlock,
216                         IOError::InvalidInput => std::io::ErrorKind::InvalidInput,
217                         IOError::InvalidData => std::io::ErrorKind::InvalidData,
218                         IOError::TimedOut => std::io::ErrorKind::TimedOut,
219                         IOError::WriteZero => std::io::ErrorKind::WriteZero,
220                         IOError::Interrupted => std::io::ErrorKind::Interrupted,
221                         IOError::Other => std::io::ErrorKind::Other,
222                         IOError::UnexpectedEof => std::io::ErrorKind::UnexpectedEof,
223                 }, "")
224         }
225 }
226
227 #[repr(C)]
228 /// A serialized transaction, in (pointer, length) form.
229 ///
230 /// This type optionally owns its own memory, and thus the semantics around access change based on
231 /// the `data_is_owned` flag. If `data_is_owned` is set, you must call `Transaction_free` to free
232 /// the underlying buffer before the object goes out of scope. If `data_is_owned` is not set, any
233 /// access to the buffer after the scope in which the object was provided to you is invalid. eg,
234 /// access after you return from the call in which a `!data_is_owned` `Transaction` is provided to
235 /// you would be invalid.
236 ///
237 /// Note that, while it may change in the future, because transactions on the Rust side are stored
238 /// in a deserialized form, all `Transaction`s generated on the Rust side will have `data_is_owned`
239 /// set. Similarly, while it may change in the future, all `Transaction`s you pass to Rust may have
240 /// `data_is_owned` either set or unset at your discretion.
241 pub struct Transaction {
242         /// The serialized transaction data.
243         ///
244         /// This is non-const for your convenience, an object passed to Rust is never written to.
245         pub data: *mut u8,
246         /// The length of the serialized transaction
247         pub datalen: usize,
248         /// Whether the data pointed to by `data` should be freed or not.
249         pub data_is_owned: bool,
250 }
251 impl Transaction {
252         fn from_vec(vec: Vec<u8>) -> Self {
253                 let datalen = vec.len();
254                 let data = Box::into_raw(vec.into_boxed_slice());
255                 Self {
256                         data: unsafe { (*data).as_mut_ptr() },
257                         datalen,
258                         data_is_owned: true,
259                 }
260         }
261         pub(crate) fn into_bitcoin(&self) -> BitcoinTransaction {
262                 if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); }
263                 ::bitcoin::consensus::encode::deserialize(unsafe { std::slice::from_raw_parts(self.data, self.datalen) }).unwrap()
264         }
265         pub(crate) fn from_bitcoin(btc: &BitcoinTransaction) -> Self {
266                 let vec = ::bitcoin::consensus::encode::serialize(btc);
267                 Self::from_vec(vec)
268         }
269 }
270 impl Drop for Transaction {
271         fn drop(&mut self) {
272                 if self.data_is_owned && self.datalen != 0 {
273                         let _ = derived::CVec_u8Z { data: self.data as *mut u8, datalen: self.datalen };
274                 }
275         }
276 }
277 impl Clone for Transaction {
278         fn clone(&self) -> Self {
279                 let sl = unsafe { std::slice::from_raw_parts(self.data, self.datalen) };
280                 let mut v = Vec::new();
281                 v.extend_from_slice(&sl);
282                 Self::from_vec(v)
283         }
284 }
285 #[no_mangle]
286 /// Frees the data buffer, if data_is_owned is set and datalen > 0.
287 pub extern "C" fn Transaction_free(_res: Transaction) { }
288
289 pub(crate) fn bitcoin_to_C_outpoint(outpoint: ::bitcoin::blockdata::transaction::OutPoint) -> crate::lightning::chain::transaction::OutPoint {
290         crate::lightning::chain::transaction::OutPoint_new(ThirtyTwoBytes { data: outpoint.txid.into_inner() }, outpoint.vout.try_into().unwrap())
291 }
292 pub(crate) fn C_to_bitcoin_outpoint(outpoint: crate::lightning::chain::transaction::OutPoint) -> ::bitcoin::blockdata::transaction::OutPoint {
293         unsafe {
294                 ::bitcoin::blockdata::transaction::OutPoint {
295                         txid: (*outpoint.inner).txid, vout: (*outpoint.inner).index as u32
296                 }
297         }
298 }
299
300 #[repr(C)]
301 #[derive(Clone)]
302 /// A transaction output including a scriptPubKey and value.
303 /// This type *does* own its own memory, so must be free'd appropriately.
304 pub struct TxOut {
305         /// The script_pubkey in this output
306         pub script_pubkey: derived::CVec_u8Z,
307         /// The value, in satoshis, of this output
308         pub value: u64,
309 }
310
311 impl TxOut {
312         pub(crate) fn into_rust(mut self) -> ::bitcoin::blockdata::transaction::TxOut {
313                 ::bitcoin::blockdata::transaction::TxOut {
314                         script_pubkey: self.script_pubkey.into_rust().into(),
315                         value: self.value,
316                 }
317         }
318         pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
319                 Self {
320                         script_pubkey: derived::CVec_u8Z::from(txout.script_pubkey.into_bytes()),
321                         value: txout.value
322                 }
323         }
324 }
325
326 #[no_mangle]
327 /// Convenience function for constructing a new TxOut
328 pub extern "C" fn TxOut_new(script_pubkey: derived::CVec_u8Z, value: u64) -> TxOut {
329         TxOut { script_pubkey, value }
330 }
331 #[no_mangle]
332 /// Frees the data pointed to by script_pubkey.
333 pub extern "C" fn TxOut_free(_res: TxOut) { }
334 #[no_mangle]
335 /// Creates a new TxOut which has the same data as `orig` but with a new script buffer.
336 pub extern "C" fn TxOut_clone(orig: &TxOut) -> TxOut { orig.clone() }
337
338 #[repr(C)]
339 /// A "slice" referencing some byte array. This is simply a length-tagged pointer which does not
340 /// own the memory pointed to by data.
341 pub struct u8slice {
342         /// A pointer to the byte buffer
343         pub data: *const u8,
344         /// The number of bytes pointed to by `data`.
345         pub datalen: usize
346 }
347 impl u8slice {
348         pub(crate) fn from_slice(s: &[u8]) -> Self {
349                 Self {
350                         data: s.as_ptr(),
351                         datalen: s.len(),
352                 }
353         }
354         pub(crate) fn to_slice(&self) -> &[u8] {
355                 if self.datalen == 0 { return &[]; }
356                 unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
357         }
358 }
359
360 #[repr(C)]
361 #[derive(Copy, Clone)]
362 /// Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
363 /// look up the corresponding function in rust-lightning's docs.
364 pub struct ThirtyTwoBytes {
365         /// The thirty-two bytes
366         pub data: [u8; 32],
367 }
368 impl ThirtyTwoBytes {
369         pub(crate) fn null() -> Self {
370                 Self { data: [0; 32] }
371         }
372 }
373
374 #[repr(C)]
375 /// A 3-byte byte array.
376 pub struct ThreeBytes { /** The three bytes */ pub data: [u8; 3], }
377 #[derive(Clone)]
378 #[repr(C)]
379 /// A 4-byte byte array.
380 pub struct FourBytes { /** The four bytes */ pub data: [u8; 4], }
381 #[derive(Clone)]
382 #[repr(C)]
383 /// A 10-byte byte array.
384 pub struct TenBytes { /** The ten bytes */ pub data: [u8; 10], }
385 #[derive(Clone)]
386 #[repr(C)]
387 /// A 16-byte byte array.
388 pub struct SixteenBytes { /** The sixteen bytes */ pub data: [u8; 16], }
389 #[derive(Clone)]
390 #[repr(C)]
391 /// A 20-byte byte array.
392 pub struct TwentyBytes { /** The twenty bytes */ pub data: [u8; 20], }
393
394 pub(crate) struct VecWriter(pub Vec<u8>);
395 impl lightning::util::ser::Writer for VecWriter {
396         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
397                 self.0.extend_from_slice(buf);
398                 Ok(())
399         }
400 }
401 pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
402         let mut out = VecWriter(Vec::new());
403         i.write(&mut out).unwrap();
404         derived::CVec_u8Z::from(out.0)
405 }
406 pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
407         I::read(&mut s.to_slice())
408 }
409 pub(crate) fn deserialize_obj_arg<A, I: lightning::util::ser::ReadableArgs<A>>(s: u8slice, args: A) -> Result<I, lightning::ln::msgs::DecodeError> {
410         I::read(&mut s.to_slice(), args)
411 }
412
413 #[repr(C)]
414 #[derive(Clone)]
415 /// A Rust str object, ie a reference to a UTF8-valid string.
416 /// This is *not* null-terminated so cannot be used directly as a C string!
417 pub struct Str {
418         /// A pointer to the string's bytes, in UTF8 encoding
419         pub chars: *const u8,
420         /// The number of bytes (not characters!) pointed to by `chars`
421         pub len: usize,
422         /// Whether the data pointed to by `chars` should be freed or not.
423         pub chars_is_owned: bool,
424 }
425 impl Into<Str> for &'static str {
426         fn into(self) -> Str {
427                 Str { chars: self.as_ptr(), len: self.len(), chars_is_owned: false }
428         }
429 }
430 impl Str {
431         pub(crate) fn into_str(&self) -> &'static str {
432                 if self.len == 0 { return ""; }
433                 std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap()
434         }
435         pub(crate) fn into_string(mut self) -> String {
436                 let bytes = if self.len == 0 {
437                         Vec::new()
438                 } else if self.chars_is_owned {
439                         let ret = unsafe {
440                                 Box::from_raw(std::slice::from_raw_parts_mut(unsafe { self.chars as *mut u8 }, self.len))
441                         }.into();
442                         self.chars_is_owned = false;
443                         ret
444                 } else {
445                         let mut ret = Vec::with_capacity(self.len);
446                         ret.extend_from_slice(unsafe { std::slice::from_raw_parts(self.chars, self.len) });
447                         ret
448                 };
449                 String::from_utf8(bytes).unwrap()
450         }
451 }
452 impl Into<Str> for String {
453         fn into(self) -> Str {
454                 let s = Box::leak(self.into_boxed_str());
455                 Str { chars: s.as_ptr(), len: s.len(), chars_is_owned: true }
456         }
457 }
458
459 impl Drop for Str {
460         fn drop(&mut self) {
461                 if self.chars_is_owned && self.len != 0 {
462                         let _ = derived::CVec_u8Z { data: self.chars as *mut u8, datalen: self.len };
463                 }
464         }
465 }
466 #[no_mangle]
467 /// Frees the data buffer, if chars_is_owned is set and len > 0.
468 pub extern "C" fn Str_free(_res: Str) { }
469
470 // Note that the C++ headers memset(0) all the Templ types to avoid deallocation!
471 // Thus, they must gracefully handle being completely null in _free.
472
473 // TODO: Integer/bool primitives should avoid the pointer indirection for underlying types
474 // everywhere in the containers.
475
476 #[repr(C)]
477 pub(crate) union CResultPtr<O, E> {
478         pub(crate) result: *mut O,
479         pub(crate) err: *mut E,
480 }
481 #[repr(C)]
482 pub(crate) struct CResultTempl<O, E> {
483         pub(crate) contents: CResultPtr<O, E>,
484         pub(crate) result_ok: bool,
485 }
486 impl<O, E> CResultTempl<O, E> {
487         pub(crate) extern "C" fn ok(o: O) -> Self {
488                 CResultTempl {
489                         contents: CResultPtr {
490                                 result: Box::into_raw(Box::new(o)),
491                         },
492                         result_ok: true,
493                 }
494         }
495         pub(crate) extern "C" fn err(e: E) -> Self {
496                 CResultTempl {
497                         contents: CResultPtr {
498                                 err: Box::into_raw(Box::new(e)),
499                         },
500                         result_ok: false,
501                 }
502         }
503 }
504 impl<O, E> Drop for CResultTempl<O, E> {
505         fn drop(&mut self) {
506                 if self.result_ok {
507                         if unsafe { !self.contents.result.is_null() } {
508                                 unsafe { Box::from_raw(self.contents.result) };
509                         }
510                 } else if unsafe { !self.contents.err.is_null() } {
511                         unsafe { Box::from_raw(self.contents.err) };
512                 }
513         }
514 }
515
516 /// Utility to make it easy to set a pointer to null and get its original value in line.
517 pub(crate) trait TakePointer<T> {
518         fn take_ptr(&mut self) -> T;
519 }
520 impl<T> TakePointer<*const T> for *const T {
521         fn take_ptr(&mut self) -> *const T {
522                 let ret = *self;
523                 *self = std::ptr::null();
524                 ret
525         }
526 }
527 impl<T> TakePointer<*mut T> for *mut T {
528         fn take_ptr(&mut self) -> *mut T {
529                 let ret = *self;
530                 *self = std::ptr::null_mut();
531                 ret
532         }
533 }
534
535
536 pub(crate) mod ObjOps {
537         #[inline]
538         #[must_use = "returns new dangling pointer"]
539         pub(crate) fn heap_alloc<T>(obj: T) -> *mut T {
540                 let ptr = Box::into_raw(Box::new(obj));
541                 nonnull_ptr_to_inner(ptr)
542         }
543         #[inline]
544         pub(crate) fn nonnull_ptr_to_inner<T>(ptr: *const T) -> *mut T {
545                 if core::mem::size_of::<T>() == 0 {
546                         // We map `None::<T>` as `T { inner: null, .. }` which works great for all
547                         // non-Zero-Sized-Types `T`.
548                         // For ZSTs, we need to differentiate between null implying `None` and null implying
549                         // `Some` with no allocation.
550                         // Thus, for ZSTs, we add one (usually) page here, which should always be aligned.
551                         // Note that this relies on undefined behavior! A pointer to NULL may be valid, but a
552                         // pointer to NULL + 4096 is almost certainly not. That said, Rust's existing use of
553                         // `(*mut T)1` for the pointer we're adding to is also not defined, so we should be
554                         // fine.
555                         // Note that we add 4095 here as at least the Java client assumes that the low bit on
556                         // any heap pointer is 0, which is generally provided by malloc, but which is not true
557                         // for ZSTs "allocated" by `Box::new`.
558                         debug_assert_eq!(ptr as usize, 1);
559                         unsafe { (ptr as *mut T).cast::<u8>().add(4096 - 1).cast::<T>() }
560                 } else {
561                         // In order to get better test coverage, also increment non-ZST pointers with
562                         // --cfg=test_mod_pointers, which is set in genbindings.sh for debug builds.
563                         #[cfg(test_mod_pointers)]
564                         unsafe { (ptr as *mut T).cast::<u8>().add(4096).cast::<T>() }
565                         #[cfg(not(test_mod_pointers))]
566                         unsafe { ptr as *mut T }
567                 }
568         }
569         #[inline]
570         /// Invert nonnull_ptr_to_inner
571         pub(crate) fn untweak_ptr<T>(ptr: *mut T) -> *mut T {
572                 if core::mem::size_of::<T>() == 0 {
573                         unsafe { ptr.cast::<u8>().sub(4096 - 1).cast::<T>() }
574                 } else {
575                         #[cfg(test_mod_pointers)]
576                         unsafe { ptr.cast::<u8>().sub(4096).cast::<T>() }
577                         #[cfg(not(test_mod_pointers))]
578                         ptr
579                 }
580         }
581 }