Closed as not planned
Description
openedon May 14, 2024
What it does
Check for trivial functions marked pub
that aren't marked #[inline]
(or #[inline(always)]
or #[inline(never)]
).
Related issue:
Advantage
Adding #[inline]
to trivial methods can have a huge effect on performance when the methods are called cross-crate and LTO is not enabled.
The Rust compilers sometimes auto-inlines some of these methods, but not reliably so (at least not yet).
Drawbacks
Defining what makes for a "trivial" function will not be easy. Suggestion is to only trigger the lint if the function restricts itself to:
- constructs/destruct an object
- gets/sets fields
- does at most one function call
- gets arguments and returns a value
Example
pub struct Foo {
name: String,
age: Option<i32>,
}
impl Foo {
pub fn new(name: String) -> Self {
Self { name, age: None }
}
pub fn with_age(mut self, age: i32) -> Self {
self.age = Some(age);
self
}
pub fn name(&self) -> &str {
self.name.as_str()
}
}
impl AsRef<str> for Foo {
fn as_ref(&self) -> &str {
self.as_str()
}
}
Could be written as:
pub struct Foo {
name: String,
age: Option<i32>,
}
impl Foo {
#[inline]
pub fn new(name: String) -> Self {
Self { name, age: None }
}
#[inline]
pub fn with_age(mut self, age: i32) -> Self {
self.age = Some(age);
self
}
#[inline]
pub fn name(&self) -> &str {
self.name.as_str()
}
}
impl AsRef<str> for Foo {
#[inline]
fn as_ref(&self) -> &str {
self.as_str()
}
}
A lot of people don't realize that #[inline]
is also important when implementing simple trait functions like these, so that's why I'm calling it out explicitly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment