39 lines
2.4 KiB
Markdown
39 lines
2.4 KiB
Markdown
# A trait impl can be written correctly and still not be reached for
|
|
|
|
The 0006 drill landed 24/24 with the shipped spec unedited: seven `TaskError` variants, correct `Display`
|
|
sentences, `source()` returning the wrapped `ParseIntError` for exactly one variant, and
|
|
`impl From<ParseIntError> for TaskError`. Every trait obligation was produced from the signature up.
|
|
|
|
And the `From` impl was never called. `command.rs` still converted by hand, twice:
|
|
|
|
```rust
|
|
let id: u32 = match id.parse() { Ok(n) => n, Err(e) => return Err(TaskError::BadId(e)) };
|
|
```
|
|
|
|
That is `From::from` typed out longhand. The tests pass either way, so nothing in the feedback loop objected.
|
|
|
|
## Evidence
|
|
|
|
Read against the real crate, plus `cargo clippy`: 24 green, `tests/errors.rs` byte-identical to
|
|
`lessons/0006-errors-spec.rs`, two duplicated `match id.parse()` blocks in `command.rs`, and the same
|
|
`match … Ok(_) => ()` in `main.rs` that LR-0004 flagged after 0005 (clippy's `single_match`).
|
|
|
|
The follow-up questions were the more useful signal. All three were about the *mechanism*, not the syntax:
|
|
can two `From` impls exist for one type, where does the wrapped message go, does a developer walk `source()`
|
|
by hand every time. The syntax was owned; the model of what the syntax buys was not.
|
|
|
|
## Implications
|
|
|
|
- **A drill step needs a check that fails when the point is missed.** "Both `match` blocks collapse to
|
|
`id.parse()?`" was written in the 0006 prose and had no check beside it, so it did not happen — the same
|
|
failure mode as the stderr/exit-1 contract in LR-0004, now seen three times. 0007 gives it a grep check
|
|
(`grep -c "match id.parse" src/command.rs` → `0`) as step 0.
|
|
- **Force the impl, do not suggest it.** In 0007 the second conversion (`From<io::Error>`) cannot be hand-rolled
|
|
around without the compiler complaining, because `?` on `fs::write` is the only reasonable shape. `E0277`
|
|
does the teaching that prose could not.
|
|
- **Recall of "why" still lags production.** Same pattern as the 0005 quiz (Enums 0/1 while writing three enums).
|
|
The fix that works is showing real compiler output for the failure mode, not asserting the rule — so 0007
|
|
ships `E0119`, `E0277`, `E0046`, and `E0369`, each captured by running it.
|
|
- The user asks precise mechanism questions when given room to. Budget for them: leaving the ladder of
|
|
`?` → `From` → `source()` → `anyhow` explicit in the lesson costs less than answering it four times after.
|