Skip to main content

NystromState

Struct NystromState 

Source
pub struct NystromState { /* private fields */ }
Expand description

Streaming Nyström attention state for ONE GQA group.

State splits along the GQA grain, because the operator does:

  • SHARED per KV group (NystromGroup) — the exact window ring, the sink buffer and the key landmarks K̃. Under GQA every Q head of a group reads the SAME k/v rows, so all three are bit-identical across the group; storing them once per group instead of once per Q head is the point of this split (identical arithmetic, ×heads_per_kv less window memory). K̃ = seg_means(ks, t, d, m_eff) is a pure function of the group’s keys and of t (which fixes m_eff), so it is shareable for the same reason the keys are.
  • PRIVATE per Q head (NystromHead) — the far accumulators T̂/Ẑ and their per-landmark running maxima, the QUERY landmarks Q̃, and the mixing matrix M = pinv(exp(Q̃K̃ᵀ/√d)). Q̃ is built from that head’s own queries, so M and the far field it drives are per-Q-head and cannot be shared: the far mass a head accumulates is contracted against its own query landmarks.

Lifecycle: new(m, w, sink)prefill(prompt) once → step() per decode token (single-head façade), or new_group/prefill_group/ step_group for a whole GQA group at once. All buffers are flat Vec<f32>, row-major; the skeleton path performs no allocations inside step().

Implementations§

Source§

impl NystromState

Source

pub fn device_view(&self) -> O1DeviceView<'_>

Source§

impl NystromState

Source

pub fn new(m: usize, w: usize, sink: usize) -> Self

Single-head state (heads_per_kv == 1, and the shape the kernel unit tests use).

m — landmark budget (≥ 4; see O1_DEFAULT_M), w — exact window width (validated setting is 128), sink — permanent exact sink keys (validated default is 4; 0 reproduces the sink-free kernel bit-for-bit). Rectifier defaults to O1_DEFAULT_RECT; override with with_rect (the golden-parity test pins it explicitly).

Examples found in repository?
examples/o1_recovery.rs (line 94)
63fn trial(m: usize, w: usize, sink: usize, amp: f32, depth: usize, seed: u64) -> f32 {
64    let (d, dv) = (64usize, 8usize);
65    let t = 8 * m + w + depth;
66    let mut s = seed;
67    let rd = (d as f32).sqrt();
68
69    let mut unit = |s: &mut u64| -> Vec<f32> {
70        let v: Vec<f32> = (0..d).map(|_| unif(s)).collect();
71        let n = v.iter().map(|x| x * x).sum::<f32>().sqrt();
72        v.iter().map(|x| x / n).collect()
73    };
74    let qhat = unit(&mut s);
75    let q: Vec<f32> = qhat.iter().map(|x| x * rd).collect();
76
77    let mut qs = Vec::with_capacity(t * d);
78    for _ in 0..t {
79        let u = unit(&mut s);
80        qs.extend(u.iter().map(|x| x * rd));
81    }
82
83    let mut ks: Vec<f32> = (0..t * d).map(|_| unif(&mut s) * 1.732).collect();
84    let mut vs: Vec<f32> = (0..t * dv).map(|_| unif(&mut s)).collect();
85    for j in 0..t {
86        vs[j * dv] = 0.0;
87    }
88    let p = t - depth;
89    for c in 0..d {
90        ks[p * d + c] += amp * qhat[c];
91    }
92    vs[p * dv] = 1.0;
93
94    let mut st = NystromState::new(m, w, sink);
95    st.prefill(&qs, &ks, &vs, t, d, dv);
96
97    let k_new: Vec<f32> = (0..d).map(|_| unif(&mut s) * 1.732).collect();
98    let mut v_new: Vec<f32> = (0..dv).map(|_| unif(&mut s)).collect();
99    v_new[0] = 0.0;
100    let mut got = vec![0f32; dv];
101    st.step(&q, &k_new, &v_new, &mut got);
102
103    let mut logits = Vec::with_capacity(t + 1);
104    for j in 0..t {
105        let dot: f32 = (0..d).map(|c| q[c] * ks[j * d + c]).sum();
106        logits.push(dot / rd);
107    }
108    let dot: f32 = (0..d).map(|c| q[c] * k_new[c]).sum();
109    logits.push(dot / rd);
110    let mx = logits.iter().cloned().fold(f32::NEG_INFINITY, f32::max);
111    let (mut den, mut num0) = (0f64, 0f64);
112    for (j, &l) in logits.iter().enumerate() {
113        let e = ((l - mx) as f64).exp();
114        den += e;
115        num0 += e * if j == t { v_new[0] } else { vs[j * dv] } as f64;
116    }
117    let want0 = (num0 / den) as f32;
118    if want0.abs() < 1e-4 {
119        return f32::NAN;
120    }
121    got[0] / want0
122}
123
124
125/// The background channel on its own: no needle, no signal, just the
126/// skeleton's error in estimating a far field of ordinary keys.
127///
128/// The recovery statistic divides by the exact answer, so it mixes two
129/// error sources — the needle's own estimate and the denominator built
130/// from every background key. Removing the needle isolates the second,
131/// and it is the one that should follow the central-limit law: a sum
132/// over ~n far keys approximated from m landmarks.
133///
134/// Returned: ‖o_o1 − o_exact‖ / ‖o_exact‖ over the whole output vector.
135/// An AMPLITUDE, deliberately — its square is the energy, and the two
136/// differ by exactly a factor of two in any log-log slope, which is why
137/// only one of them needs measuring.
138fn background_error(m: usize, w: usize, sink: usize, depth: usize, seed: u64) -> f32 {
139    let (d, dv) = (64usize, 8usize);
140    // Sequence length is FIXED, not 8*m + …. Tying it to m — which the
141    // recovery sweep above does, to guarantee m_eff reaches m — means a
142    // larger budget also gets a longer far field, and the sweep varies
143    // two things at once. Here only m moves. `8 * 64` keeps m_eff = m up
144    // to the largest budget measured.
145    let t = 8 * 64 + w + depth;
146    let _ = m;
147    let mut s = seed;
148    let rd = (d as f32).sqrt();
149
150    let mut unit = |s: &mut u64| -> Vec<f32> {
151        let v: Vec<f32> = (0..d).map(|_| unif(s)).collect();
152        let n = v.iter().map(|x| x * x).sum::<f32>().sqrt();
153        v.iter().map(|x| x / n).collect()
154    };
155    let q: Vec<f32> = unit(&mut s).iter().map(|x| x * rd).collect();
156    let mut qs = Vec::with_capacity(t * d);
157    for _ in 0..t {
158        let u = unit(&mut s);
159        qs.extend(u.iter().map(|x| x * rd));
160    }
161    let ks: Vec<f32> = (0..t * d).map(|_| unif(&mut s) * 1.732).collect();
162    let vs: Vec<f32> = (0..t * dv).map(|_| unif(&mut s)).collect();
163
164    let mut st = NystromState::new(m, w, sink);
165    st.prefill(&qs, &ks, &vs, t, d, dv);
166    let k_new: Vec<f32> = (0..d).map(|_| unif(&mut s) * 1.732).collect();
167    let v_new: Vec<f32> = (0..dv).map(|_| unif(&mut s)).collect();
168    let mut got = vec![0f32; dv];
169    st.step(&q, &k_new, &v_new, &mut got);
170
171    let mut logits = Vec::with_capacity(t + 1);
172    for j in 0..t {
173        logits.push((0..d).map(|c| q[c] * ks[j * d + c]).sum::<f32>() / rd);
174    }
175    logits.push((0..d).map(|c| q[c] * k_new[c]).sum::<f32>() / rd);
176    let mx = logits.iter().cloned().fold(f32::NEG_INFINITY, f32::max);
177    let mut den = 0f64;
178    let mut want = vec![0f64; dv];
179    for (j, &l) in logits.iter().enumerate() {
180        let e = ((l - mx) as f64).exp();
181        den += e;
182        let src = if j == t { &v_new[..] } else { &vs[j * dv..(j + 1) * dv] };
183        for (c, wc) in want.iter_mut().enumerate() {
184            *wc += e * src[c] as f64;
185        }
186    }
187    let want: Vec<f32> = want.iter().map(|x| (x / den) as f32).collect();
188    let num: f32 = got.iter().zip(&want).map(|(g, x)| (g - x) * (g - x)).sum::<f32>().sqrt();
189    let den2: f32 = want.iter().map(|x| x * x).sum::<f32>().sqrt();
190    num / den2.max(1e-9)
191}
Source

pub fn new_group(m: usize, w: usize, sink: usize, q_heads: usize) -> Self

State for one GQA group of q_heads query heads sharing a KV head. The window/sink/K̃ are stored ONCE for the group; each Q head keeps its own far field, Q̃ and M.

Source

pub fn with_rect(self, rect: O1Rect) -> Self

Select the skeleton rectifier for every head of the group (builder; see O1Rect).

Source

pub fn num_q_heads(&self) -> usize

Query heads in this group.

Source

pub fn far_len(&self, head: usize) -> usize

Keys absorbed into head head’s far field. Exposed for the delayed-insertion invariant test: eviction is a GROUP event, but each head must absorb the evicted key EXACTLY once, so this must equal the number of evictions — never a multiple of it.

Source

pub fn prefill( &mut self, qs: &[f32], ks: &[f32], vs: &[f32], t: usize, d: usize, dv: usize, )

Absorb the whole prompt for a single-head state — see prefill_group.

Examples found in repository?
examples/o1_recovery.rs (line 95)
63fn trial(m: usize, w: usize, sink: usize, amp: f32, depth: usize, seed: u64) -> f32 {
64    let (d, dv) = (64usize, 8usize);
65    let t = 8 * m + w + depth;
66    let mut s = seed;
67    let rd = (d as f32).sqrt();
68
69    let mut unit = |s: &mut u64| -> Vec<f32> {
70        let v: Vec<f32> = (0..d).map(|_| unif(s)).collect();
71        let n = v.iter().map(|x| x * x).sum::<f32>().sqrt();
72        v.iter().map(|x| x / n).collect()
73    };
74    let qhat = unit(&mut s);
75    let q: Vec<f32> = qhat.iter().map(|x| x * rd).collect();
76
77    let mut qs = Vec::with_capacity(t * d);
78    for _ in 0..t {
79        let u = unit(&mut s);
80        qs.extend(u.iter().map(|x| x * rd));
81    }
82
83    let mut ks: Vec<f32> = (0..t * d).map(|_| unif(&mut s) * 1.732).collect();
84    let mut vs: Vec<f32> = (0..t * dv).map(|_| unif(&mut s)).collect();
85    for j in 0..t {
86        vs[j * dv] = 0.0;
87    }
88    let p = t - depth;
89    for c in 0..d {
90        ks[p * d + c] += amp * qhat[c];
91    }
92    vs[p * dv] = 1.0;
93
94    let mut st = NystromState::new(m, w, sink);
95    st.prefill(&qs, &ks, &vs, t, d, dv);
96
97    let k_new: Vec<f32> = (0..d).map(|_| unif(&mut s) * 1.732).collect();
98    let mut v_new: Vec<f32> = (0..dv).map(|_| unif(&mut s)).collect();
99    v_new[0] = 0.0;
100    let mut got = vec![0f32; dv];
101    st.step(&q, &k_new, &v_new, &mut got);
102
103    let mut logits = Vec::with_capacity(t + 1);
104    for j in 0..t {
105        let dot: f32 = (0..d).map(|c| q[c] * ks[j * d + c]).sum();
106        logits.push(dot / rd);
107    }
108    let dot: f32 = (0..d).map(|c| q[c] * k_new[c]).sum();
109    logits.push(dot / rd);
110    let mx = logits.iter().cloned().fold(f32::NEG_INFINITY, f32::max);
111    let (mut den, mut num0) = (0f64, 0f64);
112    for (j, &l) in logits.iter().enumerate() {
113        let e = ((l - mx) as f64).exp();
114        den += e;
115        num0 += e * if j == t { v_new[0] } else { vs[j * dv] } as f64;
116    }
117    let want0 = (num0 / den) as f32;
118    if want0.abs() < 1e-4 {
119        return f32::NAN;
120    }
121    got[0] / want0
122}
123
124
125/// The background channel on its own: no needle, no signal, just the
126/// skeleton's error in estimating a far field of ordinary keys.
127///
128/// The recovery statistic divides by the exact answer, so it mixes two
129/// error sources — the needle's own estimate and the denominator built
130/// from every background key. Removing the needle isolates the second,
131/// and it is the one that should follow the central-limit law: a sum
132/// over ~n far keys approximated from m landmarks.
133///
134/// Returned: ‖o_o1 − o_exact‖ / ‖o_exact‖ over the whole output vector.
135/// An AMPLITUDE, deliberately — its square is the energy, and the two
136/// differ by exactly a factor of two in any log-log slope, which is why
137/// only one of them needs measuring.
138fn background_error(m: usize, w: usize, sink: usize, depth: usize, seed: u64) -> f32 {
139    let (d, dv) = (64usize, 8usize);
140    // Sequence length is FIXED, not 8*m + …. Tying it to m — which the
141    // recovery sweep above does, to guarantee m_eff reaches m — means a
142    // larger budget also gets a longer far field, and the sweep varies
143    // two things at once. Here only m moves. `8 * 64` keeps m_eff = m up
144    // to the largest budget measured.
145    let t = 8 * 64 + w + depth;
146    let _ = m;
147    let mut s = seed;
148    let rd = (d as f32).sqrt();
149
150    let mut unit = |s: &mut u64| -> Vec<f32> {
151        let v: Vec<f32> = (0..d).map(|_| unif(s)).collect();
152        let n = v.iter().map(|x| x * x).sum::<f32>().sqrt();
153        v.iter().map(|x| x / n).collect()
154    };
155    let q: Vec<f32> = unit(&mut s).iter().map(|x| x * rd).collect();
156    let mut qs = Vec::with_capacity(t * d);
157    for _ in 0..t {
158        let u = unit(&mut s);
159        qs.extend(u.iter().map(|x| x * rd));
160    }
161    let ks: Vec<f32> = (0..t * d).map(|_| unif(&mut s) * 1.732).collect();
162    let vs: Vec<f32> = (0..t * dv).map(|_| unif(&mut s)).collect();
163
164    let mut st = NystromState::new(m, w, sink);
165    st.prefill(&qs, &ks, &vs, t, d, dv);
166    let k_new: Vec<f32> = (0..d).map(|_| unif(&mut s) * 1.732).collect();
167    let v_new: Vec<f32> = (0..dv).map(|_| unif(&mut s)).collect();
168    let mut got = vec![0f32; dv];
169    st.step(&q, &k_new, &v_new, &mut got);
170
171    let mut logits = Vec::with_capacity(t + 1);
172    for j in 0..t {
173        logits.push((0..d).map(|c| q[c] * ks[j * d + c]).sum::<f32>() / rd);
174    }
175    logits.push((0..d).map(|c| q[c] * k_new[c]).sum::<f32>() / rd);
176    let mx = logits.iter().cloned().fold(f32::NEG_INFINITY, f32::max);
177    let mut den = 0f64;
178    let mut want = vec![0f64; dv];
179    for (j, &l) in logits.iter().enumerate() {
180        let e = ((l - mx) as f64).exp();
181        den += e;
182        let src = if j == t { &v_new[..] } else { &vs[j * dv..(j + 1) * dv] };
183        for (c, wc) in want.iter_mut().enumerate() {
184            *wc += e * src[c] as f64;
185        }
186    }
187    let want: Vec<f32> = want.iter().map(|x| (x / den) as f32).collect();
188    let num: f32 = got.iter().zip(&want).map(|(g, x)| (g - x) * (g - x)).sum::<f32>().sqrt();
189    let den2: f32 = want.iter().map(|x| x * x).sum::<f32>().sqrt();
190    num / den2.max(1e-9)
191}
Source

pub fn prefill_group( &mut self, qs: &[&[f32]], ks: &[f32], vs: &[f32], t: usize, d: usize, dv: usize, )

Absorb the whole prompt for a GQA group: freeze each head’s landmarks and M, then replay the prompt through the step() state semantics (window fill + delayed far insertion). qs[h] is that head’s [t][d] query block; ks is [t][d] and vs is [t][dv] — the group’s shared keys/values, row-major.

Source

pub fn step(&mut self, q: &[f32], k: &[f32], v: &[f32], out: &mut [f32])

One decode step for a single-head state — see step_group.

Examples found in repository?
examples/o1_recovery.rs (line 101)
63fn trial(m: usize, w: usize, sink: usize, amp: f32, depth: usize, seed: u64) -> f32 {
64    let (d, dv) = (64usize, 8usize);
65    let t = 8 * m + w + depth;
66    let mut s = seed;
67    let rd = (d as f32).sqrt();
68
69    let mut unit = |s: &mut u64| -> Vec<f32> {
70        let v: Vec<f32> = (0..d).map(|_| unif(s)).collect();
71        let n = v.iter().map(|x| x * x).sum::<f32>().sqrt();
72        v.iter().map(|x| x / n).collect()
73    };
74    let qhat = unit(&mut s);
75    let q: Vec<f32> = qhat.iter().map(|x| x * rd).collect();
76
77    let mut qs = Vec::with_capacity(t * d);
78    for _ in 0..t {
79        let u = unit(&mut s);
80        qs.extend(u.iter().map(|x| x * rd));
81    }
82
83    let mut ks: Vec<f32> = (0..t * d).map(|_| unif(&mut s) * 1.732).collect();
84    let mut vs: Vec<f32> = (0..t * dv).map(|_| unif(&mut s)).collect();
85    for j in 0..t {
86        vs[j * dv] = 0.0;
87    }
88    let p = t - depth;
89    for c in 0..d {
90        ks[p * d + c] += amp * qhat[c];
91    }
92    vs[p * dv] = 1.0;
93
94    let mut st = NystromState::new(m, w, sink);
95    st.prefill(&qs, &ks, &vs, t, d, dv);
96
97    let k_new: Vec<f32> = (0..d).map(|_| unif(&mut s) * 1.732).collect();
98    let mut v_new: Vec<f32> = (0..dv).map(|_| unif(&mut s)).collect();
99    v_new[0] = 0.0;
100    let mut got = vec![0f32; dv];
101    st.step(&q, &k_new, &v_new, &mut got);
102
103    let mut logits = Vec::with_capacity(t + 1);
104    for j in 0..t {
105        let dot: f32 = (0..d).map(|c| q[c] * ks[j * d + c]).sum();
106        logits.push(dot / rd);
107    }
108    let dot: f32 = (0..d).map(|c| q[c] * k_new[c]).sum();
109    logits.push(dot / rd);
110    let mx = logits.iter().cloned().fold(f32::NEG_INFINITY, f32::max);
111    let (mut den, mut num0) = (0f64, 0f64);
112    for (j, &l) in logits.iter().enumerate() {
113        let e = ((l - mx) as f64).exp();
114        den += e;
115        num0 += e * if j == t { v_new[0] } else { vs[j * dv] } as f64;
116    }
117    let want0 = (num0 / den) as f32;
118    if want0.abs() < 1e-4 {
119        return f32::NAN;
120    }
121    got[0] / want0
122}
123
124
125/// The background channel on its own: no needle, no signal, just the
126/// skeleton's error in estimating a far field of ordinary keys.
127///
128/// The recovery statistic divides by the exact answer, so it mixes two
129/// error sources — the needle's own estimate and the denominator built
130/// from every background key. Removing the needle isolates the second,
131/// and it is the one that should follow the central-limit law: a sum
132/// over ~n far keys approximated from m landmarks.
133///
134/// Returned: ‖o_o1 − o_exact‖ / ‖o_exact‖ over the whole output vector.
135/// An AMPLITUDE, deliberately — its square is the energy, and the two
136/// differ by exactly a factor of two in any log-log slope, which is why
137/// only one of them needs measuring.
138fn background_error(m: usize, w: usize, sink: usize, depth: usize, seed: u64) -> f32 {
139    let (d, dv) = (64usize, 8usize);
140    // Sequence length is FIXED, not 8*m + …. Tying it to m — which the
141    // recovery sweep above does, to guarantee m_eff reaches m — means a
142    // larger budget also gets a longer far field, and the sweep varies
143    // two things at once. Here only m moves. `8 * 64` keeps m_eff = m up
144    // to the largest budget measured.
145    let t = 8 * 64 + w + depth;
146    let _ = m;
147    let mut s = seed;
148    let rd = (d as f32).sqrt();
149
150    let mut unit = |s: &mut u64| -> Vec<f32> {
151        let v: Vec<f32> = (0..d).map(|_| unif(s)).collect();
152        let n = v.iter().map(|x| x * x).sum::<f32>().sqrt();
153        v.iter().map(|x| x / n).collect()
154    };
155    let q: Vec<f32> = unit(&mut s).iter().map(|x| x * rd).collect();
156    let mut qs = Vec::with_capacity(t * d);
157    for _ in 0..t {
158        let u = unit(&mut s);
159        qs.extend(u.iter().map(|x| x * rd));
160    }
161    let ks: Vec<f32> = (0..t * d).map(|_| unif(&mut s) * 1.732).collect();
162    let vs: Vec<f32> = (0..t * dv).map(|_| unif(&mut s)).collect();
163
164    let mut st = NystromState::new(m, w, sink);
165    st.prefill(&qs, &ks, &vs, t, d, dv);
166    let k_new: Vec<f32> = (0..d).map(|_| unif(&mut s) * 1.732).collect();
167    let v_new: Vec<f32> = (0..dv).map(|_| unif(&mut s)).collect();
168    let mut got = vec![0f32; dv];
169    st.step(&q, &k_new, &v_new, &mut got);
170
171    let mut logits = Vec::with_capacity(t + 1);
172    for j in 0..t {
173        logits.push((0..d).map(|c| q[c] * ks[j * d + c]).sum::<f32>() / rd);
174    }
175    logits.push((0..d).map(|c| q[c] * k_new[c]).sum::<f32>() / rd);
176    let mx = logits.iter().cloned().fold(f32::NEG_INFINITY, f32::max);
177    let mut den = 0f64;
178    let mut want = vec![0f64; dv];
179    for (j, &l) in logits.iter().enumerate() {
180        let e = ((l - mx) as f64).exp();
181        den += e;
182        let src = if j == t { &v_new[..] } else { &vs[j * dv..(j + 1) * dv] };
183        for (c, wc) in want.iter_mut().enumerate() {
184            *wc += e * src[c] as f64;
185        }
186    }
187    let want: Vec<f32> = want.iter().map(|x| (x / den) as f32).collect();
188    let num: f32 = got.iter().zip(&want).map(|(g, x)| (g - x) * (g - x)).sum::<f32>().sqrt();
189    let den2: f32 = want.iter().map(|x| x * x).sum::<f32>().sqrt();
190    num / den2.max(1e-9)
191}
Source

pub fn step_group( &mut self, q_all: &[f32], k: &[f32], v: &[f32], out_all: &mut [f32], )

One decode step for the whole GQA group. Inserts the group’s (k, v) ONCE, evicting the oldest window key into every head’s far accumulators, then writes each head’s attention output. q_all is [q_heads][d], out_all is [q_heads][dv].

Source

pub fn memory_bytes(&self) -> usize

Heap bytes held by this group’s state (shared window + sinks + K̃, plus each head’s skeleton and scratch) — feeds the honest “KV+state” memory line, same discipline as counting linear_state for the linear core.

Trait Implementations§

Source§

impl Clone for NystromState

Source§

fn clone(&self) -> NystromState

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NystromState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more