html-to-markdown 2.24.1 → 2.24.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +9 -6
- data/ext/html-to-markdown-rb/native/Cargo.lock +13 -13
- data/ext/html-to-markdown-rb/native/Cargo.toml +1 -1
- data/lib/html_to_markdown/version.rb +1 -1
- data/rust-vendor/bytemuck/.cargo-checksum.json +1 -1
- data/rust-vendor/bytemuck/.cargo_vcs_info.json +1 -1
- data/rust-vendor/bytemuck/.github/workflows/rust.yml +4 -4
- data/rust-vendor/bytemuck/Cargo.lock +16 -9
- data/rust-vendor/bytemuck/Cargo.toml +6 -2
- data/rust-vendor/bytemuck/Cargo.toml.orig +7 -6
- data/rust-vendor/bytemuck/changelog.md +5 -0
- data/rust-vendor/bytemuck/src/must.rs +1 -1
- data/rust-vendor/bytemuck/src/pod.rs +13 -0
- data/rust-vendor/bytemuck/src/zeroable.rs +13 -0
- data/rust-vendor/bytemuck/src/zeroable_in_option.rs +2 -2
- data/rust-vendor/bytemuck/tests/std_tests.rs +1 -1
- data/rust-vendor/cc/.cargo-checksum.json +1 -1
- data/rust-vendor/cc/.cargo_vcs_info.json +1 -1
- data/rust-vendor/cc/CHANGELOG.md +8 -0
- data/rust-vendor/cc/Cargo.lock +3 -3
- data/rust-vendor/cc/Cargo.toml +2 -2
- data/rust-vendor/cc/Cargo.toml.orig +2 -2
- data/rust-vendor/cc/src/lib.rs +1 -0
- data/rust-vendor/cc/src/target/generated.rs +10 -0
- data/rust-vendor/find-msvc-tools/.cargo-checksum.json +1 -1
- data/rust-vendor/find-msvc-tools/.cargo_vcs_info.json +1 -1
- data/rust-vendor/find-msvc-tools/CHANGELOG.md +6 -0
- data/rust-vendor/find-msvc-tools/Cargo.lock +1 -1
- data/rust-vendor/find-msvc-tools/Cargo.toml +1 -1
- data/rust-vendor/find-msvc-tools/Cargo.toml.orig +1 -1
- data/rust-vendor/find-msvc-tools/src/find_tools.rs +55 -20
- data/rust-vendor/html-to-markdown-rs/src/converter/handlers/link.rs +1 -9
- data/rust-vendor/html-to-markdown-rs/src/converter/inline/link.rs +2 -11
- data/rust-vendor/html-to-markdown-rs/src/converter/list/definition.rs +30 -7
- data/rust-vendor/html-to-markdown-rs/src/converter/semantic/definition_list.rs +30 -7
- data/rust-vendor/html-to-markdown-rs/tests/issue_199_regressions.rs +15 -0
- data/rust-vendor/html-to-markdown-rs/tests/issue_200_regressions.rs +36 -0
- data/rust-vendor/zerocopy/.cargo-checksum.json +1 -1
- data/rust-vendor/zerocopy/.cargo_vcs_info.json +2 -1
- data/rust-vendor/zerocopy/Cargo.lock +3 -3
- data/rust-vendor/zerocopy/Cargo.toml +4 -4
- data/rust-vendor/zerocopy/Cargo.toml.orig +4 -4
- data/rust-vendor/zerocopy/src/doctests.rs +27 -0
- data/rust-vendor/zerocopy/src/error.rs +30 -0
- data/rust-vendor/zerocopy/src/layout.rs +239 -135
- data/rust-vendor/zerocopy/src/lib.rs +16 -0
- data/rust-vendor/zerocopy/src/macros.rs +255 -125
- data/rust-vendor/zerocopy/src/pointer/mod.rs +1 -1
- data/rust-vendor/zerocopy/src/pointer/ptr.rs +109 -23
- data/rust-vendor/zerocopy/src/util/macro_util.rs +344 -383
- data/rust-vendor/zerocopy/src/util/mod.rs +38 -0
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-const.stderr +8 -0
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-not-a-reference.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-src-unsized.stderr +11 -3
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-mutable.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-not-a-reference.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-dst-not-references.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-src-unsized.stderr +11 -3
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-dst-not-tryfrombytes.stderr +0 -10
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-dst-mutable.stderr +1 -1
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-dst-not-immutable-tryfrombytes.stderr +0 -10
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-src-not-immutable-intobytes.stderr +1 -11
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-const.stderr +9 -0
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-not-a-reference.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-src-unsized.stderr +16 -8
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-mutable.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-not-a-reference.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-dst-not-references.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-src-unsized.stderr +16 -8
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-dst-not-tryfrombytes.stderr +38 -38
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-dst-not-immutable-tryfrombytes.stderr +33 -33
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-src-not-immutable-intobytes.stderr +12 -12
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-const.stderr +9 -0
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-not-a-reference.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-src-unsized.stderr +16 -8
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-mutable.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-not-a-reference.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-dst-not-references.stderr +10 -0
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-src-unsized.stderr +16 -8
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-dst-not-tryfrombytes.stderr +38 -38
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-dst-not-immutable-tryfrombytes.stderr +33 -33
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-src-not-immutable-intobytes.stderr +12 -12
- data/rust-vendor/zerocopy-derive/.cargo-checksum.json +1 -1
- data/rust-vendor/zerocopy-derive/.cargo_vcs_info.json +1 -1
- data/rust-vendor/zerocopy-derive/Cargo.lock +1 -1
- data/rust-vendor/zerocopy-derive/Cargo.toml +1 -1
- data/rust-vendor/zerocopy-derive/Cargo.toml.orig +1 -1
- data/rust-vendor/zerocopy-derive/tests/ui-nightly/enum.stderr +3 -3
- data/rust-vendor/zerocopy-derive/tests/ui-nightly/struct.stderr +5 -5
- data/rust-vendor/zerocopy-derive/tests/ui-stable/enum.stderr +3 -3
- data/rust-vendor/zerocopy-derive/tests/ui-stable/struct.stderr +5 -5
- data/rust-vendor/zmij/.cargo-checksum.json +1 -1
- data/rust-vendor/zmij/.cargo_vcs_info.json +1 -1
- data/rust-vendor/zmij/Cargo.lock +16 -16
- data/rust-vendor/zmij/Cargo.toml +1 -1
- data/rust-vendor/zmij/Cargo.toml.orig +1 -1
- data/rust-vendor/zmij/README.md +1 -1
- data/rust-vendor/zmij/src/lib.rs +54 -93
- metadata +4 -50
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-unsized.rs +0 -15
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-mut-dst-unsized.stderr +0 -8
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-unsized.rs +0 -15
- data/rust-vendor/zerocopy/tests/ui-msrv/transmute-ref-dst-unsized.stderr +0 -8
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-alignment-increase.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-alignment-increase.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-size-decrease.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-size-decrease.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-size-increase.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_mut-size-increase.stderr +0 -17
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-alignment-increase.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-alignment-increase.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-size-decrease.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-size-decrease.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-size-increase.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-msrv/try_transmute_ref-size-increase.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-unsized.rs +0 -15
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-mut-dst-unsized.stderr +0 -16
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-unsized.rs +0 -15
- data/rust-vendor/zerocopy/tests/ui-nightly/transmute-ref-dst-unsized.stderr +0 -16
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-alignment-increase.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-alignment-increase.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-size-decrease.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-size-decrease.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-size-increase.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_mut-size-increase.stderr +0 -17
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-alignment-increase.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-alignment-increase.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-size-decrease.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-size-decrease.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-size-increase.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-nightly/try_transmute_ref-size-increase.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-unsized.rs +0 -15
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-mut-dst-unsized.stderr +0 -16
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-unsized.rs +0 -15
- data/rust-vendor/zerocopy/tests/ui-stable/transmute-ref-dst-unsized.stderr +0 -16
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-alignment-increase.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-alignment-increase.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-size-decrease.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-size-decrease.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-size-increase.rs +0 -19
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_mut-size-increase.stderr +0 -17
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-alignment-increase.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-alignment-increase.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-size-decrease.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-size-decrease.stderr +0 -9
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-size-increase.rs +0 -18
- data/rust-vendor/zerocopy/tests/ui-stable/try_transmute_ref-size-increase.stderr +0 -9
|
@@ -210,10 +210,11 @@ macro_rules! transmute {
|
|
|
210
210
|
///
|
|
211
211
|
/// # Size compatibility
|
|
212
212
|
///
|
|
213
|
-
/// `transmute_ref!` supports transmuting between `Sized` types
|
|
214
|
-
///
|
|
215
|
-
///
|
|
216
|
-
/// metadata stored in an
|
|
213
|
+
/// `transmute_ref!` supports transmuting between `Sized` types, between unsized
|
|
214
|
+
/// (i.e., `?Sized`) types, and from a `Sized` type to an unsized type. It
|
|
215
|
+
/// supports any transmutation that preserves the number of bytes of the
|
|
216
|
+
/// referent, even if doing so requires updating the metadata stored in an
|
|
217
|
+
/// unsized "fat" reference:
|
|
217
218
|
///
|
|
218
219
|
/// ```
|
|
219
220
|
/// # use zerocopy::transmute_ref;
|
|
@@ -348,11 +349,32 @@ macro_rules! transmute_ref {
|
|
|
348
349
|
} else {
|
|
349
350
|
use $crate::util::macro_util::TransmuteRefDst;
|
|
350
351
|
let t = $crate::util::macro_util::Wrap::new(e);
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
352
|
+
|
|
353
|
+
if false {
|
|
354
|
+
// This branch exists solely to force the compiler to infer the
|
|
355
|
+
// type of `Dst` *before* it attempts to resolve the method call
|
|
356
|
+
// to `transmute_ref` in the `else` branch.
|
|
357
|
+
//
|
|
358
|
+
// Without this, if `Src` is `Sized` but `Dst` is `!Sized`, the
|
|
359
|
+
// compiler will eagerly select the inherent impl of
|
|
360
|
+
// `transmute_ref` (which requires `Dst: Sized`) because inherent
|
|
361
|
+
// methods take priority over trait methods. It does this before
|
|
362
|
+
// it realizes `Dst` is `!Sized`, leading to a compile error when
|
|
363
|
+
// it checks the bounds later.
|
|
364
|
+
//
|
|
365
|
+
// By calling this helper (which returns `&Dst`), we force `Dst`
|
|
366
|
+
// to be fully resolved. By the time it gets to the `else`
|
|
367
|
+
// branch, the compiler knows `Dst` is `!Sized`, properly
|
|
368
|
+
// disqualifies the inherent method, and falls back to the trait
|
|
369
|
+
// implementation.
|
|
370
|
+
t.transmute_ref_inference_helper()
|
|
371
|
+
} else {
|
|
372
|
+
// SAFETY: The outer `if false` branch ensures that:
|
|
373
|
+
// - `Src: IntoBytes + Immutable`
|
|
374
|
+
// - `Dst: FromBytes + Immutable`
|
|
375
|
+
unsafe {
|
|
376
|
+
t.transmute_ref()
|
|
377
|
+
}
|
|
356
378
|
}
|
|
357
379
|
}
|
|
358
380
|
}}
|
|
@@ -367,8 +389,8 @@ macro_rules! transmute_ref {
|
|
|
367
389
|
/// const fn transmute_mut<'src, 'dst, Src, Dst>(src: &'src mut Src) -> &'dst mut Dst
|
|
368
390
|
/// where
|
|
369
391
|
/// 'src: 'dst,
|
|
370
|
-
/// Src: FromBytes + IntoBytes,
|
|
371
|
-
/// Dst: FromBytes + IntoBytes,
|
|
392
|
+
/// Src: FromBytes + IntoBytes + ?Sized,
|
|
393
|
+
/// Dst: FromBytes + IntoBytes + ?Sized,
|
|
372
394
|
/// align_of::<Src>() >= align_of::<Dst>(),
|
|
373
395
|
/// size_compatible::<Src, Dst>(),
|
|
374
396
|
/// {
|
|
@@ -383,10 +405,11 @@ macro_rules! transmute_ref {
|
|
|
383
405
|
///
|
|
384
406
|
/// # Size compatibility
|
|
385
407
|
///
|
|
386
|
-
/// `transmute_mut!` supports transmuting between `Sized` types
|
|
387
|
-
///
|
|
388
|
-
///
|
|
389
|
-
/// metadata stored in an
|
|
408
|
+
/// `transmute_mut!` supports transmuting between `Sized` types, between unsized
|
|
409
|
+
/// (i.e., `?Sized`) types, and from a `Sized` type to an unsized type. It
|
|
410
|
+
/// supports any transmutation that preserves the number of bytes of the
|
|
411
|
+
/// referent, even if doing so requires updating the metadata stored in an
|
|
412
|
+
/// unsized "fat" reference:
|
|
390
413
|
///
|
|
391
414
|
/// ```
|
|
392
415
|
/// # use zerocopy::transmute_mut;
|
|
@@ -503,7 +526,26 @@ macro_rules! transmute_mut {
|
|
|
503
526
|
#[allow(unused)]
|
|
504
527
|
use $crate::util::macro_util::TransmuteMutDst as _;
|
|
505
528
|
let t = $crate::util::macro_util::Wrap::new(e);
|
|
506
|
-
|
|
529
|
+
if false {
|
|
530
|
+
// This branch exists solely to force the compiler to infer the type
|
|
531
|
+
// of `Dst` *before* it attempts to resolve the method call to
|
|
532
|
+
// `transmute_mut` in the `else` branch.
|
|
533
|
+
//
|
|
534
|
+
// Without this, if `Src` is `Sized` but `Dst` is `!Sized`, the
|
|
535
|
+
// compiler will eagerly select the inherent impl of `transmute_mut`
|
|
536
|
+
// (which requires `Dst: Sized`) because inherent methods take
|
|
537
|
+
// priority over trait methods. It does this before it realizes
|
|
538
|
+
// `Dst` is `!Sized`, leading to a compile error when it checks the
|
|
539
|
+
// bounds later.
|
|
540
|
+
//
|
|
541
|
+
// By calling this helper (which returns `&mut Dst`), we force `Dst`
|
|
542
|
+
// to be fully resolved. By the time it gets to the `else` branch,
|
|
543
|
+
// the compiler knows `Dst` is `!Sized`, properly disqualifies the
|
|
544
|
+
// inherent method, and falls back to the trait implementation.
|
|
545
|
+
t.transmute_mut_inference_helper()
|
|
546
|
+
} else {
|
|
547
|
+
t.transmute_mut()
|
|
548
|
+
}
|
|
507
549
|
}}
|
|
508
550
|
}
|
|
509
551
|
|
|
@@ -586,10 +628,10 @@ macro_rules! try_transmute {
|
|
|
586
628
|
/// ```ignore
|
|
587
629
|
/// fn try_transmute_ref<Src, Dst>(src: &Src) -> Result<&Dst, ValidityError<&Src, Dst>>
|
|
588
630
|
/// where
|
|
589
|
-
/// Src: IntoBytes + Immutable,
|
|
590
|
-
/// Dst: TryFromBytes + Immutable,
|
|
591
|
-
/// size_of::<Src>() == size_of::<Dst>(),
|
|
631
|
+
/// Src: IntoBytes + Immutable + ?Sized,
|
|
632
|
+
/// Dst: TryFromBytes + Immutable + ?Sized,
|
|
592
633
|
/// align_of::<Src>() >= align_of::<Dst>(),
|
|
634
|
+
/// size_compatible::<Src, Dst>(),
|
|
593
635
|
/// {
|
|
594
636
|
/// # /*
|
|
595
637
|
/// ...
|
|
@@ -597,13 +639,33 @@ macro_rules! try_transmute {
|
|
|
597
639
|
/// }
|
|
598
640
|
/// ```
|
|
599
641
|
///
|
|
600
|
-
///
|
|
601
|
-
///
|
|
602
|
-
///
|
|
603
|
-
///
|
|
642
|
+
/// The types `Src` and `Dst` are inferred from the calling context; they cannot
|
|
643
|
+
/// be explicitly specified in the macro invocation.
|
|
644
|
+
///
|
|
645
|
+
/// # Size compatibility
|
|
646
|
+
///
|
|
647
|
+
/// `try_transmute_ref!` supports transmuting between `Sized` types, between
|
|
648
|
+
/// unsized (i.e., `?Sized`) types, and from a `Sized` type to an unsized type.
|
|
649
|
+
/// It supports any transmutation that preserves the number of bytes of the
|
|
650
|
+
/// referent, even if doing so requires updating the metadata stored in an
|
|
651
|
+
/// unsized "fat" reference:
|
|
652
|
+
///
|
|
653
|
+
/// ```
|
|
654
|
+
/// # use zerocopy::try_transmute_ref;
|
|
655
|
+
/// # use core::mem::size_of_val; // Not in the prelude on our MSRV
|
|
656
|
+
/// let src: &[[u8; 2]] = &[[0, 1], [2, 3]][..];
|
|
657
|
+
/// let dst: &[u8] = try_transmute_ref!(src).unwrap();
|
|
658
|
+
///
|
|
659
|
+
/// assert_eq!(src.len(), 2);
|
|
660
|
+
/// assert_eq!(dst.len(), 4);
|
|
661
|
+
/// assert_eq!(dst, [0, 1, 2, 3]);
|
|
662
|
+
/// assert_eq!(size_of_val(src), size_of_val(dst));
|
|
663
|
+
/// ```
|
|
604
664
|
///
|
|
605
665
|
/// # Examples
|
|
606
666
|
///
|
|
667
|
+
/// Transmuting between `Sized` types:
|
|
668
|
+
///
|
|
607
669
|
/// ```
|
|
608
670
|
/// # use zerocopy::*;
|
|
609
671
|
/// // 0u8 → bool = false
|
|
@@ -619,67 +681,62 @@ macro_rules! try_transmute {
|
|
|
619
681
|
/// ));
|
|
620
682
|
/// ```
|
|
621
683
|
///
|
|
622
|
-
///
|
|
623
|
-
///
|
|
624
|
-
/// Because of limitations on macros, the error message generated when
|
|
625
|
-
/// `try_transmute_ref!` is used to transmute from a type of lower alignment to
|
|
626
|
-
/// a type of higher alignment is somewhat confusing. For example, the following
|
|
627
|
-
/// code:
|
|
684
|
+
/// Transmuting between unsized types:
|
|
628
685
|
///
|
|
629
|
-
/// ```compile_fail
|
|
630
|
-
/// let increase_alignment: Result<&u16, _> = zerocopy::try_transmute_ref!(&[0u8; 2]);
|
|
631
686
|
/// ```
|
|
687
|
+
/// # use {zerocopy::*, zerocopy_derive::*};
|
|
688
|
+
/// # type u16 = zerocopy::byteorder::native_endian::U16;
|
|
689
|
+
/// # type u32 = zerocopy::byteorder::native_endian::U32;
|
|
690
|
+
/// #[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]
|
|
691
|
+
/// #[repr(C)]
|
|
692
|
+
/// struct SliceDst<T, U> {
|
|
693
|
+
/// t: T,
|
|
694
|
+
/// u: [U],
|
|
695
|
+
/// }
|
|
632
696
|
///
|
|
633
|
-
///
|
|
697
|
+
/// type Src = SliceDst<u32, u16>;
|
|
698
|
+
/// type Dst = SliceDst<u16, bool>;
|
|
634
699
|
///
|
|
635
|
-
///
|
|
636
|
-
///
|
|
637
|
-
/// --> example.rs:1:47
|
|
638
|
-
/// |
|
|
639
|
-
/// 1 | let increase_alignment: Result<&u16, _> = zerocopy::try_transmute_ref!(&[0u8; 2]);
|
|
640
|
-
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
641
|
-
/// |
|
|
642
|
-
/// = note: source type: `AlignOf<[u8; 2]>` (8 bits)
|
|
643
|
-
/// = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
|
|
644
|
-
/// = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `zerocopy::try_transmute_ref` (in Nightly builds, run with -Z macro-backtrace for more info)/// ```
|
|
645
|
-
/// ```
|
|
700
|
+
/// let src = Src::ref_from_bytes(&[0, 1, 0, 1, 0, 1, 0, 1]).unwrap();
|
|
701
|
+
/// let dst: &Dst = try_transmute_ref!(src).unwrap();
|
|
646
702
|
///
|
|
647
|
-
///
|
|
648
|
-
///
|
|
649
|
-
///
|
|
703
|
+
/// assert_eq!(src.t.as_bytes(), [0, 1, 0, 1]);
|
|
704
|
+
/// assert_eq!(src.u.len(), 2);
|
|
705
|
+
/// assert_eq!(src.u.as_bytes(), [0, 1, 0, 1]);
|
|
706
|
+
///
|
|
707
|
+
/// assert_eq!(dst.t.as_bytes(), [0, 1]);
|
|
708
|
+
/// assert_eq!(dst.u, [false, true, false, true, false, true]);
|
|
709
|
+
/// ```
|
|
650
710
|
#[macro_export]
|
|
651
711
|
macro_rules! try_transmute_ref {
|
|
652
712
|
($e:expr) => {{
|
|
653
|
-
// NOTE: This must be a macro (rather than a function with trait bounds)
|
|
654
|
-
// because there's no way, in a generic context, to enforce that two
|
|
655
|
-
// types have the same size. `core::mem::transmute` uses compiler magic
|
|
656
|
-
// to enforce this so long as the types are concrete.
|
|
657
|
-
|
|
658
713
|
// Ensure that the source type is a reference or a mutable reference
|
|
659
714
|
// (note that mutable references are implicitly reborrowed here).
|
|
660
715
|
let e: &_ = $e;
|
|
661
716
|
|
|
662
|
-
#[allow(
|
|
717
|
+
#[allow(unused_imports)]
|
|
718
|
+
use $crate::util::macro_util::TryTransmuteRefDst as _;
|
|
719
|
+
let t = $crate::util::macro_util::Wrap::new(e);
|
|
663
720
|
if false {
|
|
664
|
-
// This branch
|
|
665
|
-
//
|
|
666
|
-
//
|
|
667
|
-
|
|
668
|
-
// `
|
|
669
|
-
//
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
//
|
|
674
|
-
//
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
Ok(
|
|
721
|
+
// This branch exists solely to force the compiler to infer the type
|
|
722
|
+
// of `Dst` *before* it attempts to resolve the method call to
|
|
723
|
+
// `try_transmute_ref` in the `else` branch.
|
|
724
|
+
//
|
|
725
|
+
// Without this, if `Src` is `Sized` but `Dst` is `!Sized`, the
|
|
726
|
+
// compiler will eagerly select the inherent impl of
|
|
727
|
+
// `try_transmute_ref` (which requires `Dst: Sized`) because
|
|
728
|
+
// inherent methods take priority over trait methods. It does this
|
|
729
|
+
// before it realizes `Dst` is `!Sized`, leading to a compile error
|
|
730
|
+
// when it checks the bounds later.
|
|
731
|
+
//
|
|
732
|
+
// By calling this helper (which returns `&Dst`), we force `Dst`
|
|
733
|
+
// to be fully resolved. By the time it gets to the `else`
|
|
734
|
+
// branch, the compiler knows `Dst` is `!Sized`, properly
|
|
735
|
+
// disqualifies the inherent method, and falls back to the trait
|
|
736
|
+
// implementation.
|
|
737
|
+
Ok(t.transmute_ref_inference_helper())
|
|
681
738
|
} else {
|
|
682
|
-
|
|
739
|
+
t.try_transmute_ref()
|
|
683
740
|
}
|
|
684
741
|
}}
|
|
685
742
|
}
|
|
@@ -692,10 +749,10 @@ macro_rules! try_transmute_ref {
|
|
|
692
749
|
/// ```ignore
|
|
693
750
|
/// fn try_transmute_mut<Src, Dst>(src: &mut Src) -> Result<&mut Dst, ValidityError<&mut Src, Dst>>
|
|
694
751
|
/// where
|
|
695
|
-
/// Src: FromBytes + IntoBytes,
|
|
696
|
-
/// Dst: TryFromBytes + IntoBytes,
|
|
697
|
-
/// size_of::<Src>() == size_of::<Dst>(),
|
|
752
|
+
/// Src: FromBytes + IntoBytes + ?Sized,
|
|
753
|
+
/// Dst: TryFromBytes + IntoBytes + ?Sized,
|
|
698
754
|
/// align_of::<Src>() >= align_of::<Dst>(),
|
|
755
|
+
/// size_compatible::<Src, Dst>(),
|
|
699
756
|
/// {
|
|
700
757
|
/// # /*
|
|
701
758
|
/// ...
|
|
@@ -703,13 +760,34 @@ macro_rules! try_transmute_ref {
|
|
|
703
760
|
/// }
|
|
704
761
|
/// ```
|
|
705
762
|
///
|
|
706
|
-
///
|
|
707
|
-
///
|
|
708
|
-
///
|
|
709
|
-
///
|
|
763
|
+
/// The types `Src` and `Dst` are inferred from the calling context; they cannot
|
|
764
|
+
/// be explicitly specified in the macro invocation.
|
|
765
|
+
///
|
|
766
|
+
/// # Size compatibility
|
|
767
|
+
///
|
|
768
|
+
/// `try_transmute_mut!` supports transmuting between `Sized` types, between
|
|
769
|
+
/// unsized (i.e., `?Sized`) types, and from a `Sized` type to an unsized type.
|
|
770
|
+
/// It supports any transmutation that preserves the number of bytes of the
|
|
771
|
+
/// referent, even if doing so requires updating the metadata stored in an
|
|
772
|
+
/// unsized "fat" reference:
|
|
773
|
+
///
|
|
774
|
+
/// ```
|
|
775
|
+
/// # use zerocopy::try_transmute_mut;
|
|
776
|
+
/// # use core::mem::size_of_val; // Not in the prelude on our MSRV
|
|
777
|
+
/// let src: &mut [[u8; 2]] = &mut [[0, 1], [2, 3]][..];
|
|
778
|
+
/// let dst: &mut [u8] = try_transmute_mut!(src).unwrap();
|
|
779
|
+
///
|
|
780
|
+
/// assert_eq!(dst.len(), 4);
|
|
781
|
+
/// assert_eq!(dst, [0, 1, 2, 3]);
|
|
782
|
+
/// let dst_size = size_of_val(dst);
|
|
783
|
+
/// assert_eq!(src.len(), 2);
|
|
784
|
+
/// assert_eq!(size_of_val(src), dst_size);
|
|
785
|
+
/// ```
|
|
710
786
|
///
|
|
711
787
|
/// # Examples
|
|
712
788
|
///
|
|
789
|
+
/// Transmuting between `Sized` types:
|
|
790
|
+
///
|
|
713
791
|
/// ```
|
|
714
792
|
/// # use zerocopy::*;
|
|
715
793
|
/// // 0u8 → bool = false
|
|
@@ -728,67 +806,63 @@ macro_rules! try_transmute_ref {
|
|
|
728
806
|
/// ));
|
|
729
807
|
/// ```
|
|
730
808
|
///
|
|
731
|
-
///
|
|
732
|
-
///
|
|
733
|
-
/// Because of limitations on macros, the error message generated when
|
|
734
|
-
/// `try_transmute_ref!` is used to transmute from a type of lower alignment to
|
|
735
|
-
/// a type of higher alignment is somewhat confusing. For example, the following
|
|
736
|
-
/// code:
|
|
809
|
+
/// Transmuting between unsized types:
|
|
737
810
|
///
|
|
738
|
-
/// ```compile_fail
|
|
739
|
-
/// let src = &mut [0u8; 2];
|
|
740
|
-
/// let increase_alignment: Result<&mut u16, _> = zerocopy::try_transmute_mut!(src);
|
|
741
811
|
/// ```
|
|
812
|
+
/// # use {zerocopy::*, zerocopy_derive::*};
|
|
813
|
+
/// # type u16 = zerocopy::byteorder::native_endian::U16;
|
|
814
|
+
/// # type u32 = zerocopy::byteorder::native_endian::U32;
|
|
815
|
+
/// #[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]
|
|
816
|
+
/// #[repr(C)]
|
|
817
|
+
/// struct SliceDst<T, U> {
|
|
818
|
+
/// t: T,
|
|
819
|
+
/// u: [U],
|
|
820
|
+
/// }
|
|
742
821
|
///
|
|
743
|
-
///
|
|
822
|
+
/// type Src = SliceDst<u32, u16>;
|
|
823
|
+
/// type Dst = SliceDst<u16, bool>;
|
|
744
824
|
///
|
|
745
|
-
///
|
|
746
|
-
///
|
|
747
|
-
/// --> example.rs:2:51
|
|
748
|
-
/// |
|
|
749
|
-
/// 2 | let increase_alignment: Result<&mut u16, _> = zerocopy::try_transmute_mut!(src);
|
|
750
|
-
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
751
|
-
/// |
|
|
752
|
-
/// = note: source type: `AlignOf<[u8; 2]>` (8 bits)
|
|
753
|
-
/// = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
|
|
754
|
-
/// = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `zerocopy::try_transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
755
|
-
/// ```
|
|
825
|
+
/// let mut bytes = [0, 1, 0, 1, 0, 1, 0, 1];
|
|
826
|
+
/// let src = Src::mut_from_bytes(&mut bytes).unwrap();
|
|
756
827
|
///
|
|
757
|
-
///
|
|
758
|
-
///
|
|
759
|
-
///
|
|
828
|
+
/// assert_eq!(src.t.as_bytes(), [0, 1, 0, 1]);
|
|
829
|
+
/// assert_eq!(src.u.len(), 2);
|
|
830
|
+
/// assert_eq!(src.u.as_bytes(), [0, 1, 0, 1]);
|
|
831
|
+
///
|
|
832
|
+
/// let dst: &Dst = try_transmute_mut!(src).unwrap();
|
|
833
|
+
///
|
|
834
|
+
/// assert_eq!(dst.t.as_bytes(), [0, 1]);
|
|
835
|
+
/// assert_eq!(dst.u, [false, true, false, true, false, true]);
|
|
836
|
+
/// ```
|
|
760
837
|
#[macro_export]
|
|
761
838
|
macro_rules! try_transmute_mut {
|
|
762
839
|
($e:expr) => {{
|
|
763
|
-
// NOTE: This must be a macro (rather than a function with trait bounds)
|
|
764
|
-
// because there's no way, in a generic context, to enforce that two
|
|
765
|
-
// types have the same size. `core::mem::transmute` uses compiler magic
|
|
766
|
-
// to enforce this so long as the types are concrete.
|
|
767
|
-
|
|
768
840
|
// Ensure that the source type is a mutable reference.
|
|
769
841
|
let e: &mut _ = $e;
|
|
770
842
|
|
|
771
|
-
#[allow(
|
|
843
|
+
#[allow(unused_imports)]
|
|
844
|
+
use $crate::util::macro_util::TryTransmuteMutDst as _;
|
|
845
|
+
let t = $crate::util::macro_util::Wrap::new(e);
|
|
772
846
|
if false {
|
|
773
|
-
// This branch
|
|
774
|
-
//
|
|
775
|
-
//
|
|
776
|
-
|
|
777
|
-
// `
|
|
778
|
-
//
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
//
|
|
783
|
-
//
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
Ok(
|
|
847
|
+
// This branch exists solely to force the compiler to infer the type
|
|
848
|
+
// of `Dst` *before* it attempts to resolve the method call to
|
|
849
|
+
// `try_transmute_mut` in the `else` branch.
|
|
850
|
+
//
|
|
851
|
+
// Without this, if `Src` is `Sized` but `Dst` is `!Sized`, the
|
|
852
|
+
// compiler will eagerly select the inherent impl of
|
|
853
|
+
// `try_transmute_mut` (which requires `Dst: Sized`) because
|
|
854
|
+
// inherent methods take priority over trait methods. It does this
|
|
855
|
+
// before it realizes `Dst` is `!Sized`, leading to a compile error
|
|
856
|
+
// when it checks the bounds later.
|
|
857
|
+
//
|
|
858
|
+
// By calling this helper (which returns `&Dst`), we force `Dst`
|
|
859
|
+
// to be fully resolved. By the time it gets to the `else`
|
|
860
|
+
// branch, the compiler knows `Dst` is `!Sized`, properly
|
|
861
|
+
// disqualifies the inherent method, and falls back to the trait
|
|
862
|
+
// implementation.
|
|
863
|
+
Ok(t.transmute_mut_inference_helper())
|
|
790
864
|
} else {
|
|
791
|
-
|
|
865
|
+
t.try_transmute_mut()
|
|
792
866
|
}
|
|
793
867
|
}}
|
|
794
868
|
}
|
|
@@ -1196,6 +1270,13 @@ mod tests {
|
|
|
1196
1270
|
const X: &'static [[u8; 2]; 4] = transmute_ref!(&ARRAY_OF_U8S);
|
|
1197
1271
|
assert_eq!(*X, ARRAY_OF_ARRAYS);
|
|
1198
1272
|
|
|
1273
|
+
// Test sized -> unsized transmutation.
|
|
1274
|
+
let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
|
1275
|
+
let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
|
|
1276
|
+
let slice_of_arrays = &array_of_arrays[..];
|
|
1277
|
+
let x: &[[u8; 2]] = transmute_ref!(&array_of_u8s);
|
|
1278
|
+
assert_eq!(x, slice_of_arrays);
|
|
1279
|
+
|
|
1199
1280
|
// Before 1.61.0, we can't define the `const fn transmute_ref` function
|
|
1200
1281
|
// that we do on and after 1.61.0.
|
|
1201
1282
|
#[cfg(no_zerocopy_generic_bounds_in_const_fn_1_61_0)]
|
|
@@ -1347,6 +1428,27 @@ mod tests {
|
|
|
1347
1428
|
#[allow(clippy::useless_transmute)]
|
|
1348
1429
|
let y: Result<&u8, _> = try_transmute_ref!(&mut x);
|
|
1349
1430
|
assert_eq!(y, Ok(&0));
|
|
1431
|
+
|
|
1432
|
+
// Test that sized types work which don't implement `KnownLayout`.
|
|
1433
|
+
let array_of_nkl_u8s = Nkl([0u8, 1, 2, 3, 4, 5, 6, 7]);
|
|
1434
|
+
let array_of_nkl_arrays = Nkl([[0, 1], [2, 3], [4, 5], [6, 7]]);
|
|
1435
|
+
let x: Result<&Nkl<[[u8; 2]; 4]>, _> = try_transmute_ref!(&array_of_nkl_u8s);
|
|
1436
|
+
assert_eq!(x, Ok(&array_of_nkl_arrays));
|
|
1437
|
+
|
|
1438
|
+
// Test sized -> unsized transmutation.
|
|
1439
|
+
let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
|
1440
|
+
let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
|
|
1441
|
+
let slice_of_arrays = &array_of_arrays[..];
|
|
1442
|
+
let x: Result<&[[u8; 2]], _> = try_transmute_ref!(&array_of_u8s);
|
|
1443
|
+
assert_eq!(x, Ok(slice_of_arrays));
|
|
1444
|
+
|
|
1445
|
+
// Test unsized -> unsized transmutation.
|
|
1446
|
+
let slice_dst_of_u8s =
|
|
1447
|
+
SliceDst::<U16, [u8; 2]>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();
|
|
1448
|
+
let slice_dst_of_u16s =
|
|
1449
|
+
SliceDst::<U16, U16>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();
|
|
1450
|
+
let x: Result<&SliceDst<U16, U16>, _> = try_transmute_ref!(slice_dst_of_u8s);
|
|
1451
|
+
assert_eq!(x, Ok(slice_dst_of_u16s));
|
|
1350
1452
|
}
|
|
1351
1453
|
|
|
1352
1454
|
#[test]
|
|
@@ -1382,6 +1484,27 @@ mod tests {
|
|
|
1382
1484
|
#[allow(clippy::useless_transmute)]
|
|
1383
1485
|
let y: Result<&mut u8, _> = try_transmute_mut!(&mut x);
|
|
1384
1486
|
assert_eq!(y, Ok(&mut 0));
|
|
1487
|
+
|
|
1488
|
+
// Test that sized types work which don't implement `KnownLayout`.
|
|
1489
|
+
let mut array_of_nkl_u8s = Nkl([0u8, 1, 2, 3, 4, 5, 6, 7]);
|
|
1490
|
+
let mut array_of_nkl_arrays = Nkl([[0, 1], [2, 3], [4, 5], [6, 7]]);
|
|
1491
|
+
let x: Result<&mut Nkl<[[u8; 2]; 4]>, _> = try_transmute_mut!(&mut array_of_nkl_u8s);
|
|
1492
|
+
assert_eq!(x, Ok(&mut array_of_nkl_arrays));
|
|
1493
|
+
|
|
1494
|
+
// Test sized -> unsized transmutation.
|
|
1495
|
+
let mut array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
|
1496
|
+
let mut array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
|
|
1497
|
+
let slice_of_arrays = &mut array_of_arrays[..];
|
|
1498
|
+
let x: Result<&mut [[u8; 2]], _> = try_transmute_mut!(&mut array_of_u8s);
|
|
1499
|
+
assert_eq!(x, Ok(slice_of_arrays));
|
|
1500
|
+
|
|
1501
|
+
// Test unsized -> unsized transmutation.
|
|
1502
|
+
let mut bytes = [0, 1, 2, 3, 4, 5, 6];
|
|
1503
|
+
let slice_dst_of_u8s = SliceDst::<u8, [u8; 2]>::mut_from_bytes(&mut bytes[..]).unwrap();
|
|
1504
|
+
let mut bytes = [0, 1, 2, 3, 4, 5, 6];
|
|
1505
|
+
let slice_dst_of_u16s = SliceDst::<u8, U16>::mut_from_bytes(&mut bytes[..]).unwrap();
|
|
1506
|
+
let x: Result<&mut SliceDst<u8, U16>, _> = try_transmute_mut!(slice_dst_of_u8s);
|
|
1507
|
+
assert_eq!(x, Ok(slice_dst_of_u16s));
|
|
1385
1508
|
}
|
|
1386
1509
|
|
|
1387
1510
|
#[test]
|
|
@@ -1445,6 +1568,13 @@ mod tests {
|
|
|
1445
1568
|
let slice_dst_small = SliceDst::<U16, u8>::mut_from_bytes(&mut bytes[..]).unwrap();
|
|
1446
1569
|
let x: &mut SliceDst<U16, u8> = transmute_mut!(slice_dst_big);
|
|
1447
1570
|
assert_eq!(x, slice_dst_small);
|
|
1571
|
+
|
|
1572
|
+
// Test sized -> unsized transmutation.
|
|
1573
|
+
let mut array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
|
1574
|
+
let mut array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
|
|
1575
|
+
let slice_of_arrays = &mut array_of_arrays[..];
|
|
1576
|
+
let x: &mut [[u8; 2]] = transmute_mut!(&mut array_of_u8s);
|
|
1577
|
+
assert_eq!(x, slice_of_arrays);
|
|
1448
1578
|
}
|
|
1449
1579
|
|
|
1450
1580
|
#[test]
|