mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-17 14:38:46 +00:00
Auto merge of #9174 - flip1995:rustup, r=Jarcho
Rustup r? `@ghost` changelog: none
This commit is contained in:
commit
fe6814508f
83 changed files with 288 additions and 231 deletions
|
@ -1,7 +1,7 @@
|
|||
# Clippy
|
||||
|
||||
[![Clippy Test](https://github.com/rust-lang/rust-clippy/workflows/Clippy%20Test/badge.svg?branch=auto&event=push)](https://github.com/rust-lang/rust-clippy/actions?query=workflow%3A%22Clippy+Test%22+event%3Apush+branch%3Aauto)
|
||||
[![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](#license)
|
||||
[![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](https://github.com/rust-lang/rust-clippy#license)
|
||||
|
||||
A collection of lints to catch common mistakes and improve your
|
||||
[Rust](https://github.com/rust-lang/rust) code.
|
||||
|
|
|
@ -13,7 +13,6 @@ because that's clearly a non-descriptive name.
|
|||
- [Testing](#testing)
|
||||
- [Cargo lints](#cargo-lints)
|
||||
- [Rustfix tests](#rustfix-tests)
|
||||
- [Edition 2018 tests](#edition-2018-tests)
|
||||
- [Testing manually](#testing-manually)
|
||||
- [Lint declaration](#lint-declaration)
|
||||
- [Lint registration](#lint-registration)
|
||||
|
@ -402,9 +401,8 @@ need to ensure that the MSRV configured for the project is >= the MSRV of the
|
|||
required Rust feature. If multiple features are required, just use the one with
|
||||
a lower MSRV.
|
||||
|
||||
First, add an MSRV alias for the required feature in
|
||||
[`clippy_utils::msrvs`](/clippy_utils/src/msrvs.rs). This can be accessed later
|
||||
as `msrvs::STR_STRIP_PREFIX`, for example.
|
||||
First, add an MSRV alias for the required feature in [`clippy_utils::msrvs`].
|
||||
This can be accessed later as `msrvs::STR_STRIP_PREFIX`, for example.
|
||||
|
||||
```rust
|
||||
msrv_aliases! {
|
||||
|
@ -468,6 +466,8 @@ define_Conf! {
|
|||
}
|
||||
```
|
||||
|
||||
[`clippy_utils::msrvs`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/msrvs/index.html
|
||||
|
||||
## Author lint
|
||||
|
||||
If you have trouble implementing your lint, there is also the internal `author`
|
||||
|
@ -583,8 +583,7 @@ the workspace directory. Adding a configuration to a lint can be useful for
|
|||
thresholds or to constrain some behavior that can be seen as a false positive
|
||||
for some users. Adding a configuration is done in the following steps:
|
||||
|
||||
1. Adding a new configuration entry to
|
||||
[clippy_lints::utils::conf](/clippy_lints/src/utils/conf.rs) like this:
|
||||
1. Adding a new configuration entry to [`clippy_lints::utils::conf`] like this:
|
||||
|
||||
```rust
|
||||
/// Lint: LINT_NAME.
|
||||
|
@ -635,9 +634,9 @@ for some users. Adding a configuration is done in the following steps:
|
|||
```
|
||||
3. Passing the configuration value to the lint impl struct:
|
||||
|
||||
First find the struct construction in the [clippy_lints lib
|
||||
file](/clippy_lints/src/lib.rs). The configuration value is now cloned or
|
||||
copied into a local value that is then passed to the impl struct like this:
|
||||
First find the struct construction in the [`clippy_lints` lib file]. The
|
||||
configuration value is now cloned or copied into a local value that is then
|
||||
passed to the impl struct like this:
|
||||
|
||||
```rust
|
||||
// Default generated registration:
|
||||
|
@ -653,12 +652,16 @@ for some users. Adding a configuration is done in the following steps:
|
|||
|
||||
4. Adding tests:
|
||||
1. The default configured value can be tested like any normal lint in
|
||||
[`tests/ui`](/tests/ui).
|
||||
2. The configuration itself will be tested separately in
|
||||
[`tests/ui-toml`](/tests/ui-toml). Simply add a new subfolder with a
|
||||
fitting name. This folder contains a `clippy.toml` file with the
|
||||
configuration value and a rust file that should be linted by Clippy. The
|
||||
test can otherwise be written as usual.
|
||||
[`tests/ui`].
|
||||
2. The configuration itself will be tested separately in [`tests/ui-toml`].
|
||||
Simply add a new subfolder with a fitting name. This folder contains a
|
||||
`clippy.toml` file with the configuration value and a rust file that
|
||||
should be linted by Clippy. The test can otherwise be written as usual.
|
||||
|
||||
[`clippy_lints::utils::conf`]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/utils/conf.rs
|
||||
[`clippy_lints` lib file]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/lib.rs
|
||||
[`tests/ui`]: https://github.com/rust-lang/rust-clippy/blob/master/tests/ui
|
||||
[`tests/ui-toml`]: https://github.com/rust-lang/rust-clippy/blob/master/tests/ui-toml
|
||||
|
||||
## Cheat Sheet
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ cargo dev dogfood
|
|||
```
|
||||
|
||||
More about intellij command usage and reasons
|
||||
[here](../CONTRIBUTING.md#intellij-rust)
|
||||
[here](https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md#intellij-rust)
|
||||
|
||||
## lintcheck
|
||||
|
||||
|
|
|
@ -276,4 +276,4 @@ functions to deal with macros:
|
|||
[LateContext]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LateContext.html
|
||||
[TyCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html
|
||||
[pat_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TypeckResults.html#method.pat_ty
|
||||
[paths]: ../clippy_utils/src/paths.rs
|
||||
[paths]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/paths/index.html
|
||||
|
|
|
@ -148,4 +148,4 @@ clippy-driver --edition 2018 -Cpanic=abort foo.rs
|
|||
> that are not optimized as expected, for example.
|
||||
|
||||
[Installation]: installation.md
|
||||
[CI]: continuous_integration
|
||||
[CI]: continuous_integration/index.md
|
||||
|
|
|
@ -6,7 +6,7 @@ use clippy_utils::ty::implements_trait;
|
|||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::{BlockCheckMode, Expr, ExprKind};
|
||||
use rustc_hir::{BlockCheckMode, Closure, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -51,7 +51,7 @@ struct ExVisitor<'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
|
||||
if let ExprKind::Closure { body, .. } = expr.kind {
|
||||
if let ExprKind::Closure(&Closure { body, .. }) = expr.kind {
|
||||
// do not lint if the closure is called using an iterator (see #1141)
|
||||
if_chain! {
|
||||
if let Some(parent) = get_parent_expr(self.cx, expr);
|
||||
|
|
|
@ -5,7 +5,7 @@ use clippy_utils::visitors::is_local_used;
|
|||
use clippy_utils::{path_to_local_id, paths, peel_blocks, peel_ref_operators, strip_pat_refs};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, PatKind};
|
||||
use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, PatKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{self, UintTy};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for ByteCount {
|
|||
if count.ident.name == sym::count;
|
||||
if let ExprKind::MethodCall(filter, [filter_recv, filter_arg], _) = count_recv.kind;
|
||||
if filter.ident.name == sym!(filter);
|
||||
if let ExprKind::Closure { body, .. } = filter_arg.kind;
|
||||
if let ExprKind::Closure(&Closure { body, .. }) = filter_arg.kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if let [param] = body.params;
|
||||
if let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind;
|
||||
|
|
|
@ -8,14 +8,14 @@ use rustc_data_structures::fx::FxIndexMap;
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_ty, Visitor};
|
||||
use rustc_hir::{
|
||||
self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, FnRetTy, GenericArg, HirId, ImplItem,
|
||||
ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem,
|
||||
self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Closure, Expr, ExprKind, FnRetTy, GenericArg, HirId,
|
||||
ImplItem, ImplItemKind, Item, ItemKind, Local, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, TraitItem,
|
||||
TraitItemKind, TyKind, UnOp,
|
||||
};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeckResults};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{symbol::sym, Span, Symbol};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
|
@ -720,7 +720,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
|
|||
let owner_id = cx.tcx.hir().body_owner(cx.enclosing_body.unwrap());
|
||||
Some(
|
||||
if let Node::Expr(Expr {
|
||||
kind: ExprKind::Closure { fn_decl, .. },
|
||||
kind: ExprKind::Closure(&Closure { fn_decl, .. }),
|
||||
..
|
||||
}) = cx.tcx.hir().get(owner_id)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_ast::ast::{Crate, Inline, Item, ItemKind, ModKind};
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{FileName, Span};
|
||||
use std::collections::BTreeMap;
|
||||
|
@ -49,6 +49,7 @@ declare_clippy_lint! {
|
|||
struct Modules {
|
||||
local_path: PathBuf,
|
||||
spans: Vec<Span>,
|
||||
lint_levels: Vec<Level>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -70,13 +71,38 @@ impl EarlyLintPass for DuplicateMod {
|
|||
let modules = self.modules.entry(absolute_path).or_insert(Modules {
|
||||
local_path,
|
||||
spans: Vec::new(),
|
||||
lint_levels: Vec::new(),
|
||||
});
|
||||
modules.spans.push(item.span_with_attributes());
|
||||
modules.lint_levels.push(cx.get_lint_level(DUPLICATE_MOD));
|
||||
}
|
||||
}
|
||||
|
||||
fn check_crate_post(&mut self, cx: &EarlyContext<'_>, _: &Crate) {
|
||||
for Modules { local_path, spans } in self.modules.values() {
|
||||
for Modules {
|
||||
local_path,
|
||||
spans,
|
||||
lint_levels,
|
||||
} in self.modules.values()
|
||||
{
|
||||
if spans.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
|
||||
// At this point the lint would be emitted
|
||||
assert_eq!(spans.len(), lint_levels.len());
|
||||
let spans: Vec<_> = spans
|
||||
.iter()
|
||||
.zip(lint_levels)
|
||||
.filter_map(|(span, lvl)| {
|
||||
if let Some(id) = lvl.get_expectation_id() {
|
||||
cx.fulfill_expectation(id);
|
||||
}
|
||||
|
||||
(!matches!(lvl, Level::Allow | Level::Expect(_))).then_some(*span)
|
||||
})
|
||||
.collect();
|
||||
|
||||
if spans.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_hir;
|
||||
use clippy_utils::ty::contains_ty;
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node};
|
||||
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::mir::FakeReadCause;
|
||||
|
@ -132,7 +132,10 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
|
|||
// TODO: Replace with Map::is_argument(..) when it's fixed
|
||||
fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool {
|
||||
match map.find(id) {
|
||||
Some(Node::Binding(_)) => (),
|
||||
Some(Node::Pat(Pat {
|
||||
kind: PatKind::Binding(..),
|
||||
..
|
||||
})) => (),
|
||||
_ => return false,
|
||||
}
|
||||
|
||||
|
@ -144,15 +147,6 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
|
|||
if cmt.place.projections.is_empty() {
|
||||
if let PlaceBase::Local(lid) = cmt.place.base {
|
||||
self.set.remove(&lid);
|
||||
let map = &self.cx.tcx.hir();
|
||||
if let Some(Node::Binding(_)) = map.find(cmt.hir_id) {
|
||||
if self.set.contains(&lid) {
|
||||
// let y = x where x is known
|
||||
// remove x, insert y
|
||||
self.set.insert(cmt.hir_id);
|
||||
self.set.remove(&lid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@ use clippy_utils::{higher, is_adjusted, path_to_local, path_to_local_id};
|
|||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{Expr, ExprKind, Param, PatKind, Unsafety};
|
||||
use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
||||
use rustc_middle::ty::binding::BindingMode;
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable};
|
||||
use rustc_middle::ty::{self, ClosureKind, Ty, TypeVisitable};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
|
@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
|||
return;
|
||||
}
|
||||
let body = match expr.kind {
|
||||
ExprKind::Closure { body, .. } => cx.tcx.hir().body(body),
|
||||
ExprKind::Closure(&Closure { body, .. }) => cx.tcx.hir().body(body),
|
||||
_ => return,
|
||||
};
|
||||
if body.value.span.from_expansion() {
|
||||
|
|
|
@ -94,7 +94,7 @@ impl ExcessiveBools {
|
|||
|
||||
fn check_fn_sig(&self, cx: &EarlyContext<'_>, fn_sig: &FnSig, span: Span) {
|
||||
match fn_sig.header.ext {
|
||||
Extern::Implicit | Extern::Explicit(_) => return,
|
||||
Extern::Implicit(_) | Extern::Explicit(_, _) => return,
|
||||
Extern::None => (),
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>)
|
|||
// Find id of the local that expr_end_of_block resolves to
|
||||
if let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind;
|
||||
if let Res::Local(expr_res) = expr_path.res;
|
||||
if let Some(Node::Binding(res_pat)) = cx.tcx.hir().find(expr_res);
|
||||
if let Some(Node::Pat(res_pat)) = cx.tcx.hir().find(expr_res);
|
||||
|
||||
// Find id of the local we found in the block
|
||||
if let PatKind::Binding(BindingAnnotation::Unannotated, local_hir_id, _ident, None) = local.pat.kind;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::{higher, match_def_path, path_def_id, paths};
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind};
|
||||
use rustc_hir::{BorrowKind, Closure, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
|
@ -159,7 +159,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
|||
}
|
||||
}
|
||||
if method.ident.name == sym!(flat_map) && args.len() == 2 {
|
||||
if let ExprKind::Closure { body, .. } = args[1].kind {
|
||||
if let ExprKind::Closure(&Closure { body, .. }) = args[1].kind {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
return is_infinite(cx, &body.value);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
|
|||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::{get_trait_def_id, paths, return_ty, trait_ref_of_method};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir::{ImplItem, ImplItemKind};
|
||||
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
|
@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
|
|||
let decl = &signature.decl;
|
||||
if decl.implicit_self.has_implicit_self();
|
||||
if decl.inputs.len() == 1;
|
||||
if impl_item.generics.params.is_empty();
|
||||
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
|
||||
|
||||
// Check if return type is String
|
||||
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String);
|
||||
|
|
|
@ -9,8 +9,8 @@ use rustc_hir::intravisit::{
|
|||
use rustc_hir::FnRetTy::Return;
|
||||
use rustc_hir::{
|
||||
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
|
||||
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin,
|
||||
TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
|
||||
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, LifetimeParamKind, ParamName, PolyTraitRef,
|
||||
PredicateOrigin, TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter as middle_nested_filter;
|
||||
|
@ -338,7 +338,10 @@ fn could_use_elision<'tcx>(
|
|||
fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<RefLt> {
|
||||
let mut allowed_lts = FxHashSet::default();
|
||||
for par in named_generics.iter() {
|
||||
if let GenericParamKind::Lifetime { .. } = par.kind {
|
||||
if let GenericParamKind::Lifetime {
|
||||
kind: LifetimeParamKind::Explicit,
|
||||
} = par.kind
|
||||
{
|
||||
allowed_lts.insert(RefLt::Named(par.name.ident().name));
|
||||
}
|
||||
}
|
||||
|
@ -379,6 +382,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
|
|||
self.lts.push(RefLt::Static);
|
||||
} else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name {
|
||||
// Fresh lifetimes generated should be ignored.
|
||||
self.lts.push(RefLt::Unnamed);
|
||||
} else if lt.is_elided() {
|
||||
self.lts.push(RefLt::Unnamed);
|
||||
} else {
|
||||
|
|
|
@ -43,7 +43,7 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option<Span>) {
|
|||
fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId> {
|
||||
if_chain! {
|
||||
if let Some(hir_id) = path_to_local(bound);
|
||||
if let Node::Binding(pat) = cx.tcx.hir().get(hir_id);
|
||||
if let Node::Pat(pat) = cx.tcx.hir().get(hir_id);
|
||||
if let PatKind::Binding(BindingAnnotation::Mutable, ..) = pat.kind;
|
||||
then {
|
||||
return Some(hir_id);
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc_ast::ast;
|
|||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, PatKind, QPath};
|
||||
use rustc_hir::{BinOpKind, BorrowKind, Closure, Expr, ExprKind, HirId, Mutability, Pat, PatKind, QPath};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
|
@ -369,7 +369,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
self.visit_expr(expr);
|
||||
}
|
||||
},
|
||||
ExprKind::Closure { body, .. } => {
|
||||
ExprKind::Closure(&Closure { body, .. }) => {
|
||||
let body = self.cx.tcx.hir().body(body);
|
||||
self.visit_expr(&body.value);
|
||||
},
|
||||
|
|
|
@ -63,7 +63,7 @@ pub(super) fn check<'tcx>(
|
|||
Res::Local(hir_id) => {
|
||||
let node = cx.tcx.hir().get(hir_id);
|
||||
if_chain! {
|
||||
if let Node::Binding(pat) = node;
|
||||
if let Node::Pat(pat) = node;
|
||||
if let PatKind::Binding(bind_ann, ..) = pat.kind;
|
||||
if !matches!(bind_ann, BindingAnnotation::RefMut | BindingAnnotation::Mutable);
|
||||
let parent_node = cx.tcx.hir().get_parent_node(hir_id);
|
||||
|
|
|
@ -9,7 +9,7 @@ use clippy_utils::{
|
|||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::{def::Res, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp};
|
||||
use rustc_hir::{def::Res, Closure, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
|
@ -222,7 +222,7 @@ fn uses_iter<'tcx>(cx: &LateContext<'tcx>, iter_expr: &IterExpr, container: &'tc
|
|||
if let Some(e) = e {
|
||||
self.visit_expr(e);
|
||||
}
|
||||
} else if let ExprKind::Closure { body: id, .. } = e.kind {
|
||||
} else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
|
||||
if is_res_used(self.cx, self.iter_expr.path, id) {
|
||||
self.uses_iter = true;
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
|
|||
if let Some(e) = e {
|
||||
self.visit_expr(e);
|
||||
}
|
||||
} else if let ExprKind::Closure { body: id, .. } = e.kind {
|
||||
} else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
|
||||
self.used_iter = is_res_used(self.cx, self.iter_expr.path, id);
|
||||
} else {
|
||||
walk_expr(self, e);
|
||||
|
@ -319,7 +319,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
|
|||
if let Some(e) = e {
|
||||
self.visit_expr(e);
|
||||
}
|
||||
} else if let ExprKind::Closure { body: id, .. } = e.kind {
|
||||
} else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
|
||||
self.used_after = is_res_used(self.cx, self.iter_expr.path, id);
|
||||
} else {
|
||||
walk_expr(self, e);
|
||||
|
|
|
@ -6,8 +6,8 @@ use if_chain::if_chain;
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId,
|
||||
IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||
AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
|
||||
HirId, IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -177,7 +177,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>)
|
|||
if let Some(block_expr) = block.expr;
|
||||
if let Some(args) = match_function_call(cx, block_expr, &FUTURE_FROM_GENERATOR);
|
||||
if args.len() == 1;
|
||||
if let Expr{kind: ExprKind::Closure { body, .. }, ..} = args[0];
|
||||
if let Expr{kind: ExprKind::Closure(&Closure { body, .. }), ..} = args[0];
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
if closure_body.generator_kind == Some(GeneratorKind::Async(AsyncGeneratorKind::Block));
|
||||
then {
|
||||
|
|
|
@ -5,7 +5,7 @@ use clippy_utils::{is_lang_ctor, path_to_local_id};
|
|||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::{ResultErr, ResultOk};
|
||||
use rustc_hir::{Expr, ExprKind, PatKind};
|
||||
use rustc_hir::{Closure, Expr, ExprKind, PatKind};
|
||||
use rustc_lint::LintContext;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
@ -88,7 +88,7 @@ fn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool {
|
|||
}
|
||||
}
|
||||
if_chain! {
|
||||
if let ExprKind::Closure { body, .. } = map_expr.kind;
|
||||
if let ExprKind::Closure(&Closure { body, .. }) = map_expr.kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind;
|
||||
if let ExprKind::Call(Expr { kind: ExprKind::Path(ok_path), .. }, &[ref ok_arg]) = body.value.kind;
|
||||
|
|
|
@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
|
|||
// Also ensures the const is nonzero since zero can't be a divisor
|
||||
&& const1 == const2 && const2 == const3
|
||||
&& let Some(hir_id) = path_to_local(expr3)
|
||||
&& let Some(Node::Binding(_)) = cx.tcx.hir().find(hir_id) {
|
||||
&& let Some(Node::Pat(_)) = cx.tcx.hir().find(hir_id) {
|
||||
// Apply only to params or locals with annotated types
|
||||
match cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
|
||||
Some(Node::Param(..)) => (),
|
||||
|
|
|
@ -148,7 +148,7 @@ fn check_to_owned(
|
|||
|
||||
fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::Expr<'_>, filter_expr: &hir::Expr<'_>) {
|
||||
if let hir::ExprKind::MethodCall(_, [_, closure], _) = filter_expr.kind
|
||||
&& let hir::ExprKind::Closure{ body, ..} = closure.kind
|
||||
&& let hir::ExprKind::Closure(&hir::Closure { body, ..}) = closure.kind
|
||||
&& let filter_body = cx.tcx.hir().body(body)
|
||||
&& let [filter_params] = filter_body.params
|
||||
&& let Some(sugg) = match filter_params.pat.kind {
|
||||
|
|
|
@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for MapClone {
|
|||
if method.ident.name == sym::map;
|
||||
let ty = cx.typeck_results().expr_ty(&args[0]);
|
||||
if is_type_diagnostic_item(cx, ty, sym::Option) || is_trait_method(cx, e, sym::Iterator);
|
||||
if let hir::ExprKind::Closure { body, .. } = args[1].kind;
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = args[1].kind;
|
||||
then {
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&closure_body.value);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_hir::{CaptureBy, Expr, ExprKind, PatKind};
|
||||
use rustc_hir::{CaptureBy, Closure, Expr, ExprKind, PatKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
|
@ -119,12 +119,12 @@ impl<'tcx> LateLintPass<'tcx> for MapErrIgnore {
|
|||
if method.ident.as_str() == "map_err" && args.len() == 2 {
|
||||
// make sure the first argument is a closure, and grab the CaptureRef, BodyId, and fn_decl_span
|
||||
// fields
|
||||
if let ExprKind::Closure {
|
||||
if let ExprKind::Closure(&Closure {
|
||||
capture_clause,
|
||||
body,
|
||||
fn_decl_span,
|
||||
..
|
||||
} = args[1].kind
|
||||
}) = args[1].kind
|
||||
{
|
||||
// check if this is by Reference (meaning there's no move statement)
|
||||
if capture_clause == CaptureBy::Ref {
|
||||
|
|
|
@ -169,7 +169,7 @@ fn unit_closure<'tcx>(
|
|||
expr: &hir::Expr<'_>,
|
||||
) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> {
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Closure { fn_decl, body, .. } = expr.kind;
|
||||
if let hir::ExprKind::Closure(&hir::Closure { fn_decl, body, .. }) = expr.kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
let body_expr = &body.value;
|
||||
if fn_decl.inputs.len() == 1;
|
||||
|
|
|
@ -1041,7 +1041,8 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
|
|||
}
|
||||
|
||||
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
|
||||
self.infallible_destructuring_match_linted |= infallible_destructuring_match::check(cx, local);
|
||||
self.infallible_destructuring_match_linted |=
|
||||
local.els.is_none() && infallible_destructuring_match::check(cx, local);
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
|
||||
|
|
|
@ -150,7 +150,7 @@ pub(crate) trait BindInsteadOfMap {
|
|||
}
|
||||
|
||||
match arg.kind {
|
||||
hir::ExprKind::Closure { body, fn_decl_span, .. } => {
|
||||
hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) => {
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&closure_body.value);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use if_chain::if_chain;
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{Expr, ExprKind, PatKind, PathSegment, QPath, UnOp};
|
||||
use rustc_hir::{Closure, Expr, ExprKind, PatKind, PathSegment, QPath, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_span::source_map::Span;
|
||||
|
@ -23,8 +23,8 @@ fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
|
|||
hir::ExprKind::Path(QPath::Resolved(_, segments)) => {
|
||||
segments.segments.last().unwrap().ident.name == method_name
|
||||
},
|
||||
hir::ExprKind::Closure { body, .. } => {
|
||||
let body = cx.tcx.hir().body(*body);
|
||||
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&body.value);
|
||||
let arg_id = body.params[0].pat.hir_id;
|
||||
match closure_expr.kind {
|
||||
|
@ -95,7 +95,7 @@ pub(super) fn check<'tcx>(
|
|||
if is_trait_method(cx, map_recv, sym::Iterator);
|
||||
|
||||
// filter(|x| ...is_some())...
|
||||
if let ExprKind::Closure { body: filter_body_id, .. } = filter_arg.kind;
|
||||
if let ExprKind::Closure(&Closure { body: filter_body_id, .. }) = filter_arg.kind;
|
||||
let filter_body = cx.tcx.hir().body(filter_body_id);
|
||||
if let [filter_param] = filter_body.params;
|
||||
// optional ref pattern: `filter(|&x| ..)`
|
||||
|
@ -118,7 +118,7 @@ pub(super) fn check<'tcx>(
|
|||
if path.ident.name.as_str() == if is_result { "is_ok" } else { "is_some" };
|
||||
|
||||
// ...map(|x| ...unwrap())
|
||||
if let ExprKind::Closure { body: map_body_id, .. } = map_arg.kind;
|
||||
if let ExprKind::Closure(&Closure { body: map_body_id, .. }) = map_arg.kind;
|
||||
let map_body = cx.tcx.hir().body(map_body_id);
|
||||
if let [map_param] = map_body.params;
|
||||
if let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind;
|
||||
|
|
|
@ -22,7 +22,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
|
|||
|diag| {
|
||||
if_chain! {
|
||||
if let Some(id) = path_to_local(recv);
|
||||
if let Node::Binding(pat) = cx.tcx.hir().get(id);
|
||||
if let Node::Pat(pat) = cx.tcx.hir().get(id);
|
||||
if let PatKind::Binding(ann, _, _, _) = pat.kind;
|
||||
if ann != BindingAnnotation::Mutable;
|
||||
then {
|
||||
|
|
|
@ -51,7 +51,7 @@ pub(super) fn check<'tcx>(
|
|||
.map_or(false, |fun_def_id| {
|
||||
deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path))
|
||||
}),
|
||||
hir::ExprKind::Closure { body, .. } => {
|
||||
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&closure_body.value);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ pub(super) fn check<'tcx>(
|
|||
if is_option {
|
||||
let self_snippet = snippet(cx, recv.span, "..");
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Closure { body, fn_decl_span, .. } = map_arg.kind;
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = map_arg.kind;
|
||||
let arg_snippet = snippet(cx, fn_decl_span, "..");
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if let Some((func, [arg_char])) = reduce_unit_expression(&body.value);
|
||||
|
|
|
@ -41,7 +41,7 @@ pub(super) fn check<'tcx>(
|
|||
let mut applicability = Applicability::MachineApplicable;
|
||||
let any_search_snippet = if_chain! {
|
||||
if search_method == "find";
|
||||
if let hir::ExprKind::Closure { body, .. } = search_arg.kind;
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind;
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
if let Some(closure_arg) = closure_body.params.get(0);
|
||||
then {
|
||||
|
|
|
@ -18,7 +18,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
|
|||
return;
|
||||
}
|
||||
|
||||
if let hir::ExprKind::Closure { body, .. } = arg.kind {
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
let arg_id = body.params[0].pat.hir_id;
|
||||
let mutates_arg =
|
||||
|
|
|
@ -29,7 +29,7 @@ pub(super) fn check(
|
|||
) {
|
||||
if_chain! {
|
||||
// Extract the body of the closure passed to fold
|
||||
if let hir::ExprKind::Closure { body, .. } = acc.kind;
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind;
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
let closure_expr = peel_blocks(&closure_body.value);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(
|
|||
let is_bool = cx.typeck_results().expr_ty(recv).is_bool();
|
||||
|
||||
if is_option || is_result || is_bool {
|
||||
if let hir::ExprKind::Closure { body, .. } = arg.kind {
|
||||
if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind {
|
||||
let body = cx.tcx.hir().body(body);
|
||||
let body_expr = &body.value;
|
||||
|
||||
|
|
|
@ -301,7 +301,7 @@ fn in_attributes_expansion(expr: &Expr<'_>) -> bool {
|
|||
use rustc_span::hygiene::MacroKind;
|
||||
if expr.span.from_expansion() {
|
||||
let data = expr.span.ctxt().outer_expn_data();
|
||||
matches!(data.kind, ExpnKind::Macro(MacroKind::Attr, _))
|
||||
matches!(data.kind, ExpnKind::Macro(MacroKind::Attr | MacroKind::Derive, _))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint;
|
|||
use clippy_utils::trait_ref_of_method;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::TypeFoldable;
|
||||
use rustc_middle::ty::TypeVisitable;
|
||||
use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::source_map::Span;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{
|
||||
intravisit::{walk_expr, Visitor},
|
||||
Expr, ExprKind, Stmt, StmtKind,
|
||||
Closure, Expr, ExprKind, Stmt, StmtKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
|
|||
if has_iter_method(cx, cx.typeck_results().expr_ty(iter_recv)).is_some();
|
||||
// Skip the lint if the body is not block because this is simpler than `for` loop.
|
||||
// e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop.
|
||||
if let ExprKind::Closure { body, .. } = for_each_arg.kind;
|
||||
if let ExprKind::Closure(&Closure { body, .. }) = for_each_arg.kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
if let ExprKind::Block(..) = body.value.kind;
|
||||
then {
|
||||
|
|
|
@ -13,7 +13,7 @@ use rustc_hir::{HirIdMap, HirIdSet};
|
|||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::mir::FakeReadCause;
|
||||
use rustc_middle::ty::{self, TypeFoldable};
|
||||
use rustc_middle::ty::{self, TypeVisitable};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::kw;
|
||||
use rustc_span::{sym, Span};
|
||||
|
|
|
@ -92,6 +92,7 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
|
|||
if_chain! {
|
||||
if !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id);
|
||||
if let Some(init) = local.init;
|
||||
if local.els.is_none();
|
||||
if !local.pat.span.from_expansion();
|
||||
if has_no_effect(cx, init);
|
||||
if let PatKind::Binding(_, _, ident, _) = local.pat.kind;
|
||||
|
|
|
@ -148,7 +148,7 @@ fn is_value_unfrozen_raw<'tcx>(
|
|||
match val.ty().kind() {
|
||||
// the fact that we have to dig into every structs to search enums
|
||||
// leads us to the point checking `UnsafeCell` directly is the only option.
|
||||
ty::Adt(ty_def, ..) if Some(ty_def.did()) == cx.tcx.lang_items().unsafe_cell_type() => true,
|
||||
ty::Adt(ty_def, ..) if ty_def.is_unsafe_cell() => true,
|
||||
ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
|
||||
let val = cx.tcx.destructure_mir_constant(cx.param_env, val);
|
||||
val.fields.iter().any(|field| inner(cx, *field))
|
||||
|
|
|
@ -11,8 +11,8 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
use rustc_hir::intravisit::{walk_expr, walk_stmt, FnKind, Visitor};
|
||||
use rustc_hir::{
|
||||
Arm, Block, Body, Expr, ExprKind, Guard, HirId, ImplicitSelfKind, Let, Local, Pat, PatKind, Path, PathSegment,
|
||||
QPath, Stmt, StmtKind, TyKind, UnOp,
|
||||
Arm, Block, Body, Closure, Expr, ExprKind, Guard, HirId, ImplicitSelfKind, Let, Local, Pat, PatKind, Path,
|
||||
PathSegment, QPath, Stmt, StmtKind, TyKind, UnOp,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
|
@ -298,7 +298,7 @@ impl<'tcx> Visitor<'tcx> for SideEffectVisit<'tcx> {
|
|||
},
|
||||
ExprKind::Match(expr, arms, _) => self.visit_match(expr, arms),
|
||||
// since analysing the closure is not easy, just set all variables in it to side-effect
|
||||
ExprKind::Closure { body, .. } => {
|
||||
ExprKind::Closure(&Closure { body, .. }) => {
|
||||
let body = self.tcx.hir().body(body);
|
||||
self.visit_body(body);
|
||||
let vars = std::mem::take(&mut self.ret_vars);
|
||||
|
|
|
@ -96,11 +96,12 @@ impl Context {
|
|||
}
|
||||
|
||||
pub fn enter_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
|
||||
let body_owner = cx.tcx.hir().body_owner_def_id(body.id());
|
||||
let body_owner = cx.tcx.hir().body_owner(body.id());
|
||||
let body_owner_def_id = cx.tcx.hir().local_def_id(body_owner);
|
||||
|
||||
match cx.tcx.hir().body_owner_kind(body_owner) {
|
||||
match cx.tcx.hir().body_owner_kind(body_owner_def_id) {
|
||||
hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const => {
|
||||
let body_span = cx.tcx.def_span(body_owner);
|
||||
let body_span = cx.tcx.hir().span_with_body(body_owner);
|
||||
|
||||
if let Some(span) = self.const_span {
|
||||
if span.contains(body_span) {
|
||||
|
@ -115,7 +116,7 @@ impl Context {
|
|||
|
||||
pub fn body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {
|
||||
let body_owner = cx.tcx.hir().body_owner(body.id());
|
||||
let body_span = cx.tcx.hir().span(body_owner);
|
||||
let body_span = cx.tcx.hir().span_with_body(body_owner);
|
||||
|
||||
if let Some(span) = self.const_span {
|
||||
if span.contains(body_span) {
|
||||
|
|
|
@ -495,12 +495,13 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
|
|||
if let FnRetTy::Return(ty) = sig.decl.output
|
||||
&& let Some((out, Mutability::Mut, _)) = get_rptr_lm(ty)
|
||||
{
|
||||
let out_region = cx.tcx.named_region(out.hir_id);
|
||||
let args: Option<Vec<_>> = sig
|
||||
.decl
|
||||
.inputs
|
||||
.iter()
|
||||
.filter_map(get_rptr_lm)
|
||||
.filter(|&(lt, _, _)| lt.name == out.name)
|
||||
.filter(|&(lt, _, _)| cx.tcx.named_region(lt.hir_id) == out_region)
|
||||
.map(|(_, mutability, span)| (mutability == Mutability::Not).then_some(span))
|
||||
.collect();
|
||||
if let Some(args) = args
|
||||
|
|
|
@ -14,7 +14,7 @@ use rustc_middle::mir::{
|
|||
visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor as _},
|
||||
Mutability,
|
||||
};
|
||||
use rustc_middle::ty::{self, fold::TypeVisitor, Ty};
|
||||
use rustc_middle::ty::{self, visit::TypeVisitor, Ty};
|
||||
use rustc_mir_dataflow::{Analysis, AnalysisDomain, CallReturnPlaces, GenKill, GenKillAnalysis, ResultsCursor};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::source_map::{BytePos, Span};
|
||||
|
@ -161,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
|
|||
// `arg` is a reference as it is `.deref()`ed in the previous block.
|
||||
// Look into the predecessor block and find out the source of deref.
|
||||
|
||||
let ps = &mir.predecessors()[bb];
|
||||
let ps = &mir.basic_blocks.predecessors()[bb];
|
||||
if ps.len() != 1 {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ impl EarlyLintPass for RedundantClosureCall {
|
|||
if_chain! {
|
||||
if let ast::ExprKind::Call(ref paren, _) = expr.kind;
|
||||
if let ast::ExprKind::Paren(ref closure) = paren.kind;
|
||||
if let ast::ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.kind;
|
||||
if let ast::ExprKind::Closure(_, _, _, _, ref decl, ref block, _) = closure.kind;
|
||||
then {
|
||||
let mut visitor = ReturnVisitor::new();
|
||||
visitor.visit_expr(block);
|
||||
|
|
|
@ -10,7 +10,6 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
|
|||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::sym;
|
||||
|
||||
|
@ -203,9 +202,7 @@ fn check_final_expr<'tcx>(
|
|||
check_block_return(cx, ifblock);
|
||||
}
|
||||
if let Some(else_clause) = else_clause_opt {
|
||||
if expr.span.desugaring_kind() != Some(DesugaringKind::LetElse) {
|
||||
check_final_expr(cx, else_clause, None, RetReplacement::Empty);
|
||||
}
|
||||
check_final_expr(cx, else_clause, None, RetReplacement::Empty);
|
||||
}
|
||||
},
|
||||
// a match expr, check all arms
|
||||
|
|
|
@ -582,7 +582,7 @@ fn ident_difference_expr_with_base_location(
|
|||
| (Await(_), Await(_))
|
||||
| (Async(_, _, _), Async(_, _, _))
|
||||
| (Block(_, _), Block(_, _))
|
||||
| (Closure(_, _, _, _, _, _), Closure(_, _, _, _, _, _))
|
||||
| (Closure(_, _, _, _, _, _, _), Closure(_, _, _, _, _, _, _))
|
||||
| (Match(_, _), Match(_, _))
|
||||
| (Loop(_, _), Loop(_, _))
|
||||
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _))
|
||||
|
|
|
@ -5,7 +5,7 @@ use clippy_utils::{meets_msrv, msrvs, sugg};
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{self as hir, Expr, GenericArg, Mutability, Path, TyKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, Ty, TypeFoldable};
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitable};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
||||
/// Checks for `transmute_ptr_to_ref` lint.
|
||||
|
|
|
@ -4,7 +4,7 @@ use clippy_utils::sugg;
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, Ty, TypeFoldable};
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitable};
|
||||
|
||||
/// Checks for `useless_transmute` lint.
|
||||
/// Returns `true` if it's triggered, otherwise returns `false`.
|
||||
|
|
|
@ -31,7 +31,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
|
|||
return false;
|
||||
}
|
||||
|
||||
let ltopt = if lt.is_elided() {
|
||||
let ltopt = if lt.name.is_anonymous() {
|
||||
String::new()
|
||||
} else {
|
||||
format!("{} ", lt.name.ident().as_str())
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_errors::Applicability;
|
|||
use rustc_hir::{self as hir, def_id::DefId, GenericArg, QPath, TyKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::TypeFoldable;
|
||||
use rustc_middle::ty::TypeVisitable;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
|
|||
use clippy_utils::{get_trait_def_id, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{Expr, ExprKind, StmtKind};
|
||||
use rustc_hir::{Closure, Expr, ExprKind, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::{GenericPredicates, PredicateKind, ProjectionPredicate, TraitPredicate};
|
||||
|
@ -116,7 +116,7 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve
|
|||
|
||||
fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> {
|
||||
if_chain! {
|
||||
if let ExprKind::Closure { body, fn_decl_span, .. } = arg.kind;
|
||||
if let ExprKind::Closure(&Closure { body, fn_decl_span, .. }) = arg.kind;
|
||||
if let ty::Closure(_def_id, substs) = &cx.typeck_results().node_type(arg.hir_id).kind();
|
||||
let ret_ty = substs.as_closure().sig().output();
|
||||
let ty = cx.tcx.erase_late_bound_regions(ret_ty);
|
||||
|
|
|
@ -3,7 +3,7 @@ use clippy_utils::sugg::Sugg;
|
|||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};
|
||||
use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{self, subst::GenericArgKind};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
@ -155,7 +155,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
|
|||
if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind;
|
||||
if let name = name_ident.ident.name.to_ident_string();
|
||||
if name == "sort_by" || name == "sort_unstable_by";
|
||||
if let [vec, Expr { kind: ExprKind::Closure{ body: closure_body_id, .. }, .. }] = args;
|
||||
if let [vec, Expr { kind: ExprKind::Closure(Closure { body: closure_body_id, .. }), .. }] = args;
|
||||
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(vec), sym::Vec);
|
||||
if let closure_body = cx.tcx.hir().body(*closure_body_id);
|
||||
if let &[
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_ast::ast::{LitFloatType, LitKind};
|
|||
use rustc_ast::LitIntType;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{ArrayLen, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind};
|
||||
use rustc_hir::{ArrayLen, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
|
@ -466,13 +466,13 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
self.expr(scrutinee);
|
||||
self.slice(arms, |arm| self.arm(arm));
|
||||
},
|
||||
ExprKind::Closure {
|
||||
ExprKind::Closure(&Closure {
|
||||
capture_clause,
|
||||
fn_decl,
|
||||
body: body_id,
|
||||
movability,
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
let movability = OptionPat::new(movability.map(|m| format!("Movability::{m:?}")));
|
||||
|
||||
let ret_ty = match fn_decl.output {
|
||||
|
|
|
@ -20,8 +20,8 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::hir_id::CRATE_HIR_ID;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{
|
||||
BinOpKind, Block, Expr, ExprKind, HirId, Item, Local, MutTy, Mutability, Node, Path, Stmt, StmtKind, Ty, TyKind,
|
||||
UnOp,
|
||||
BinOpKind, Block, Closure, Expr, ExprKind, HirId, Item, Local, MutTy, Mutability, Node, Path, Stmt, StmtKind, Ty,
|
||||
TyKind, UnOp,
|
||||
};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
@ -730,8 +730,8 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls {
|
|||
if let ExprKind::Call(func, and_then_args) = expr.kind;
|
||||
if is_expr_path_def_path(cx, func, &["clippy_utils", "diagnostics", "span_lint_and_then"]);
|
||||
if and_then_args.len() == 5;
|
||||
if let ExprKind::Closure { body, .. } = &and_then_args[4].kind;
|
||||
let body = cx.tcx.hir().body(*body);
|
||||
if let ExprKind::Closure(&Closure { body, .. }) = &and_then_args[4].kind;
|
||||
let body = cx.tcx.hir().body(body);
|
||||
let only_expr = peel_blocks_with_stmt(&body.value);
|
||||
if let ExprKind::MethodCall(ps, span_call_args, _) = &only_expr.kind;
|
||||
if let ExprKind::Path(..) = span_call_args[0].kind;
|
||||
|
|
|
@ -17,7 +17,7 @@ use if_chain::if_chain;
|
|||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::{
|
||||
self as hir, def::DefKind, intravisit, intravisit::Visitor, ExprKind, Item, ItemKind, Mutability, QPath,
|
||||
self as hir, def::DefKind, intravisit, intravisit::Visitor, Closure, ExprKind, Item, ItemKind, Mutability, QPath,
|
||||
};
|
||||
use rustc_lint::{CheckLintNameResult, LateContext, LateLintPass, LintContext, LintId};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
@ -958,7 +958,7 @@ fn resolve_applicability<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hi
|
|||
}
|
||||
|
||||
fn check_is_multi_part<'hir>(cx: &LateContext<'hir>, closure_expr: &'hir hir::Expr<'hir>) -> bool {
|
||||
if let ExprKind::Closure { body, .. } = closure_expr.kind {
|
||||
if let ExprKind::Closure(&Closure { body, .. }) = closure_expr.kind {
|
||||
let mut scanner = IsMultiSpanScanner::new(cx);
|
||||
intravisit::walk_body(&mut scanner, cx.tcx.hir().body(body));
|
||||
return scanner.is_multi_part();
|
||||
|
|
|
@ -4,7 +4,7 @@ use if_chain::if_chain;
|
|||
use rustc_hir::{self as hir, HirId, ItemKind, Node};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::layout::LayoutOf as _;
|
||||
use rustc_middle::ty::{Adt, Ty, TypeFoldable};
|
||||
use rustc_middle::ty::{Adt, Ty, TypeVisitable};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
|
|
|
@ -168,8 +168,13 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
|||
(AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
|
||||
(Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
|
||||
(Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
|
||||
(Closure(lc, la, lm, lf, lb, _), Closure(rc, ra, rm, rf, rb, _)) => {
|
||||
lc == rc && la.is_async() == ra.is_async() && lm == rm && eq_fn_decl(lf, rf) && eq_expr(lb, rb)
|
||||
(Closure(lb, lc, la, lm, lf, le, _), Closure(rb, rc, ra, rm, rf, re, _)) => {
|
||||
eq_closure_binder(lb, rb)
|
||||
&& lc == rc
|
||||
&& la.is_async() == ra.is_async()
|
||||
&& lm == rm
|
||||
&& eq_fn_decl(lf, rf)
|
||||
&& eq_expr(le, re)
|
||||
},
|
||||
(Async(lc, _, lb), Async(rc, _, rb)) => lc == rc && eq_block(lb, rb),
|
||||
(Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt),
|
||||
|
@ -561,6 +566,16 @@ pub fn eq_fn_decl(l: &FnDecl, r: &FnDecl) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn eq_closure_binder(l: &ClosureBinder, r: &ClosureBinder) -> bool {
|
||||
match (l, r) {
|
||||
(ClosureBinder::NotPresent, ClosureBinder::NotPresent) => true,
|
||||
(ClosureBinder::For { generic_params: lp, .. }, ClosureBinder::For { generic_params: rp, .. }) => {
|
||||
lp.len() == rp.len() && std::iter::zip(lp.iter(), rp.iter()).all(|(l, r)| eq_generic_param(l, r))
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eq_fn_ret_ty(l: &FnRetTy, r: &FnRetTy) -> bool {
|
||||
match (l, r) {
|
||||
(FnRetTy::Default(_), FnRetTy::Default(_)) => true,
|
||||
|
@ -600,8 +615,8 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
|
|||
pub fn eq_ext(l: &Extern, r: &Extern) -> bool {
|
||||
use Extern::*;
|
||||
match (l, r) {
|
||||
(None, None) | (Implicit, Implicit) => true,
|
||||
(Explicit(l), Explicit(r)) => eq_str_lit(l, r),
|
||||
(None, None) | (Implicit(_), Implicit(_)) => true,
|
||||
(Explicit(l, _), Explicit(r, _)) => eq_str_lit(l, r),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ use rustc_data_structures::fx::FxHasher;
|
|||
use rustc_hir::def::Res;
|
||||
use rustc_hir::HirIdMap;
|
||||
use rustc_hir::{
|
||||
ArrayLen, BinOpKind, Block, BodyId, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, HirId,
|
||||
InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, Stmt,
|
||||
StmtKind, Ty, TyKind, TypeBinding,
|
||||
ArrayLen, BinOpKind, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard,
|
||||
HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath,
|
||||
Stmt, StmtKind, Ty, TyKind, TypeBinding,
|
||||
};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
@ -117,6 +117,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
// these only get added if the init and type is equal.
|
||||
both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
|
||||
&& both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r))
|
||||
&& both(&l.els, &r.els, |l, r| self.eq_block(l, r))
|
||||
&& self.eq_pat(l.pat, r.pat)
|
||||
},
|
||||
(&StmtKind::Expr(l), &StmtKind::Expr(r)) | (&StmtKind::Semi(l), &StmtKind::Semi(r)) => self.eq_expr(l, r),
|
||||
|
@ -662,9 +663,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
self.hash_expr(e);
|
||||
self.hash_ty(ty);
|
||||
},
|
||||
ExprKind::Closure {
|
||||
ExprKind::Closure(&Closure {
|
||||
capture_clause, body, ..
|
||||
} => {
|
||||
}) => {
|
||||
std::mem::discriminant(&capture_clause).hash(&mut self.s);
|
||||
// closures inherit TypeckResults
|
||||
self.hash_expr(&self.cx.tcx.hir().body(body).value);
|
||||
|
@ -926,6 +927,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
if let Some(init) = local.init {
|
||||
self.hash_expr(init);
|
||||
}
|
||||
if let Some(els) = local.els {
|
||||
self.hash_block(els);
|
||||
}
|
||||
},
|
||||
StmtKind::Item(..) => {},
|
||||
StmtKind::Expr(expr) | StmtKind::Semi(expr) => {
|
||||
|
|
|
@ -79,10 +79,10 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
|
|||
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
||||
use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
|
||||
use rustc_hir::{
|
||||
def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr, ExprKind, FnDecl,
|
||||
HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource, Mutability, Node,
|
||||
Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind,
|
||||
UnOp,
|
||||
def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination, Expr,
|
||||
ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource,
|
||||
Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
|
||||
TraitRef, TyKind, UnOp,
|
||||
};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc_middle::hir::place::PlaceBase;
|
||||
|
@ -94,7 +94,7 @@ use rustc_middle::ty::fast_reject::SimplifiedTypeGen::{
|
|||
PtrSimplifiedType, SliceSimplifiedType, StrSimplifiedType, UintSimplifiedType,
|
||||
};
|
||||
use rustc_middle::ty::{
|
||||
layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeFoldable, UpvarCapture,
|
||||
layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitable, UpvarCapture,
|
||||
};
|
||||
use rustc_middle::ty::{FloatTy, IntTy, UintTy};
|
||||
use rustc_semver::RustcVersion;
|
||||
|
@ -185,7 +185,7 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr
|
|||
pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
|
||||
let hir = cx.tcx.hir();
|
||||
if_chain! {
|
||||
if let Some(Node::Binding(pat)) = hir.find(hir_id);
|
||||
if let Some(Node::Pat(pat)) = hir.find(hir_id);
|
||||
if matches!(pat.kind, PatKind::Binding(BindingAnnotation::Unannotated, ..));
|
||||
let parent = hir.get_parent_node(hir_id);
|
||||
if let Some(Node::Local(local)) = hir.find(parent);
|
||||
|
@ -1739,7 +1739,7 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t
|
|||
_,
|
||||
&[
|
||||
Expr {
|
||||
kind: ExprKind::Closure { body, .. },
|
||||
kind: ExprKind::Closure(&Closure { body, .. }),
|
||||
..
|
||||
},
|
||||
],
|
||||
|
@ -1826,7 +1826,7 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool
|
|||
}
|
||||
|
||||
match expr.kind {
|
||||
ExprKind::Closure { body, .. } => is_body_identity_function(cx, cx.tcx.hir().body(body)),
|
||||
ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir().body(body)),
|
||||
_ => path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, &paths::CONVERT_IDENTITY)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,7 @@ fn check_rvalue<'tcx>(
|
|||
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
|
||||
check_place(tcx, *place, span, body)
|
||||
},
|
||||
Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body),
|
||||
Rvalue::Repeat(operand, _)
|
||||
| Rvalue::Use(operand)
|
||||
| Rvalue::Cast(
|
||||
|
@ -353,7 +354,7 @@ fn check_terminator<'a, 'tcx>(
|
|||
fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<RustcVersion>) -> bool {
|
||||
tcx.is_const_fn(def_id)
|
||||
&& tcx.lookup_const_stability(def_id).map_or(true, |const_stab| {
|
||||
if let rustc_attr::StabilityLevel::Stable { since } = const_stab.level {
|
||||
if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level {
|
||||
// Checking MSRV is manually necessary because `rustc` has no such concept. This entire
|
||||
// function could be removed if `rustc` provided a MSRV-aware version of `is_const_fn`.
|
||||
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc_ast::{ast, token};
|
|||
use rustc_ast_pretty::pprust::token_kind_to_string;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{ExprKind, HirId, MutTy, TyKind};
|
||||
use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{EarlyContext, LateContext, LintContext};
|
||||
use rustc_middle::hir::place::ProjectionKind;
|
||||
|
@ -790,7 +790,7 @@ pub struct DerefClosure {
|
|||
///
|
||||
/// note: this only works on single line immutable closures with exactly one input parameter.
|
||||
pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, closure: &'tcx hir::Expr<'_>) -> Option<DerefClosure> {
|
||||
if let hir::ExprKind::Closure { fn_decl, body, .. } = closure.kind {
|
||||
if let hir::ExprKind::Closure(&Closure { fn_decl, body, .. }) = closure.kind {
|
||||
let closure_body = cx.tcx.hir().body(body);
|
||||
// is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`)
|
||||
// a type annotation is present if param `kind` is different from `TyKind::Infer`
|
||||
|
|
|
@ -15,7 +15,7 @@ use rustc_middle::mir::interpret::{ConstValue, Scalar};
|
|||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{
|
||||
self, AdtDef, Binder, BoundRegion, DefIdTree, FnSig, IntTy, ParamEnv, Predicate, PredicateKind, ProjectionTy,
|
||||
Region, RegionKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitor, UintTy, VariantDef, VariantDiscr,
|
||||
Region, RegionKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, VariantDef, VariantDiscr,
|
||||
};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
||||
|
@ -773,7 +773,7 @@ pub fn for_each_top_level_late_bound_region<B>(
|
|||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_binder<T: TypeVisitable<'tcx>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> {
|
||||
self.index += 1;
|
||||
let res = t.super_visit_with(self);
|
||||
self.index -= 1;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2022-06-30"
|
||||
channel = "nightly-2022-07-15"
|
||||
components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||
|
|
|
@ -117,7 +117,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
|
|||
// run on the unoptimized MIR. On the other hand this results in some false negatives. If
|
||||
// MIR passes can be enabled / disabled separately, we should figure out, what passes to
|
||||
// use for Clippy.
|
||||
config.opts.debugging_opts.mir_opt_level = Some(0);
|
||||
config.opts.unstable_opts.mir_opt_level = Some(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
|
|||
|
||||
/// All crates used in UI tests are listed here
|
||||
static TEST_DEPENDENCIES: &[&str] = &[
|
||||
"clap",
|
||||
"clippy_lints",
|
||||
"clippy_utils",
|
||||
"derive_new",
|
||||
|
@ -43,8 +42,6 @@ static TEST_DEPENDENCIES: &[&str] = &[
|
|||
// Test dependencies may need an `extern crate` here to ensure that they show up
|
||||
// in the depinfo file (otherwise cargo thinks they are unused)
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate clap;
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate clippy_lints;
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate clippy_utils;
|
||||
|
|
1
tests/ui-cargo/duplicate_mod/fail/src/d.rs
Normal file
1
tests/ui-cargo/duplicate_mod/fail/src/d.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#![feature(lint_reasons)]
|
||||
|
||||
mod a;
|
||||
|
||||
mod b;
|
||||
|
@ -13,4 +15,14 @@ mod c3;
|
|||
mod from_other_module;
|
||||
mod other_module;
|
||||
|
||||
mod d;
|
||||
#[path = "d.rs"]
|
||||
mod d2;
|
||||
#[path = "d.rs"]
|
||||
#[expect(clippy::duplicate_mod)]
|
||||
mod d3;
|
||||
#[path = "d.rs"]
|
||||
#[allow(clippy::duplicate_mod)]
|
||||
mod d4;
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: file is loaded as a module multiple times: `$DIR/b.rs`
|
||||
--> $DIR/main.rs:3:1
|
||||
--> $DIR/main.rs:5:1
|
||||
|
|
||||
LL | mod b;
|
||||
| ^^^^^^ first loaded here
|
||||
|
@ -11,7 +11,7 @@ LL | | mod b2;
|
|||
= help: replace all but one `mod` item with `use` items
|
||||
|
||||
error: file is loaded as a module multiple times: `$DIR/c.rs`
|
||||
--> $DIR/main.rs:7:1
|
||||
--> $DIR/main.rs:9:1
|
||||
|
|
||||
LL | mod c;
|
||||
| ^^^^^^ first loaded here
|
||||
|
@ -24,8 +24,19 @@ LL | | mod c3;
|
|||
|
|
||||
= help: replace all but one `mod` item with `use` items
|
||||
|
||||
error: file is loaded as a module multiple times: `$DIR/d.rs`
|
||||
--> $DIR/main.rs:18:1
|
||||
|
|
||||
LL | mod d;
|
||||
| ^^^^^^ first loaded here
|
||||
LL | / #[path = "d.rs"]
|
||||
LL | | mod d2;
|
||||
| |_______^ loaded again here
|
||||
|
|
||||
= help: replace all but one `mod` item with `use` items
|
||||
|
||||
error: file is loaded as a module multiple times: `$DIR/from_other_module.rs`
|
||||
--> $DIR/main.rs:13:1
|
||||
--> $DIR/main.rs:15:1
|
||||
|
|
||||
LL | mod from_other_module;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ first loaded here
|
||||
|
@ -38,5 +49,5 @@ LL | | mod m;
|
|||
|
|
||||
= help: replace all but one `mod` item with `use` items
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ LL | fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {
|
|||
| ^^^^^^^^^^^ expected `usize`, found closure
|
||||
|
|
||||
= note: expected type `usize`
|
||||
found closure `[closure@$DIR/ice-6251.rs:4:44: 4:55]`
|
||||
found closure `[closure@$DIR/ice-6251.rs:4:44: 4:53]`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ error[E0046]: not all trait items implemented, missing: `VAL`
|
|||
--> $DIR/ice-6252.rs:10:1
|
||||
|
|
||||
LL | const VAL: T;
|
||||
| ------------- `VAL` from trait
|
||||
| ------------ `VAL` from trait
|
||||
...
|
||||
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
|
||||
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/ice-6252.rs:13:9
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(untagged_unions)]
|
||||
#![allow(dead_code)]
|
||||
#![warn(clippy::expl_impl_clone_on_copy)]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> $DIR/derive.rs:8:1
|
||||
--> $DIR/derive.rs:7:1
|
||||
|
|
||||
LL | / impl Clone for Qux {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -10,7 +10,7 @@ LL | | }
|
|||
|
|
||||
= note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings`
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> $DIR/derive.rs:8:1
|
||||
--> $DIR/derive.rs:7:1
|
||||
|
|
||||
LL | / impl Clone for Qux {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -20,7 +20,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> $DIR/derive.rs:32:1
|
||||
--> $DIR/derive.rs:31:1
|
||||
|
|
||||
LL | / impl<'a> Clone for Lt<'a> {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -30,7 +30,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> $DIR/derive.rs:32:1
|
||||
--> $DIR/derive.rs:31:1
|
||||
|
|
||||
LL | / impl<'a> Clone for Lt<'a> {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -40,7 +40,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> $DIR/derive.rs:43:1
|
||||
--> $DIR/derive.rs:42:1
|
||||
|
|
||||
LL | / impl Clone for BigArray {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -50,7 +50,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> $DIR/derive.rs:43:1
|
||||
--> $DIR/derive.rs:42:1
|
||||
|
|
||||
LL | / impl Clone for BigArray {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -60,7 +60,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> $DIR/derive.rs:54:1
|
||||
--> $DIR/derive.rs:53:1
|
||||
|
|
||||
LL | / impl Clone for FnPtr {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -70,7 +70,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> $DIR/derive.rs:54:1
|
||||
--> $DIR/derive.rs:53:1
|
||||
|
|
||||
LL | / impl Clone for FnPtr {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -80,7 +80,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: you are implementing `Clone` explicitly on a `Copy` type
|
||||
--> $DIR/derive.rs:74:1
|
||||
--> $DIR/derive.rs:73:1
|
||||
|
|
||||
LL | / impl<T: Clone> Clone for Generic2<T> {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
@ -90,7 +90,7 @@ LL | | }
|
|||
| |_^
|
||||
|
|
||||
note: consider deriving `Clone` or removing `Copy`
|
||||
--> $DIR/derive.rs:74:1
|
||||
--> $DIR/derive.rs:73:1
|
||||
|
|
||||
LL | / impl<T: Clone> Clone for Generic2<T> {
|
||||
LL | | fn clone(&self) -> Self {
|
||||
|
|
|
@ -8,12 +8,8 @@ LL | #[derive(Hash)]
|
|||
note: `PartialEq` implemented here
|
||||
--> $DIR/derive_hash_xor_eq.rs:15:1
|
||||
|
|
||||
LL | / impl PartialEq for Bar {
|
||||
LL | | fn eq(&self, _: &Bar) -> bool {
|
||||
LL | | true
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | impl PartialEq for Bar {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: you are deriving `Hash` but have implemented `PartialEq` explicitly
|
||||
|
@ -25,12 +21,8 @@ LL | #[derive(Hash)]
|
|||
note: `PartialEq` implemented here
|
||||
--> $DIR/derive_hash_xor_eq.rs:24:1
|
||||
|
|
||||
LL | / impl PartialEq<Baz> for Baz {
|
||||
LL | | fn eq(&self, _: &Baz) -> bool {
|
||||
LL | | true
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | impl PartialEq<Baz> for Baz {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: you are implementing `Hash` explicitly but have derived `PartialEq`
|
||||
|
|
|
@ -8,12 +8,8 @@ LL | #[derive(Ord, PartialEq, Eq)]
|
|||
note: `PartialOrd` implemented here
|
||||
--> $DIR/derive_ord_xor_partial_ord.rs:24:1
|
||||
|
|
||||
LL | / impl PartialOrd for DeriveOrd {
|
||||
LL | | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
LL | | Some(other.cmp(self))
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | impl PartialOrd for DeriveOrd {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: you are deriving `Ord` but have implemented `PartialOrd` explicitly
|
||||
|
@ -25,12 +21,8 @@ LL | #[derive(Ord, PartialEq, Eq)]
|
|||
note: `PartialOrd` implemented here
|
||||
--> $DIR/derive_ord_xor_partial_ord.rs:33:1
|
||||
|
|
||||
LL | / impl PartialOrd<DeriveOrdWithExplicitTypeVariable> for DeriveOrdWithExplicitTypeVariable {
|
||||
LL | | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
LL | | Some(other.cmp(self))
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | impl PartialOrd<DeriveOrdWithExplicitTypeVariable> for DeriveOrdWithExplicitTypeVariable {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: you are implementing `Ord` explicitly but have derived `PartialOrd`
|
||||
|
|
|
@ -124,7 +124,7 @@ help: consider marking this type as `Copy`
|
|||
--> $DIR/needless_pass_by_value.rs:123:1
|
||||
|
|
||||
LL | struct CopyWrapper(u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:131:29
|
||||
|
@ -136,7 +136,7 @@ help: consider marking this type as `Copy`
|
|||
--> $DIR/needless_pass_by_value.rs:123:1
|
||||
|
|
||||
LL | struct CopyWrapper(u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:131:45
|
||||
|
@ -148,7 +148,7 @@ help: consider marking this type as `Copy`
|
|||
--> $DIR/needless_pass_by_value.rs:123:1
|
||||
|
|
||||
LL | struct CopyWrapper(u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:131:61
|
||||
|
@ -160,7 +160,7 @@ help: consider marking this type as `Copy`
|
|||
--> $DIR/needless_pass_by_value.rs:123:1
|
||||
|
|
||||
LL | struct CopyWrapper(u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this argument is passed by value, but not consumed in the function body
|
||||
--> $DIR/needless_pass_by_value.rs:143:40
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#![allow(path_statements)]
|
||||
#![allow(clippy::deref_addrof)]
|
||||
#![allow(clippy::redundant_field_names)]
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
struct Unit;
|
||||
struct Tuple(i32);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:95:5
|
||||
--> $DIR/no_effect.rs:94:5
|
||||
|
|
||||
LL | 0;
|
||||
| ^^
|
||||
|
@ -7,157 +7,157 @@ LL | 0;
|
|||
= note: `-D clippy::no-effect` implied by `-D warnings`
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:96:5
|
||||
--> $DIR/no_effect.rs:95:5
|
||||
|
|
||||
LL | s2;
|
||||
| ^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:97:5
|
||||
--> $DIR/no_effect.rs:96:5
|
||||
|
|
||||
LL | Unit;
|
||||
| ^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:98:5
|
||||
--> $DIR/no_effect.rs:97:5
|
||||
|
|
||||
LL | Tuple(0);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:99:5
|
||||
--> $DIR/no_effect.rs:98:5
|
||||
|
|
||||
LL | Struct { field: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:100:5
|
||||
--> $DIR/no_effect.rs:99:5
|
||||
|
|
||||
LL | Struct { ..s };
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:101:5
|
||||
--> $DIR/no_effect.rs:100:5
|
||||
|
|
||||
LL | Union { a: 0 };
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:102:5
|
||||
--> $DIR/no_effect.rs:101:5
|
||||
|
|
||||
LL | Enum::Tuple(0);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:103:5
|
||||
--> $DIR/no_effect.rs:102:5
|
||||
|
|
||||
LL | Enum::Struct { field: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:104:5
|
||||
--> $DIR/no_effect.rs:103:5
|
||||
|
|
||||
LL | 5 + 6;
|
||||
| ^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:105:5
|
||||
--> $DIR/no_effect.rs:104:5
|
||||
|
|
||||
LL | *&42;
|
||||
| ^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:106:5
|
||||
--> $DIR/no_effect.rs:105:5
|
||||
|
|
||||
LL | &6;
|
||||
| ^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:107:5
|
||||
--> $DIR/no_effect.rs:106:5
|
||||
|
|
||||
LL | (5, 6, 7);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:108:5
|
||||
--> $DIR/no_effect.rs:107:5
|
||||
|
|
||||
LL | box 42;
|
||||
| ^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:109:5
|
||||
--> $DIR/no_effect.rs:108:5
|
||||
|
|
||||
LL | ..;
|
||||
| ^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:110:5
|
||||
--> $DIR/no_effect.rs:109:5
|
||||
|
|
||||
LL | 5..;
|
||||
| ^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:111:5
|
||||
--> $DIR/no_effect.rs:110:5
|
||||
|
|
||||
LL | ..5;
|
||||
| ^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:112:5
|
||||
--> $DIR/no_effect.rs:111:5
|
||||
|
|
||||
LL | 5..6;
|
||||
| ^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:113:5
|
||||
--> $DIR/no_effect.rs:112:5
|
||||
|
|
||||
LL | 5..=6;
|
||||
| ^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:114:5
|
||||
--> $DIR/no_effect.rs:113:5
|
||||
|
|
||||
LL | [42, 55];
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:115:5
|
||||
--> $DIR/no_effect.rs:114:5
|
||||
|
|
||||
LL | [42, 55][1];
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:116:5
|
||||
--> $DIR/no_effect.rs:115:5
|
||||
|
|
||||
LL | (42, 55).1;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:117:5
|
||||
--> $DIR/no_effect.rs:116:5
|
||||
|
|
||||
LL | [42; 55];
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:118:5
|
||||
--> $DIR/no_effect.rs:117:5
|
||||
|
|
||||
LL | [42; 55][13];
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:120:5
|
||||
--> $DIR/no_effect.rs:119:5
|
||||
|
|
||||
LL | || x += 5;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: statement with no effect
|
||||
--> $DIR/no_effect.rs:122:5
|
||||
--> $DIR/no_effect.rs:121:5
|
||||
|
|
||||
LL | FooString { s: s };
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: binding to `_` prefixed variable with no side-effect
|
||||
--> $DIR/no_effect.rs:123:5
|
||||
--> $DIR/no_effect.rs:122:5
|
||||
|
|
||||
LL | let _unused = 1;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
@ -165,19 +165,19 @@ LL | let _unused = 1;
|
|||
= note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings`
|
||||
|
||||
error: binding to `_` prefixed variable with no side-effect
|
||||
--> $DIR/no_effect.rs:124:5
|
||||
--> $DIR/no_effect.rs:123:5
|
||||
|
|
||||
LL | let _penguin = || println!("Some helpful closure");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: binding to `_` prefixed variable with no side-effect
|
||||
--> $DIR/no_effect.rs:125:5
|
||||
--> $DIR/no_effect.rs:124:5
|
||||
|
|
||||
LL | let _duck = Struct { field: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: binding to `_` prefixed variable with no side-effect
|
||||
--> $DIR/no_effect.rs:126:5
|
||||
--> $DIR/no_effect.rs:125:5
|
||||
|
|
||||
LL | let _cat = [2, 4, 6, 8][2];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -44,6 +44,12 @@ fn in_struct_field() {
|
|||
s._underscore_field += 1;
|
||||
}
|
||||
|
||||
/// Tests that we do not lint if the struct field is used in code created with derive.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UnderscoreInStruct {
|
||||
_foo: u32,
|
||||
}
|
||||
|
||||
/// Tests that we do not lint if the underscore is not a prefix
|
||||
fn non_prefix_underscore(some_foo: u32) -> u32 {
|
||||
some_foo + 1
|
||||
|
|
|
@ -31,7 +31,7 @@ LL | s._underscore_field += 1;
|
|||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
|
||||
--> $DIR/used_underscore_binding.rs:99:16
|
||||
--> $DIR/used_underscore_binding.rs:105:16
|
||||
|
|
||||
LL | uses_i(_i);
|
||||
| ^^
|
||||
|
|
Loading…
Add table
Reference in a new issue