@@ -299,24 +299,25 @@ const _: () = unsafe {
299299
300300// SAFETY: The following types can be transmuted from `[0u8; size_of::<T>()]`. [1]
301301//
302- // [1] Per https://doc.rust-lang.org/nightly /core/option/index.html#representation:
302+ // [1] Per https://doc.rust-lang.org/1.89.0 /core/option/index.html#representation:
303303//
304304// Rust guarantees to optimize the following types `T` such that [`Option<T>`]
305305// has the same size and alignment as `T`. In some of these cases, Rust
306306// further guarantees that `transmute::<_, Option<T>>([0u8; size_of::<T>()])`
307307// is sound and produces `Option::<T>::None`. These cases are identified by
308308// the second column:
309309//
310- // | `T` | `transmute::<_, Option<T>>([0u8; size_of::<T>()])` sound? |
311- // |-----------------------|-----------------------------------------------------------|
312- // | [`Box<U>`] | when `U: Sized` |
313- // | `&U` | when `U: Sized` |
314- // | `&mut U` | when `U: Sized` |
315- // | [`ptr::NonNull<U>`] | when `U: Sized` |
316- // | `fn`, `extern "C" fn` | always |
317- //
318- // FIXME(#429), FIXME(https://github.com/rust-lang/rust/pull/115333): Cite the
319- // Stable docs once they're available.
310+ // | `T` | `transmute::<_, Option<T>>([0u8; size_of::<T>()])` sound? |
311+ // |-----------------------------------|-----------------------------------------------------------|
312+ // | [`Box<U>`] | when `U: Sized` |
313+ // | `&U` | when `U: Sized` |
314+ // | `&mut U` | when `U: Sized` |
315+ // | [`ptr::NonNull<U>`] | when `U: Sized` |
316+ // | `fn`, `extern "C" fn`[^extern_fn] | always |
317+ //
318+ // [^extern_fn]: this remains true for `unsafe` variants, any argument/return
319+ // types, and any other ABI: `[unsafe] extern "abi" fn` (_e.g._, `extern
320+ // "system" fn`)
320321const _: ( ) = unsafe {
321322 #[ cfg( feature = "alloc" ) ]
322323 unsafe_impl ! (
@@ -345,19 +346,31 @@ const _: () = unsafe {
345346 A , B , C , D , E , F , G , H , I , J , K , L -> M => TryFromBytes for opt_fn!( ...) ;
346347 |c| pointer:: is_zeroed( c)
347348 ) ;
349+ unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => FromZeros for opt_unsafe_fn!( ...) ) ;
350+ unsafe_impl_for_power_set ! (
351+ A , B , C , D , E , F , G , H , I , J , K , L -> M => TryFromBytes for opt_unsafe_fn!( ...) ;
352+ |c| pointer:: is_zeroed( c)
353+ ) ;
348354 unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => FromZeros for opt_extern_c_fn!( ...) ) ;
349355 unsafe_impl_for_power_set ! (
350356 A , B , C , D , E , F , G , H , I , J , K , L -> M => TryFromBytes for opt_extern_c_fn!( ...) ;
351357 |c| pointer:: is_zeroed( c)
352358 ) ;
359+ unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => FromZeros for opt_unsafe_extern_c_fn!( ...) ) ;
360+ unsafe_impl_for_power_set ! (
361+ A , B , C , D , E , F , G , H , I , J , K , L -> M => TryFromBytes for opt_unsafe_extern_c_fn!( ...) ;
362+ |c| pointer:: is_zeroed( c)
363+ ) ;
353364} ;
354365
355- // SAFETY: `fn()` and ` extern "C" fn()` self-evidently do not contain
366+ // SAFETY: `[unsafe] [ extern "C"] fn()` self-evidently do not contain
356367// `UnsafeCell`s. This is not a proof, but we are accepting this as a known risk
357368// per #1358.
358369const _: ( ) = unsafe {
359370 unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => Immutable for opt_fn!( ...) ) ;
371+ unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => Immutable for opt_unsafe_fn!( ...) ) ;
360372 unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => Immutable for opt_extern_c_fn!( ...) ) ;
373+ unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => Immutable for opt_unsafe_extern_c_fn!( ...) ) ;
361374} ;
362375
363376#[ cfg( all(
0 commit comments