When do Rust's traits make your life difficult?
Hello Rustaceans, the same lab that has brought you The Rust Book Experiment, Aquascope, and Flowistry is starting a new endeavor.
We want to understand when Rust's trait system makes it hard for you to understand or debug a Rust program.
Take for example the below piece of code that uses Bevy, a popular crate for game development.
use bevy::prelude::*;
fn main() {
App::new()
.add_startup_system(startup_system) // (1) error emitted here
.run();
}
fn startup_system(_: i32 /* (2) issue lies here */) {
println!("startup system ran first");
}
The full error diagnostic can be found alongside the code at this link: https://gist.github.com/gavinleroy/0bfac718296906bef1d7b5e1d05490be.
The Rust compiler emits the error at point (1) giving the reason that startup_system doesn't implement the trait IntoSystem. However, the core issue is at point (2) because _: i32 is not an acceptable parameter to a Bevy System. Scenarios like this, when many traits and constraints are involved, can lead to error diagnostics that point to the surface error and not the root cause.
We imagine that these types of trait-level errors are hard to understand and debug for both experienced Rust developers and newcomers to the language. But we want to hear from you, the Rust community, do you have examples where a trait error was hard to debug?
Are there some crates where you find errors harder to debug than others? Do you disagree with our example, is it easy to understand? If so, tell us why!