Skip to content

Add missing_inline lint #2895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 5, 2018
Merged

Add missing_inline lint #2895

merged 4 commits into from
Jul 5, 2018

Conversation

gnzlbg
Copy link
Contributor

@gnzlbg gnzlbg commented Jul 4, 2018

When turned on, the missing_inline lint warns on all exported functions, methods,
trait methods (default impls, impls), that are not #[inline].

Closes #1503.

When turned on, the lint warns on all exported functions, methods,
trait methods (default impls, impls), that are not `#[inline]`.

Closes rust-lang#1503.
@gnzlbg
Copy link
Contributor Author

gnzlbg commented Jul 4, 2018

cc @oli-obk

// If we're building a test harness, FIXME: is this relevant?
// if cx.sess().opts.test {
// return;
// }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea whether this is needed for something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not. Just don't turn it on in tests, and most test stuff isn't pub

/// It allows the crate to require all exported methods to be `#[inline]` by default, and then opt
/// out for specific methods where this might not make sense.
///
/// **Known problems:** None.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even when the example is trivial there should be an example in the documentation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an example of a lint that does this? I based this lint on missing_docs, which doesn't provide anything :/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some examples.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's more than enough examples! Thanks!

You're right the missing_docs lint is missing an example. Every other lint does have one AFAIK. Even when it is obvious what the lint does: https://rust-lang-nursery.github.io/rust-clippy/current/index.html#assign_ops

"detects missing #[inline] attribute for public callables (functions, trait methods, methods...)"
}

pub struct MissingInline {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just make it a pub struct MissingInline;, saving you the Default impl and new method

// If we're building a test harness, FIXME: is this relevant?
// if cx.sess().opts.test {
// return;
// }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not. Just don't turn it on in tests, and most test stuff isn't pub

}
match it.node {
hir::ItemFn(..) => {
// ignore main()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just ignore this lint on binary crates? It's only relevant for libs, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, do you have an example of a lint that does that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope ^^ You can probably ask the session what kind of crate it is.

let desc = "a function";
self.check_missing_inline_attrs(cx, &it.attrs, it.span, desc);
},
hir::ItemTrait(ref _is_auto, ref _unsafe, ref _generics,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment here that we're not using https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/trait.LateLintPass.html#method.check_trait_item because we need to check if the trait is exported

use rustc::ty::{TraitContainer, ImplContainer};

// If the item being implemented is not exported, then we don't need #[inline]
if !cx.access_levels.is_exported(impl_item.id) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this check is doing anything

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without it, the check fails for:

// do not need inline because Foo is not exported
impl Foo {
    fn FooImpl() {} // ok
}

match cx.tcx.associated_item(def_id).container {
TraitContainer(cid) => {
let n = cx.tcx.hir.as_local_node_id(cid);
if n.is_some() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with if let Some(n) = n to get rid of the unwrap inside

},
}

let desc = match impl_item.node {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this up in the function as an early abort (saves unnecessary CPU cycles)

@flip1995
Copy link
Member

flip1995 commented Jul 4, 2018

dogfood test errors on your implementation:

error: this if statement can be collapsed
   --> clippy_lints/src/missing_inline.rs:141:17
    |
141 | /                 if n.is_some() {
142 | |                     if !cx.access_levels.is_exported(n.unwrap()) {
143 | |                         // If a trait is being implemented for an item, and the
144 | |                         // trait is not exported, we don't need #[inline]
145 | |                         return;
146 | |                     }
147 | |                 }

See travis

Also (unrelated) we should fix the span of the collapsible-if suggestion.. 😄

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Jul 4, 2018

I've addresses all changes (hopefully) except for detecting the type of crate being compiled. I can only get a cx.lint_sess session, and I don't see a way of getting anything about the crate from there :/

@oli-obk
Copy link
Contributor

oli-obk commented Jul 4, 2018

Ah, it's under cx.tcx.sess, and it has a field for this: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/session/struct.Session.html#structfield.crate_types

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Jul 4, 2018

Thanks, i've now fixed that too.

Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, overlooked one thing in the reviews

r=me with the nit fixed

pub struct MissingInline;

impl MissingInline {
fn check_missing_inline_attrs(&self, cx: &LateContext,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be a function instead of a method. It does not use &self at all.

@oli-obk oli-obk merged commit 6c70013 into rust-lang:master Jul 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants