← demo0xa307f6…c756Succeededblock 90
No position yet0 / 99
FetchingOpeningPositioning
noir
Narrow session: Code, Call Trace and Values only, read-only. The event log and stepping need a wider viewport.
Code
1 side = "6"
2 radius = "3"
1 // TOUR: generics and traits
2 //
3 // The subject is what the debugger shows you when the source is written once
4 // and executed several times over different types. A generic function has one
5 // body and many instantiations; a trait method has one name and many bodies.
6 // Both are places where "which code is running" is a real question, and the
7 // call trace is where it gets answered.
8
9 mod shapes;
10
11 use shapes::{Circle, Rect, Shape};
12
13 // A type generic. One body, three instantiations — `u32`, `u64` and `i32` —
14 // and the call trace names the frame each time it is entered.
15 //
16 // The bound is `Ord`, which `Field` deliberately does NOT implement: field
17 // elements wrap, so "greater than" is not a question they answer. That refusal
18 // is a language fact worth meeting here rather than in a compiler error later.
19 unconstrained fn largest<T>(a: T, b: T) -> T
20 where
21 T: std::cmp::Ord,
22 {
23 if a > b {
24 a
25 } else {
26 b
27 }
28 }
29
30 // A NUMERIC generic: `N` is a value, not a type, and the same source runs over
31 // arrays of two different lengths. The loop bound is the generic, so the loop
32 // rail has a different number of rungs per instantiation.
33 unconstrained fn sum_all<let N: u32>(values: [u32; N]) -> u32 {
34 let mut total: u32 = 0;
35 for i in 0..N {
36 total = total + values[i];
37 }
38 total
39 }
40
41 // A generic constrained by a trait this package defines. Which `area` runs is
42 // decided by the argument's type, and the only place a reader can SEE which
43 // one ran is the trace.
44 unconstrained fn describe<T>(shape: T) -> u32
45 where
46 T: Shape,
47 {
48 let a = shape.area();
49 let p = shape.perimeter();
50 a + p
51 }
52
53 unconstrained fn main(side: u32, radius: pub u32) -> pub u32 {
54 // Three instantiations of one generic function, over three types.
55 let big_u = largest(side, 17);
56 let big_w = largest(side as u64, 4_000_000_000);
57 // The suffix is load-bearing: a bare negative literal is a `Field`, and
58 // `Field` has no `Ord`.
59 let big_i = largest(-3_i32, -9_i32);
60
61 // Two instantiations of a numeric generic, N = 3 and N = 5.
62 let three = sum_all([1, 2, 3]);
63 let five = sum_all([side, side, side, side, side]);
64
65 // Two impls of one trait, dispatched by type.
66 let c = describe(Circle { radius });
67 let r = describe(Rect { w: side, h: side + 1 });
68
69 assert(big_u >= 17);
70 assert(three == 6);
71 assert(big_i == -3);
72 assert(big_w == 4_000_000_000);
73
74 big_u + three + five + c + r + big_w as u32
75 }
1 // A trait with two implementations, in a module of its own so that stepping
2 // into a trait method crosses a file boundary and the call trace has to name
3 // which impl it entered — the thing a source view alone cannot tell you.
4
5 pub trait Shape {
6 fn area(self) -> u32;
7
8 // A DEFAULT method: `Circle` takes it as written and `Rect` overrides it,
9 // so the same call spelling reaches two different bodies and the trace is
10 // what distinguishes them.
11 fn perimeter(self) -> u32 {
12 self.area() * 2
13 }
14 }
15
16 pub struct Circle {
17 pub radius: u32,
18 }
19
20 pub struct Rect {
21 pub w: u32,
22 pub h: u32,
23 }
24
25 impl Shape for Circle {
26 fn area(self) -> u32 {
27 // 3 is a deliberately crude pi: this program is about dispatch, and a
28 // value a reader can verify in their head is worth more here than a
29 // correct one they cannot.
30 3 * self.radius * self.radius
31 }
32 // `perimeter` is NOT overridden — the default body runs.
33 }
34
35 impl Shape for Rect {
36 fn area(self) -> u32 {
37 self.w * self.h
38 }
39
40 fn perimeter(self) -> u32 {
41 2 * (self.w + self.h)
42 }
43 }
1 [package]
2 name = "tour_generics"
3 type = "bin"
4 authors = ["BlockTracer capability tour"]
5
6 [dependencies]
Event Log

The recorded event stream is in the published recording. Reading it needs the replay engine, which this page has not started.

Call Trace

The call structure is in the published recording. Reading it needs the replay engine, which this page has not started.

Values

The recorded values are in the published recording. Reading them needs the replay engine, which this page has not started.