Closed as not planned
Description
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.