When including TypeScript code examples in documentation, I found two features useful (supported by a checker I wrote):
#1: checking inferred types
// %inferred-type: number
let num = 123;
#2: checking type errors
// @ts-expect-error: Object is possibly 'null'. (2531)
As a result, readers see what is going on and the checker ensures that there are no typos. I first extract the example code and then check it.
Is there a way to perform similar checks in Rust code?
What you're describing are called doc tests in Rust and you can read about them here: Documentation tests - The rustdoc book
For the first one, you can just annotate the type:
/// let num: i32 = 123;
For the second one, you can start the code block with
compile_fail to create a doc test that passes if the example doesn't compile. There's no good way to specify which error it should result in AFAIK.
/// let num: i32 = "hello";
And if it's desirable, one might want to reach out for
trybuild and create a full-blown compilation UI test.
On nightly, you can actually test which error code is emitted in a
compile_fail test. On stable, this just silently doesn't do anything. IIRC it's doing
```compile_fail,E0123, but I basically never do this, so I'm mostly just guessing.
Testing the exact form of an error is fundamentally fragile, though. The compiler is constantly tweaking and improving diagnostics, so if you're testing what the error message is, updates to the compiler may require re-"blessing" your tests. Error codes are a bit more stable, but it's still explicitly considered unstable what specific errors an invalid code snippet causes.
If you understand the limitations, then trybuild is the state of the art for snapshot testing of compiler diagnostics. It doesn't do anything to directly help with testing the examples in your documentation, but it does allow monitoring error message quality.
I've also run into this, slightly. I think it would be best if you could specify something sorta like a "diff" in the rustdoc source for a compile_fail doctest.
/// - let num: i32 = "hello";
/// + let num: i32 = 123;
compile_fail is insensitive to code changes. After refactoring a crate, any existing
compile_fail tests will continue to fail, but for a different reason than intended.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.