Auto merge of #9174 - flip1995:rustup, r=Jarcho

Rustup

r? `@ghost`

changelog: none
This commit is contained in:
bors 2022-07-15 13:38:01 +00:00
commit fe6814508f
83 changed files with 288 additions and 231 deletions

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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);
}
}
}
}
}

View file

@ -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() {

View file

@ -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 => (),
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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);

View file

@ -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 {

View file

@ -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);

View file

@ -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);
},

View file

@ -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);

View file

@ -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);

View file

@ -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 {

View file

@ -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;

View file

@ -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(..)) => (),

View file

@ -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 {

View file

@ -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);

View file

@ -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 {

View file

@ -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;

View file

@ -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<'_>) {

View file

@ -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);

View file

@ -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;

View file

@ -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 {

View file

@ -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);

View file

@ -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);

View file

@ -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 {

View file

@ -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 =

View file

@ -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);

View file

@ -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;

View file

@ -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
}

View file

@ -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;

View file

@ -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 {

View file

@ -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};

View file

@ -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;

View file

@ -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))

View file

@ -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);

View file

@ -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) {

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -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(_, _, _, _))

View file

@ -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.

View file

@ -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`.

View file

@ -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())

View file

@ -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;

View file

@ -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);

View file

@ -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 &[

View file

@ -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 {

View file

@ -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;

View file

@ -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();

View file

@ -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;

View file

@ -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,
}
}

View file

@ -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) => {

View file

@ -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)),
}
}

View file

@ -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.

View file

@ -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`

View file

@ -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;

View file

@ -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"]

View file

@ -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);
}
}

View file

@ -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;

View file

@ -0,0 +1 @@

View file

@ -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() {}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,4 +1,3 @@
#![feature(untagged_unions)]
#![allow(dead_code)]
#![warn(clippy::expl_impl_clone_on_copy)]

View file

@ -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 {

View file

@ -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`

View file

@ -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`

View file

@ -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

View file

@ -4,7 +4,6 @@
#![allow(path_statements)]
#![allow(clippy::deref_addrof)]
#![allow(clippy::redundant_field_names)]
#![feature(untagged_unions)]
struct Unit;
struct Tuple(i32);

View file

@ -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];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -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

View file

@ -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);
| ^^