use rustc::lint::*;
use rustc::hir::*;
use syntax::ast::{Attribute, Name};
-use utils::span_lint;
+use utils::span_lint_and_then;
+use utils::sugg::DiagnosticBuilderExt;
/// **What it does:** Checks for `#[inline]` on trait methods without bodies
///
continue;
}
- span_lint(
+ span_lint_and_then(
cx,
INLINE_FN_WITHOUT_BODY,
attr.span,
&format!("use of `#[inline]` on trait method `{}` which has no body", name),
+ |db| {
+ db.suggest_remove_item(cx, attr.span, "remove");
+ },
);
}
}
use syntax::util::parser::AssocOp;
use syntax::ast;
use utils::{higher, snippet, snippet_opt};
+use syntax_pos::{BytePos, Pos};
/// A helper type to build suggestion correctly handling parenthesis.
pub enum Sugg<'a> {
/// }");
/// ```
fn suggest_prepend_item(&mut self, cx: &T, item: Span, msg: &str, new_item: &str);
+
+ /// Suggest to completely remove an item.
+ ///
+ /// This will remove an item and all following whitespace until the next non-whitespace
+ /// character. This should work correctly if item is on the same indentation level as the
+ /// following item.
+ ///
+ /// # Example
+ ///
+ /// ```rust,ignore
+ /// db.suggest_remove_item(cx, item, "remove this")
+ /// ```
+ fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str);
}
impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_errors::DiagnosticBuilder<'b> {
self.span_suggestion(span, msg, format!("{}\n{}", new_item, indent));
}
}
+
+ fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str) {
+ let mut remove_span = item;
+ let fmpos = cx.sess()
+ .codemap()
+ .lookup_byte_offset(remove_span.next_point().hi());
+
+ if let Some(ref src) = fmpos.fm.src {
+ let non_whitespace_offset = src[fmpos.pos.to_usize()..].find(|c| c != ' ' && c != '\t' && c != '\n');
+
+ if let Some(non_whitespace_offset) = non_whitespace_offset {
+ remove_span = remove_span.with_hi(remove_span.hi() + BytePos(non_whitespace_offset as u32))
+ }
+ }
+
+ self.span_suggestion(remove_span, msg, String::new());
+ }
}
error: use of `#[inline]` on trait method `default_inline` which has no body
- --> $DIR/inline_fn_without_body.rs:7:5
+ --> $DIR/inline_fn_without_body.rs:8:5
|
-7 | #[inline]
- | ^^^^^^^^^
+8 | #[inline]
+ | _____-^^^^^^^^
+9 | | fn default_inline();
+ | |____- help: remove
|
= note: `-D inline-fn-without-body` implied by `-D warnings`
error: use of `#[inline]` on trait method `always_inline` which has no body
- --> $DIR/inline_fn_without_body.rs:10:5
+ --> $DIR/inline_fn_without_body.rs:11:5
|
-10 | #[inline(always)]
- | ^^^^^^^^^^^^^^^^^
+11 | #[inline(always)]fn always_inline();
+ | ^^^^^^^^^^^^^^^^^ help: remove
+
+error: use of `#[inline]` on trait method `never_inline` which has no body
+ --> $DIR/inline_fn_without_body.rs:13:5
+ |
+13 | #[inline(never)]
+ | _____-^^^^^^^^^^^^^^^
+14 | |
+15 | | fn never_inline();
+ | |____- help: remove
+
+error: aborting due to 3 previous errors