Emit warning for ignored #[inline] on trait method prototypes

This commit is contained in:
varkor 2019-10-11 02:35:22 +01:00
parent 7f3c8438e0
commit 94c4dd9902
6 changed files with 71 additions and 6 deletions

View file

@ -8,6 +8,7 @@ use crate::hir::{self, HirId, HirVec, Attribute, Item, ItemKind, TraitItem, Trai
use crate::hir::DUMMY_HIR_ID;
use crate::hir::def_id::DefId;
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
use crate::lint::builtin::UNUSED_ATTRIBUTES;
use crate::ty::TyCtxt;
use crate::ty::query::Providers;
@ -36,6 +37,9 @@ pub(crate) enum Target {
Impl,
Expression,
Statement,
AssocConst,
Method { body: bool },
AssocTy,
}
impl Display for Target {
@ -60,6 +64,9 @@ impl Display for Target {
Target::Impl => "item",
Target::Expression => "expression",
Target::Statement => "statement",
Target::AssocConst => "associated const",
Target::Method { .. } => "method",
Target::AssocTy => "associated type",
})
}
}
@ -85,6 +92,19 @@ impl Target {
ItemKind::Impl(..) => Target::Impl,
}
}
fn from_trait_item(trait_item: &TraitItem) -> Target {
match trait_item.kind {
TraitItemKind::Const(..) => Target::AssocConst,
TraitItemKind::Method(_, hir::TraitMethod::Required(_)) => {
Target::Method { body: false }
}
TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => {
Target::Method { body: true }
}
TraitItemKind::Type(..) => Target::AssocTy,
}
}
}
}
}
@ -136,6 +156,15 @@ impl CheckAttrVisitor<'tcx> {
fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) -> bool {
match target {
Target::Fn | Target::Closure | Target::Method { body: true } => true,
Target::Method { body: false } | Target::ForeignFn => {
self.tcx.struct_span_lint_hir(
UNUSED_ATTRIBUTES,
hir_id,
attr.span,
"`#[inline]` is ignored on function prototypes",
).emit();
true
}
_ => {
struct_span_err!(self.tcx.sess,
attr.span,
@ -392,6 +421,11 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
intravisit::walk_item(self, item)
}
fn visit_trait_item(&mut self, trait_item: &'tcx TraitItem) {
let target = Target::from_trait_item(trait_item);
self.check_attributes(trait_item.hir_id, &trait_item.attrs, &trait_item.span, target, None);
intravisit::walk_trait_item(self, trait_item)
}
fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt) {
self.check_stmt_attributes(stmt);

View file

@ -68,6 +68,12 @@ declare_lint! {
"detect unused, unexported items"
}
declare_lint! {
pub UNUSED_ATTRIBUTES,
Warn,
"detects attributes that were not used by the compiler"
}
declare_lint! {
pub UNREACHABLE_CODE,
Warn,

View file

@ -1,6 +1,7 @@
use rustc::hir::def::{Res, DefKind};
use rustc::hir::def_id::DefId;
use rustc::lint;
use rustc::lint::builtin::UNUSED_ATTRIBUTES;
use rustc::ty::{self, Ty};
use rustc::ty::adjustment;
use rustc_data_structures::fx::FxHashMap;
@ -277,12 +278,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathStatements {
}
}
declare_lint! {
pub UNUSED_ATTRIBUTES,
Warn,
"detects attributes that were not used by the compiler"
}
#[derive(Copy, Clone)]
pub struct UnusedAttributes {
builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>,

View file

@ -0,0 +1,8 @@
warning: `#[inline]` is ignored on function prototypes
--> $DIR/issue-52057.rs:10:5
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_attributes)]` on by default

View file

@ -0,0 +1,8 @@
#![deny(unused_attributes)]
trait Trait {
#[inline] //~ ERROR `#[inline]` is ignored on function prototypes
fn foo();
}
fn main() {}

View file

@ -0,0 +1,14 @@
error: `#[inline]` is ignored on function prototypes
--> $DIR/warn-unused-inline-on-fn-prototypes.rs:9:5
|
LL | #[inline]
| ^^^^^^^^^
|
note: lint level defined here
--> $DIR/warn-unused-inline-on-fn-prototypes.rs:1:9
|
LL | #![deny(unused_attributes)]
| ^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors