use crate::utils::{in_macro, is_expn_of, snippet_opt, span_lint_and_then};
-use rustc::hir::{intravisit::FnKind, Body, ExprKind, FnDecl, MatchSource};
+use rustc::hir::{intravisit::FnKind, Body, ExprKind, FnDecl, HirId, MatchSource};
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_tool_lint, lint_array};
use rustc_errors::Applicability;
-use syntax::{ast::NodeId, source_map::Span};
+use syntax::source_map::Span;
-/// **What it does:** Checks for missing return statements at the end of a block.
-///
-/// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers
-/// coming from other languages might prefer the expressiveness of `return`. It's possible to miss
-/// the last returning statement because the only difference is a missing `;`. Especially in bigger
-/// code with multiple return paths having a `return` keyword makes it easier to find the
-/// corresponding statements.
-///
-/// **Known problems:** None.
-///
-/// **Example:**
-/// ```rust
-/// fn foo(x: usize) {
-/// x
-/// }
-/// ```
-/// add return
-/// ```rust
-/// fn foo(x: usize) {
-/// return x;
-/// }
-/// ```
declare_clippy_lint! {
+ /// **What it does:** Checks for missing return statements at the end of a block.
+ ///
+ /// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers
+ /// coming from other languages might prefer the expressiveness of `return`. It's possible to miss
+ /// the last returning statement because the only difference is a missing `;`. Especially in bigger
+ /// code with multiple return paths having a `return` keyword makes it easier to find the
+ /// corresponding statements.
+ ///
+ /// **Known problems:** None.
+ ///
+ /// **Example:**
+ /// ```rust
+ /// fn foo(x: usize) {
+ /// x
+ /// }
+ /// ```
+ /// add return
+ /// ```rust
+ /// fn foo(x: usize) {
+ /// return x;
+ /// }
+ /// ```
pub IMPLICIT_RETURN,
restriction,
"use a return statement like `return expr` instead of an expression"
fn lint(cx: &LateContext<'_, '_>, outer_span: syntax_pos::Span, inner_span: syntax_pos::Span, msg: &str) {
span_lint_and_then(cx, IMPLICIT_RETURN, outer_span, "missing return statement", |db| {
if let Some(snippet) = snippet_opt(cx, inner_span) {
- db.span_suggestion_with_applicability(
+ db.span_suggestion(
outer_span,
msg,
format!("return {}", snippet),
fn get_lints(&self) -> LintArray {
lint_array!(IMPLICIT_RETURN)
}
+
+ fn name(&self) -> &'static str {
+ "ImplicitReturn"
+ }
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
_: &'tcx FnDecl,
body: &'tcx Body,
span: Span,
- _: NodeId,
+ _: HirId,
) {
let def_id = cx.tcx.hir().body_owner_def_id(body.id());
let mir = cx.tcx.optimized_mir(def_id);