rust-marker / design

Apache License 2.0
15 stars 1 forks source link

Detecting unneeded allocations when using SNAFU's context selectors #23

Open shepmaster opened 2 years ago

shepmaster commented 2 years ago

Lint explanation

Avoid unconditionally allocating when providing context for SNAFU errors.

Example code

use snafu::prelude::*;

#[derive(Snafu)]
enum Error {
    BadThingHappened { source: AnotherError, username: String },
}

fn demo(username: &str) {
    do_something().context(BadThingHappenedSnafu { username: username.to_string() });
}
Warning: unconditional allocation
    do_something().context(BadThingHappenedSnafu { username: username.to_string() });
                                                                     ^^^^^^^^^^^^ Remove this function call

Notes

SNAFU automatically calls Into::into on all arguments to context selectors, mostly for converting reference types to owned types (like &str to String). When used with the context method, if the user performs the allocation, it will happen all the time, even when no error has occurred.

This is conceptually very similar to Clippy's clippy::or_fun_call warning for Ok::<_, ()>(String::new()).unwrap_or(String::from("junk")).

I might also want to investigate if there is a similar lint that would warn about unneeded usages of with_context, which accepts a closure.

shepmaster commented 1 year ago

FWIW, I've since implemented this using dylint