I wanted to give some feedback about my experience taking the very first steps in Rust and two things that let me stumble while taking them.
So in the spirit of Becoming a Contributor by @chriskrycho, I wanted to share my personal "pain points" with you.
The first one is one for WG-compiler-errors
.
Consider the following code:
/// A Point
///
/// ```
/// assert!(false);
/// ```
#[derive(Debug)]
pub struct Point {
x: f64,
y: f64,
}
/// The main function.
pub fn main() {
let p = Point { x: 0.0, y: 0.0 };
println!("A point: {}", p);
}
Trying to compile it will cause the following error:
error[E0277]: `Point` doesn't implement `std::fmt::Display`
--> src/main.rs:15:29
|
15 | println!("A point: {}", p);
| ^ `Point` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
|
= help: the trait `std::fmt::Display` is not implemented for `Point`
= note: required by `std::fmt::Display::fmt`
The problem with the error message is the :?
part.
If you have zero experience with Rust then you simply don't understand that you should replace the {}
with a {:?}
. So my initial reaction to that message was "wat?" followed by a tentative println!("A point: {}", p:?);
. One reason for my mistake was that the ^
points to p
while the suggestion is actually talking about the {}
further to the left.
I'd suggest to replace the "try using :?
instead" part with "try using {:?}
or {:#?}
instead" and, ideally, also point to the correct placeholder.
This would serve two purposes:
- it would clarify where the
:?
is supposed to be added. - it would mention
{:#?}
pretty-printing, an awesome feature that is currently not promoted enough.
While this whole thing isn't an issue for people that worked with Rust beyond the very first steps I'd argue that every newcomer will, at some point, be confronted with this error message.
I watched a coworker playing with Rust for the first time and he stumbled in a similar way at this very same error message. That's still just anecdotal evidence but tells me that it's not just me.
The second thing that caused me headaches is already hidden in the source code above and took my quite some time to solve...
When you start out with your first project beyond using the playground you are likely doing something like cargo new example
(with an implicit --bin
), cd example
followed by cargo run
, cargo test
and cargo doc --open
.
My code above contains an assert!(false);
in the documentation of the Point
type so I would expect a failing test... but that didn't happen.
First of all, it's not apparent that doctests aren't executed. It's a habit of mine to let tests fail on purpose at least once ("never trust a passing test") so I realized pretty fast that my doctests were not processed.
That didn't exactly help me, though, because I had no idea at all about why they were ignored.
My very first guess was that doctests probably aren't in stable
yet... so I tried my code with beta
and nightly
.
Didn't help.
I read the testing chapters of "The Rust Programming Language" (second edition) and the tests chapter of "The Cargo Book" but wasn't any wiser.
Then I found "(note: this only works in library crates, not binary crates)" in the testing chapter of "The Rust Programming Language" (first edition) which finally pointed me into the right direction...
If I write doctests, I definitely expect them to be executed. Otherwise cargo doc
generates documentation including supposedly working example code that hasn't actually been executed or even compiled. And that's not good at all.
Beside those two points I had a lot of fun.
I hope this feedback is somewhat valuable since it touches on points that seasoned devs likely won't even see anymore. Because of course it has to be {:?}
and, yep, doctests only work in library crates.