intravisit::{walk_expr, walk_stmt, NestedVisitorMap, Visitor},
Body, Expr, ExprKind, HirId, Lit, Stmt, StmtKind,
};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::{
hir::map::Map,
+ lint::in_external_macro,
ty::{self, FloatTy, IntTy, PolyFnSig, Ty},
};
use rustc_session::{declare_lint_pass, declare_tool_lint};
/// Check whether a passed literal has potential to cause fallback or not.
fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>) {
if_chain! {
+ if !in_external_macro(self.cx.sess(), lit.span);
if let Some(ty_bound) = self.ty_bounds.last();
if matches!(lit.node,
LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed));
mod manual_unwrap_or;
mod map_clone;
mod map_err_ignore;
-mod map_identity;
mod map_unit_fn;
mod match_on_vec_items;
mod matches;
manual_unwrap_or::MANUAL_UNWRAP_OR,
map_clone::MAP_CLONE,
map_err_ignore::MAP_ERR_IGNORE,
- map_identity::MAP_IDENTITY,
map_unit_fn::OPTION_MAP_UNIT_FN,
map_unit_fn::RESULT_MAP_UNIT_FN,
match_on_vec_items::MATCH_ON_VEC_ITEMS,
methods::MANUAL_STR_REPEAT,
methods::MAP_COLLECT_RESULT_UNIT,
methods::MAP_FLATTEN,
+ methods::MAP_IDENTITY,
methods::MAP_UNWRAP_OR,
methods::NEW_RET_NO_SELF,
methods::OK_EXPECT,
LintId::of(manual_strip::MANUAL_STRIP),
LintId::of(manual_unwrap_or::MANUAL_UNWRAP_OR),
LintId::of(map_clone::MAP_CLONE),
- LintId::of(map_identity::MAP_IDENTITY),
LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
LintId::of(methods::MANUAL_STR_REPEAT),
LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
+ LintId::of(methods::MAP_IDENTITY),
LintId::of(methods::NEW_RET_NO_SELF),
LintId::of(methods::OK_EXPECT),
LintId::of(methods::OPTION_AS_REF_DEREF),
LintId::of(loops::WHILE_LET_LOOP),
LintId::of(manual_strip::MANUAL_STRIP),
LintId::of(manual_unwrap_or::MANUAL_UNWRAP_OR),
- LintId::of(map_identity::MAP_IDENTITY),
LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
LintId::of(matches::MATCH_AS_REF),
LintId::of(methods::ITER_COUNT),
LintId::of(methods::MANUAL_FILTER_MAP),
LintId::of(methods::MANUAL_FIND_MAP),
+ LintId::of(methods::MAP_IDENTITY),
LintId::of(methods::OPTION_AS_REF_DEREF),
LintId::of(methods::OPTION_FILTER_MAP),
LintId::of(methods::SEARCH_IS_SOME),
single_char_binding_names_threshold,
});
store.register_late_pass(|| box macro_use::MacroUseImports::default());
- store.register_late_pass(|| box map_identity::MapIdentity);
store.register_late_pass(|| box pattern_type_mismatch::PatternTypeMismatch);
store.register_late_pass(|| box stable_sort_primitive::StableSortPrimitive);
store.register_late_pass(|| box repeat_once::RepeatOnce);
use super::WHILE_LET_ON_ITERATOR;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{get_enclosing_loop, is_refutable, is_trait_method, match_def_path, paths, visitors::is_res_used};
+use clippy_utils::{
+ get_enclosing_loop_or_closure, is_refutable, is_trait_method, match_def_path, paths, visitors::is_res_used,
+};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, ErasedMap, NestedVisitorMap, Visitor};
}
}
- if let Some(e) = get_enclosing_loop(cx.tcx, loop_expr) {
- // The iterator expression will be used on the next iteration unless it is declared within the outer
- // loop.
+ if let Some(e) = get_enclosing_loop_or_closure(cx.tcx, loop_expr) {
+ // The iterator expression will be used on the next iteration (for loops), or on the next call (for
+ // closures) unless it is declared within the enclosing expression. TODO: Check for closures
+ // used where an `FnOnce` type is expected.
let local_id = match iter_expr.path {
Res::Local(id) => id,
_ => return true,
+++ /dev/null
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_adjusted, is_qpath_def_path, is_trait_method, match_var, paths, remove_blocks};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::{Body, Expr, ExprKind, Pat, PatKind, QPath, StmtKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
- /// **What it does:** Checks for instances of `map(f)` where `f` is the identity function.
- ///
- /// **Why is this bad?** It can be written more concisely without the call to `map`.
- ///
- /// **Known problems:** None.
- ///
- /// **Example:**
- ///
- /// ```rust
- /// let x = [1, 2, 3];
- /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();
- /// ```
- /// Use instead:
- /// ```rust
- /// let x = [1, 2, 3];
- /// let y: Vec<_> = x.iter().map(|x| 2*x).collect();
- /// ```
- pub MAP_IDENTITY,
- complexity,
- "using iterator.map(|x| x)"
-}
-
-declare_lint_pass!(MapIdentity => [MAP_IDENTITY]);
-
-impl<'tcx> LateLintPass<'tcx> for MapIdentity {
- fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
- if expr.span.from_expansion() {
- return;
- }
-
- if_chain! {
- if let Some([caller, func]) = get_map_argument(cx, expr);
- if is_expr_identity_function(cx, func);
- then {
- span_lint_and_sugg(
- cx,
- MAP_IDENTITY,
- expr.span.trim_start(caller.span).unwrap(),
- "unnecessary map of the identity function",
- "remove the call to `map`",
- String::new(),
- Applicability::MachineApplicable
- )
- }
- }
- }
-}
-
-/// Returns the arguments passed into map() if the expression is a method call to
-/// map(). Otherwise, returns None.
-fn get_map_argument<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a [Expr<'a>]> {
- if_chain! {
- if let ExprKind::MethodCall(method, _, args, _) = expr.kind;
- if args.len() == 2 && method.ident.name == sym::map;
- let caller_ty = cx.typeck_results().expr_ty(&args[0]);
- if is_trait_method(cx, expr, sym::Iterator)
- || is_type_diagnostic_item(cx, caller_ty, sym::result_type)
- || is_type_diagnostic_item(cx, caller_ty, sym::option_type);
- then {
- Some(args)
- } else {
- None
- }
- }
-}
-
-/// Checks if an expression represents the identity function
-/// Only examines closures and `std::convert::identity`
-fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
- match expr.kind {
- ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)),
- ExprKind::Path(ref path) => is_qpath_def_path(cx, path, expr.hir_id, &paths::CONVERT_IDENTITY),
- _ => false,
- }
-}
-
-/// Checks if a function's body represents the identity function
-/// Looks for bodies of the form `|x| x`, `|x| return x`, `|x| { return x }` or `|x| {
-/// return x; }`
-fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
- let params = func.params;
- let body = remove_blocks(&func.value);
-
- // if there's less/more than one parameter, then it is not the identity function
- if params.len() != 1 {
- return false;
- }
-
- match body.kind {
- ExprKind::Path(QPath::Resolved(None, _)) => match_expr_param(cx, body, params[0].pat),
- ExprKind::Ret(Some(ret_val)) => match_expr_param(cx, ret_val, params[0].pat),
- ExprKind::Block(block, _) => {
- if_chain! {
- if block.stmts.len() == 1;
- if let StmtKind::Semi(expr) | StmtKind::Expr(expr) = block.stmts[0].kind;
- if let ExprKind::Ret(Some(ret_val)) = expr.kind;
- then {
- match_expr_param(cx, ret_val, params[0].pat)
- } else {
- false
- }
- }
- },
- _ => false,
- }
-}
-
-/// Returns true iff an expression returns the same thing as a parameter's pattern
-fn match_expr_param(cx: &LateContext<'_>, expr: &Expr<'_>, pat: &Pat<'_>) -> bool {
- if let PatKind::Binding(_, _, ident, _) = pat.kind {
- match_var(expr, ident.name) && !(cx.typeck_results().hir_owner == expr.hir_id.owner && is_adjusted(cx, expr))
- } else {
- false
- }
-}
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_expr_path_def_path, is_trait_method, path_to_local_id, paths};
-use if_chain::if_chain;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use super::FILTER_MAP_IDENTITY;
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg: &hir::Expr<'_>, filter_map_span: Span) {
- if is_trait_method(cx, expr, sym::Iterator) {
- let apply_lint = |message: &str| {
- span_lint_and_sugg(
- cx,
- FILTER_MAP_IDENTITY,
- filter_map_span.with_hi(expr.span.hi()),
- message,
- "try",
- "flatten()".to_string(),
- Applicability::MachineApplicable,
- );
- };
-
- if_chain! {
- if let hir::ExprKind::Closure(_, _, body_id, _, _) = filter_map_arg.kind;
- let body = cx.tcx.hir().body(body_id);
-
- if let hir::PatKind::Binding(_, binding_id, ..) = body.params[0].pat.kind;
- if path_to_local_id(&body.value, binding_id);
- then {
- apply_lint("called `filter_map(|x| x)` on an `Iterator`");
- }
- }
-
- if is_expr_path_def_path(cx, filter_map_arg, &paths::CONVERT_IDENTITY) {
- apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
- }
+ if is_trait_method(cx, expr, sym::Iterator) && is_expr_identity_function(cx, filter_map_arg) {
+ span_lint_and_sugg(
+ cx,
+ FILTER_MAP_IDENTITY,
+ filter_map_span.with_hi(expr.span.hi()),
+ "use of `filter_map` with an identity function",
+ "try",
+ "flatten()".to_string(),
+ Applicability::MachineApplicable,
+ );
}
}
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_expr_path_def_path, is_trait_method, paths};
-use if_chain::if_chain;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
flat_map_arg: &'tcx hir::Expr<'_>,
flat_map_span: Span,
) {
- if is_trait_method(cx, expr, sym::Iterator) {
- let apply_lint = |message: &str| {
- span_lint_and_sugg(
- cx,
- FLAT_MAP_IDENTITY,
- flat_map_span.with_hi(expr.span.hi()),
- message,
- "try",
- "flatten()".to_string(),
- Applicability::MachineApplicable,
- );
- };
-
- if_chain! {
- if let hir::ExprKind::Closure(_, _, body_id, _, _) = flat_map_arg.kind;
- let body = cx.tcx.hir().body(body_id);
-
- if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind;
- if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = body.value.kind;
-
- if path.segments.len() == 1;
- if path.segments[0].ident.name == binding_ident.name;
-
- then {
- apply_lint("called `flat_map(|x| x)` on an `Iterator`");
- }
- }
-
- if is_expr_path_def_path(cx, flat_map_arg, &paths::CONVERT_IDENTITY) {
- apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`");
- }
+ if is_trait_method(cx, expr, sym::Iterator) && is_expr_identity_function(cx, flat_map_arg) {
+ span_lint_and_sugg(
+ cx,
+ FLAT_MAP_IDENTITY,
+ flat_map_span.with_hi(expr.span.hi()),
+ "use of `flat_map` with an identity function",
+ "try",
+ "flatten()".to_string(),
+ Applicability::MachineApplicable,
+ );
}
}
--- /dev/null
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+use rustc_span::{source_map::Span, sym};
+
+use super::MAP_IDENTITY;
+
+pub(super) fn check(
+ cx: &LateContext<'_>,
+ expr: &hir::Expr<'_>,
+ caller: &hir::Expr<'_>,
+ map_arg: &hir::Expr<'_>,
+ _map_span: Span,
+) {
+ let caller_ty = cx.typeck_results().expr_ty(caller);
+
+ if_chain! {
+ if is_trait_method(cx, expr, sym::Iterator)
+ || is_type_diagnostic_item(cx, caller_ty, sym::result_type)
+ || is_type_diagnostic_item(cx, caller_ty, sym::option_type);
+ if is_expr_identity_function(cx, map_arg);
+ if let Some(sugg_span) = expr.span.trim_start(caller.span);
+ then {
+ span_lint_and_sugg(
+ cx,
+ MAP_IDENTITY,
+ sugg_span,
+ "unnecessary map of the identity function",
+ "remove the call to `map`",
+ String::new(),
+ Applicability::MachineApplicable,
+ )
+ }
+ }
+}
mod manual_str_repeat;
mod map_collect_result_unit;
mod map_flatten;
+mod map_identity;
mod map_unwrap_or;
mod ok_expect;
mod option_as_ref_deref;
"call to `filter_map` where `flatten` is sufficient"
}
+declare_clippy_lint! {
+ /// **What it does:** Checks for instances of `map(f)` where `f` is the identity function.
+ ///
+ /// **Why is this bad?** It can be written more concisely without the call to `map`.
+ ///
+ /// **Known problems:** None.
+ ///
+ /// **Example:**
+ ///
+ /// ```rust
+ /// let x = [1, 2, 3];
+ /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// let x = [1, 2, 3];
+ /// let y: Vec<_> = x.iter().map(|x| 2*x).collect();
+ /// ```
+ pub MAP_IDENTITY,
+ complexity,
+ "using iterator.map(|x| x)"
+}
+
declare_clippy_lint! {
/// **What it does:** Checks for the use of `.bytes().nth()`.
///
FILTER_NEXT,
SKIP_WHILE_NEXT,
FILTER_MAP_IDENTITY,
+ MAP_IDENTITY,
MANUAL_FILTER_MAP,
MANUAL_FIND_MAP,
OPTION_FILTER_MAP,
_ => {},
}
}
+ map_identity::check(cx, expr, recv, m_arg, span);
},
("map_or", [def, map]) => option_map_or_none::check(cx, expr, recv, def, map),
("next", []) => {
+use crate::rustc_lint::LintContext;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_macro_callsite;
use clippy_utils::{in_macro, sugg};
if t_expr.is_unit();
if let snippet = snippet_with_macro_callsite(cx, expr.span, "}");
if !snippet.ends_with('}');
+ if cx.sess().source_map().is_multiline(block.span);
then {
// filter out the desugared `for` loop
if let ExprKind::DropTemps(..) = &expr.kind {
"WebGL",
"TensorFlow",
"TrueType",
- "iOS", "macOS",
+ "iOS", "macOS", "FreeBSD",
"TeX", "LaTeX", "BibTeX", "BibLaTeX",
"MinGW",
"CamelCase",
})
}
-/// Gets the loop enclosing the given expression, if any.
-pub fn get_enclosing_loop(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
+/// Gets the loop or closure enclosing the given expression, if any.
+pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
let map = tcx.hir();
for (_, node) in map.parent_iter(expr.hir_id) {
match node {
Node::Expr(
- e @ Expr {
- kind: ExprKind::Loop(..),
+ e
+ @
+ Expr {
+ kind: ExprKind::Loop(..) | ExprKind::Closure(..),
..
},
) => return Some(e),
did.map_or(false, |did| must_use_attr(cx.tcx.get_attrs(did)).is_some())
}
+/// Checks if an expression represents the identity function
+/// Only examines closures and `std::convert::identity`
+pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+ /// Returns true if the expression is a binding to the given pattern
+ fn is_expr_pat_binding(cx: &LateContext<'_>, expr: &Expr<'_>, pat: &Pat<'_>) -> bool {
+ if let PatKind::Binding(_, _, ident, _) = pat.kind {
+ if match_var(expr, ident.name) {
+ return !(cx.typeck_results().hir_owner == expr.hir_id.owner && is_adjusted(cx, expr));
+ }
+ }
+
+ false
+ }
+
+ /// Checks if a function's body represents the identity function. Looks for bodies of the form:
+ /// * `|x| x`
+ /// * `|x| return x`
+ /// * `|x| { return x }`
+ /// * `|x| { return x; }`
+ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
+ let body = remove_blocks(&func.value);
+
+ let value_pat = if let [value_param] = func.params {
+ value_param.pat
+ } else {
+ return false;
+ };
+
+ match body.kind {
+ ExprKind::Path(QPath::Resolved(None, _)) => is_expr_pat_binding(cx, body, value_pat),
+ ExprKind::Ret(Some(ret_val)) => is_expr_pat_binding(cx, ret_val, value_pat),
+ ExprKind::Block(block, _) => {
+ if_chain! {
+ if let &[block_stmt] = &block.stmts;
+ if let StmtKind::Semi(expr) | StmtKind::Expr(expr) = block_stmt.kind;
+ if let ExprKind::Ret(Some(ret_val)) = expr.kind;
+ then {
+ is_expr_pat_binding(cx, ret_val, value_pat)
+ } else {
+ false
+ }
+ }
+ },
+ _ => false,
+ }
+ }
+
+ match expr.kind {
+ ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)),
+ ExprKind::Path(ref path) => is_qpath_def_path(cx, path, expr.hir_id, &paths::CONVERT_IDENTITY),
+ _ => false,
+ }
+}
+
/// Gets the node where an expression is either used, or it's type is unified with another branch.
pub fn get_expr_use_or_unification_node(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<Node<'tcx>> {
let map = tcx.hir();
}
};
}
+
+#[macro_export]
+macro_rules! default_numeric_fallback {
+ () => {
+ let x = 22;
+ };
+}
+// aux-build:macro_rules.rs
+
#![warn(clippy::default_numeric_fallback)]
#![allow(unused)]
#![allow(clippy::never_loop)]
#![allow(clippy::unnecessary_operation)]
#![allow(clippy::branches_sharing_code)]
+#[macro_use]
+extern crate macro_rules;
+
mod basic_expr {
fn test() {
// Should lint unsuffixed literals typed `i32`.
}
}
+mod in_macro {
+ macro_rules! internal_macro {
+ () => {
+ let x = 22;
+ };
+ }
+
+ // Should lint in internal macro.
+ fn internal() {
+ internal_macro!();
+ }
+
+ // Should NOT lint in external macro.
+ fn external() {
+ default_numeric_fallback!();
+ }
+}
+
fn main() {}
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:11:17
+ --> $DIR/default_numeric_fallback.rs:16:17
|
LL | let x = 22;
| ^^ help: consider adding suffix: `22_i32`
= note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:12:18
+ --> $DIR/default_numeric_fallback.rs:17:18
|
LL | let x = [1, 2, 3];
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:12:21
+ --> $DIR/default_numeric_fallback.rs:17:21
|
LL | let x = [1, 2, 3];
| ^ help: consider adding suffix: `2_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:12:24
+ --> $DIR/default_numeric_fallback.rs:17:24
|
LL | let x = [1, 2, 3];
| ^ help: consider adding suffix: `3_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:13:28
+ --> $DIR/default_numeric_fallback.rs:18:28
|
LL | let x = if true { (1, 2) } else { (3, 4) };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:13:31
+ --> $DIR/default_numeric_fallback.rs:18:31
|
LL | let x = if true { (1, 2) } else { (3, 4) };
| ^ help: consider adding suffix: `2_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:13:44
+ --> $DIR/default_numeric_fallback.rs:18:44
|
LL | let x = if true { (1, 2) } else { (3, 4) };
| ^ help: consider adding suffix: `3_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:13:47
+ --> $DIR/default_numeric_fallback.rs:18:47
|
LL | let x = if true { (1, 2) } else { (3, 4) };
| ^ help: consider adding suffix: `4_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:14:23
+ --> $DIR/default_numeric_fallback.rs:19:23
|
LL | let x = match 1 {
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:15:13
+ --> $DIR/default_numeric_fallback.rs:20:13
|
LL | 1 => 1,
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:15:18
+ --> $DIR/default_numeric_fallback.rs:20:18
|
LL | 1 => 1,
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:16:18
+ --> $DIR/default_numeric_fallback.rs:21:18
|
LL | _ => 2,
| ^ help: consider adding suffix: `2_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:20:17
+ --> $DIR/default_numeric_fallback.rs:25:17
|
LL | let x = 0.12;
| ^^^^ help: consider adding suffix: `0.12_f64`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:38:21
+ --> $DIR/default_numeric_fallback.rs:43:21
|
LL | let y = 1;
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:46:21
+ --> $DIR/default_numeric_fallback.rs:51:21
|
LL | let y = 1;
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:52:21
+ --> $DIR/default_numeric_fallback.rs:57:21
|
LL | let y = 1;
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:64:9
+ --> $DIR/default_numeric_fallback.rs:69:9
|
LL | 1
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:70:27
+ --> $DIR/default_numeric_fallback.rs:75:27
|
LL | let f = || -> _ { 1 };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:74:29
+ --> $DIR/default_numeric_fallback.rs:79:29
|
LL | let f = || -> i32 { 1 };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:88:21
+ --> $DIR/default_numeric_fallback.rs:93:21
|
LL | generic_arg(1);
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:91:32
+ --> $DIR/default_numeric_fallback.rs:96:32
|
LL | let x: _ = generic_arg(1);
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:109:28
+ --> $DIR/default_numeric_fallback.rs:114:28
|
LL | GenericStruct { x: 1 };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:112:36
+ --> $DIR/default_numeric_fallback.rs:117:36
|
LL | let _ = GenericStruct { x: 1 };
| ^ help: consider adding suffix: `1_i32`
error: default numeric fallback might occur
- --> $DIR/default_numeric_fallback.rs:132:23
+ --> $DIR/default_numeric_fallback.rs:137:23
|
LL | s.generic_arg(1);
| ^ help: consider adding suffix: `1_i32`
-error: aborting due to 24 previous errors
+error: default numeric fallback might occur
+ --> $DIR/default_numeric_fallback.rs:144:21
+ |
+LL | let x = 22;
+ | ^^ help: consider adding suffix: `22_i32`
+...
+LL | internal_macro!();
+ | ------------------ in this macro invocation
+ |
+ = note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 25 previous errors
/// WebGL
/// TensorFlow
/// TrueType
-/// iOS macOS
+/// iOS macOS FreeBSD
/// TeX LaTeX BibTeX BibLaTeX
/// MinGW
/// CamelCase (see also #2395)
// run-rustfix
-#![allow(unused_imports)]
+#![allow(unused_imports, clippy::needless_return)]
#![warn(clippy::filter_map_identity)]
fn main() {
use std::convert::identity;
let iterator = vec![Some(1), None, Some(2)].into_iter();
let _ = iterator.flatten();
+
+ let iterator = vec![Some(1), None, Some(2)].into_iter();
+ let _ = iterator.flatten();
}
// run-rustfix
-#![allow(unused_imports)]
+#![allow(unused_imports, clippy::needless_return)]
#![warn(clippy::filter_map_identity)]
fn main() {
use std::convert::identity;
let iterator = vec![Some(1), None, Some(2)].into_iter();
let _ = iterator.filter_map(identity);
+
+ let iterator = vec![Some(1), None, Some(2)].into_iter();
+ let _ = iterator.filter_map(|x| return x);
}
-error: called `filter_map(|x| x)` on an `Iterator`
+error: use of `filter_map` with an identity function
--> $DIR/filter_map_identity.rs:8:22
|
LL | let _ = iterator.filter_map(|x| x);
|
= note: `-D clippy::filter-map-identity` implied by `-D warnings`
-error: called `filter_map(std::convert::identity)` on an `Iterator`
+error: use of `filter_map` with an identity function
--> $DIR/filter_map_identity.rs:11:22
|
LL | let _ = iterator.filter_map(std::convert::identity);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
-error: called `filter_map(std::convert::identity)` on an `Iterator`
+error: use of `filter_map` with an identity function
--> $DIR/filter_map_identity.rs:15:22
|
LL | let _ = iterator.filter_map(identity);
| ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
-error: aborting due to 3 previous errors
+error: use of `filter_map` with an identity function
+ --> $DIR/filter_map_identity.rs:18:22
+ |
+LL | let _ = iterator.filter_map(|x| return x);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: aborting due to 4 previous errors
// run-rustfix
-#![allow(unused_imports)]
+#![allow(unused_imports, clippy::needless_return)]
#![warn(clippy::flat_map_identity)]
use std::convert;
let iterator = [[0, 1], [2, 3], [4, 5]].iter();
let _ = iterator.flatten();
+
+ let iterator = [[0, 1], [2, 3], [4, 5]].iter();
+ let _ = iterator.flatten();
}
// run-rustfix
-#![allow(unused_imports)]
+#![allow(unused_imports, clippy::needless_return)]
#![warn(clippy::flat_map_identity)]
use std::convert;
let iterator = [[0, 1], [2, 3], [4, 5]].iter();
let _ = iterator.flat_map(convert::identity);
+
+ let iterator = [[0, 1], [2, 3], [4, 5]].iter();
+ let _ = iterator.flat_map(|x| return x);
}
-error: called `flat_map(|x| x)` on an `Iterator`
+error: use of `flat_map` with an identity function
--> $DIR/flat_map_identity.rs:10:22
|
LL | let _ = iterator.flat_map(|x| x);
|
= note: `-D clippy::flat-map-identity` implied by `-D warnings`
-error: called `flat_map(std::convert::identity)` on an `Iterator`
+error: use of `flat_map` with an identity function
--> $DIR/flat_map_identity.rs:13:22
|
LL | let _ = iterator.flat_map(convert::identity);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
-error: aborting due to 2 previous errors
+error: use of `flat_map` with an identity function
+ --> $DIR/flat_map_identity.rs:16:22
+ |
+LL | let _ = iterator.flat_map(|x| return x);
+ | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: aborting due to 3 previous errors
y = x + 1
}
+#[rustfmt::skip]
+fn closure_error() {
+ let _d = || {
+ hello()
+ };
+}
+
+#[rustfmt::skip]
+fn unsafe_checks_error() {
+ use std::mem::MaybeUninit;
+ use std::ptr;
+
+ let mut s = MaybeUninit::<String>::uninit();
+ let _d = || unsafe {
+ ptr::drop_in_place(s.as_mut_ptr())
+ };
+}
+
// this is fine
fn print_sum(a: i32, b: i32) {
println!("{}", a + b);
println!("{}", ext);
}
}
+
+fn closure() {
+ let _d = || hello();
+}
+
+#[rustfmt::skip]
+fn closure_block() {
+ let _d = || { hello() };
+}
+
+unsafe fn some_unsafe_op() {}
+unsafe fn some_other_unsafe_fn() {}
+
+fn do_something() {
+ unsafe { some_unsafe_op() };
+
+ unsafe { some_other_unsafe_fn() };
+}
+
+fn unsafe_checks() {
+ use std::mem::MaybeUninit;
+ use std::ptr;
+
+ let mut s = MaybeUninit::<String>::uninit();
+ let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()) };
+}
LL | y = x + 1
| ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
-error: aborting due to 3 previous errors
+error: consider adding a `;` to the last statement for consistent formatting
+ --> $DIR/semicolon_if_nothing_returned.rs:23:9
+ |
+LL | hello()
+ | ^^^^^^^ help: add a `;` here: `hello();`
+
+error: consider adding a `;` to the last statement for consistent formatting
+ --> $DIR/semicolon_if_nothing_returned.rs:34:9
+ |
+LL | ptr::drop_in_place(s.as_mut_ptr())
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`
+
+error: aborting due to 5 previous errors
println!("iterator field {}", it.1);
}
+fn issue7249() {
+ let mut it = 0..10;
+ let mut x = || {
+ // Needs &mut, the closure can be called multiple times
+ for x in &mut it {
+ if x % 2 == 0 {
+ break;
+ }
+ }
+ };
+ x();
+ x();
+}
+
fn main() {
let mut it = 0..20;
for _ in it {
println!("iterator field {}", it.1);
}
+fn issue7249() {
+ let mut it = 0..10;
+ let mut x = || {
+ // Needs &mut, the closure can be called multiple times
+ while let Some(x) = it.next() {
+ if x % 2 == 0 {
+ break;
+ }
+ }
+ };
+ x();
+ x();
+}
+
fn main() {
let mut it = 0..20;
while let Some(..) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in &mut it`
error: this loop could be written as a `for` loop
- --> $DIR/while_let_on_iterator.rs:325:5
+ --> $DIR/while_let_on_iterator.rs:327:9
+ |
+LL | while let Some(x) = it.next() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in &mut it`
+
+error: this loop could be written as a `for` loop
+ --> $DIR/while_let_on_iterator.rs:339:5
|
LL | while let Some(..) = it.next() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it`
-error: aborting due to 18 previous errors
+error: aborting due to 19 previous errors