1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//! Substrate-level `Pod` marker.
//!
//! Every zero-copy access path, including the native substrate, requires a Pod
//! bound rather than the loose `T: Copy`. This module is that marker.
//!
//! ## Hopper-owned safety
//!
//! `Zeroable` and `Pod` are Hopper-owned marker traits. Hopper macros
//! emit field-level proof blocks that require every field to already
//! implement Hopper `Pod` before the containing layout receives its own
//! impl. That gives the same useful rejection points users got from the
//! old dependency-backed path while keeping the proof surface inside the
//! framework:
//!
//! - `bool`, `char`, references, not all bit patterns valid
//! - padded `#[repr(C)]` structs, padding bytes aren't accounted for
//! - non-alignment-1 primitives when alignment-1 was claimed
//! - enums with niches and non-zero variants
//!
//! Hopper's `#[hopper::pod]` derive and `#[hopper::state]` macro emit these
//! field-level proofs, so layouts can use the Hopper-owned marker directly.
//!
//! See `hopper_runtime::pod::Pod` (downstream re-export) for the
//! runtime-side view.
/// Marker for `Copy + Sized` values that are valid for every bit pattern.
///
/// # Safety
///
/// This is the **by-value** contract: a `Zeroable` value can be produced
/// by copying `size_of::<T>()` arbitrary bytes (e.g. a zero fill, or an
/// unaligned `read_unaligned`). It says **nothing** about alignment, so
/// it holds for native multi-byte integers as well. To overlay a type as
/// `&T` / `&mut T` directly on account bytes, which requires
/// alignment 1, use [`Pod`] (and, at the framework level,
/// `hopper_runtime::ZeroCopy`).
pub unsafe
/// Marker for types that can be safely overlaid as `&T` / `&mut T` on raw
/// account bytes at **any** offset.
///
/// # Safety
///
/// Implementing `Pod` for a type `T` asserts all of:
///
/// 1. Every `[u8; size_of::<T>()]` bit pattern decodes to a valid `T`.
/// 2. `align_of::<T>() == 1`, so a reference can be formed at any byte
/// offset without an unaligned-reference (which is UB).
/// 3. `T` contains no padding.
/// 4. `T` contains no internal pointers or references.
///
/// Native multi-byte integers (`u16`, `u32`, `u64`, `u128`, `i16`…`i128`)
/// are deliberately **not** `Pod`: their alignment is greater than 1, so
/// forming `&u64` from an arbitrary account offset is undefined behaviour.
/// Use the alignment-1 wire types (`WireU64`, `WireI64`, …) in layouts,
/// and [`ValuePod`] + [`read_unaligned_value`] for by-value scalar reads.
///
/// Hopper macros mechanically enforce the field-level proof before
/// emitting this impl. Hand-written impls carry the same unsafe contract.
pub unsafe
/// Marker for `Copy + Sized` scalars/arrays that may be read **by value**
/// from raw bytes with [`read_unaligned_value`] (alignment-independent).
///
/// # Safety
///
/// Unlike [`Pod`], `ValuePod` does not permit forming a `&T` overlay, so
/// it is safe to implement for native multi-byte integers. Use it for
/// instruction-argument decoding and local scalar loads where the value
/// is copied out, not referenced in place. Implementers assert every
/// `[u8; size_of::<T>()]` bit pattern decodes to a valid `T`.
pub unsafe
// ── Primitive implementations ───────────────────────────────────────
//
// `Zeroable` / `ValuePod`: every native integer is a valid by-value POD.
// `Pod`: only alignment-1 types (so `&T` overlays are never misaligned).
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
unsafe
/// Read a `ValuePod` scalar/array out of `bytes` at `offset` by value,
/// tolerating any alignment (uses `core::ptr::read_unaligned`).
///
/// Returns `Err(AccountDataTooSmall)` if the range is out of bounds. This
/// is the correct path for native multi-byte integers, which must never
/// be formed as a `&T` reference at an arbitrary offset.