Auto merge of #12507 - Alexendoo:unused-qualifications, r=dswij

Enable unused_qualifications lint

Fixes a common nit

changelog: none
This commit is contained in:
bors 2024-03-22 16:15:06 +00:00
commit 44a5edaaab
67 changed files with 349 additions and 349 deletions

View file

@ -1,6 +1,12 @@
#![feature(rustc_private, let_chains)] #![feature(rustc_private, let_chains)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))] #![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)] #![warn(
trivial_casts,
trivial_numeric_casts,
rust_2018_idioms,
unused_lifetimes,
unused_qualifications
)]
#![allow( #![allow(
clippy::must_use_candidate, clippy::must_use_candidate,
clippy::missing_panics_doc, clippy::missing_panics_doc,

View file

@ -2,8 +2,13 @@
#![feature(let_chains)] #![feature(let_chains)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))] #![cfg_attr(feature = "deny-warnings", deny(warnings))]
// warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(
#![warn(rust_2018_idioms, unused_lifetimes)] trivial_casts,
trivial_numeric_casts,
rust_2018_idioms,
unused_lifetimes,
unused_qualifications
)]
// The `rustc_driver` crate seems to be required in order to use the `rust_lexer` crate. // The `rustc_driver` crate seems to be required in order to use the `rust_lexer` crate.
#[allow(unused_extern_crates)] #[allow(unused_extern_crates)]

View file

@ -992,7 +992,7 @@ fn replace_region_in_text<'a>(
} }
fn try_rename_file(old_name: &Path, new_name: &Path) -> bool { fn try_rename_file(old_name: &Path, new_name: &Path) -> bool {
match fs::OpenOptions::new().create_new(true).write(true).open(new_name) { match OpenOptions::new().create_new(true).write(true).open(new_name) {
Ok(file) => drop(file), Ok(file) => drop(file),
Err(e) if matches!(e.kind(), io::ErrorKind::AlreadyExists | io::ErrorKind::NotFound) => return false, Err(e) if matches!(e.kind(), io::ErrorKind::AlreadyExists | io::ErrorKind::NotFound) => return false,
Err(e) => panic_file(e, new_name, "create"), Err(e) => panic_file(e, new_name, "create"),
@ -1016,7 +1016,7 @@ fn panic_file(error: io::Error, name: &Path, action: &str) -> ! {
} }
fn rewrite_file(path: &Path, f: impl FnOnce(&str) -> Option<String>) { fn rewrite_file(path: &Path, f: impl FnOnce(&str) -> Option<String>) {
let mut file = fs::OpenOptions::new() let mut file = OpenOptions::new()
.write(true) .write(true)
.read(true) .read(true)
.open(path) .open(path)

View file

@ -65,7 +65,7 @@ impl AssigningClones {
impl_lint_pass!(AssigningClones => [ASSIGNING_CLONES]); impl_lint_pass!(AssigningClones => [ASSIGNING_CLONES]);
impl<'tcx> LateLintPass<'tcx> for AssigningClones { impl<'tcx> LateLintPass<'tcx> for AssigningClones {
fn check_expr(&mut self, cx: &LateContext<'tcx>, assign_expr: &'tcx hir::Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, assign_expr: &'tcx Expr<'_>) {
// Do not fire the lint in macros // Do not fire the lint in macros
let expn_data = assign_expr.span().ctxt().outer_expn_data(); let expn_data = assign_expr.span().ctxt().outer_expn_data();
match expn_data.kind { match expn_data.kind {
@ -205,12 +205,7 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC
implemented_fns.contains_key(&provided_fn.def_id) implemented_fns.contains_key(&provided_fn.def_id)
} }
fn suggest<'tcx>( fn suggest<'tcx>(cx: &LateContext<'tcx>, assign_expr: &Expr<'tcx>, lhs: &Expr<'tcx>, call: &CallCandidate<'tcx>) {
cx: &LateContext<'tcx>,
assign_expr: &hir::Expr<'tcx>,
lhs: &hir::Expr<'tcx>,
call: &CallCandidate<'tcx>,
) {
span_lint_and_then(cx, ASSIGNING_CLONES, assign_expr.span, call.message(), |diag| { span_lint_and_then(cx, ASSIGNING_CLONES, assign_expr.span, call.message(), |diag| {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
@ -263,7 +258,7 @@ impl<'tcx> CallCandidate<'tcx> {
fn suggested_replacement( fn suggested_replacement(
&self, &self,
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
lhs: &hir::Expr<'tcx>, lhs: &Expr<'tcx>,
applicability: &mut Applicability, applicability: &mut Applicability,
) -> String { ) -> String {
match self.target { match self.target {

View file

@ -392,13 +392,13 @@ fn simple_negate(b: Bool) -> Bool {
t @ Term(_) => Not(Box::new(t)), t @ Term(_) => Not(Box::new(t)),
And(mut v) => { And(mut v) => {
for el in &mut v { for el in &mut v {
*el = simple_negate(::std::mem::replace(el, True)); *el = simple_negate(std::mem::replace(el, True));
} }
Or(v) Or(v)
}, },
Or(mut v) => { Or(mut v) => {
for el in &mut v { for el in &mut v {
*el = simple_negate(::std::mem::replace(el, True)); *el = simple_negate(std::mem::replace(el, True));
} }
And(v) And(v)
}, },

View file

@ -127,7 +127,7 @@ fn is_local_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>, ref_expr: &Expr<'_>)
struct InferVisitor(bool); struct InferVisitor(bool);
impl<'tcx> Visitor<'tcx> for InferVisitor { impl<'tcx> Visitor<'tcx> for InferVisitor {
fn visit_ty(&mut self, t: &rustc_hir::Ty<'_>) { fn visit_ty(&mut self, t: &Ty<'_>) {
self.0 |= matches!(t.kind, TyKind::Infer | TyKind::OpaqueDef(..) | TyKind::TraitObject(..)); self.0 |= matches!(t.kind, TyKind::Infer | TyKind::OpaqueDef(..) | TyKind::TraitObject(..));
if !self.0 { if !self.0 {
walk_ty(self, t); walk_ty(self, t);

View file

@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
} }
} }
fn match_acceptable_type(cx: &LateContext<'_>, local: &Local<'_>, collections: &[rustc_span::Symbol]) -> bool { fn match_acceptable_type(cx: &LateContext<'_>, local: &Local<'_>, collections: &[Symbol]) -> bool {
let ty = cx.typeck_results().pat_ty(local.pat); let ty = cx.typeck_results().pat_ty(local.pat);
collections.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym)) collections.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym))
// String type is a lang item but not a diagnostic item for now so we need a separate check // String type is a lang item but not a diagnostic item for now so we need a separate check

View file

@ -56,7 +56,7 @@ fn is_alias(ty: hir::Ty<'_>) -> bool {
impl LateLintPass<'_> for DefaultConstructedUnitStructs { impl LateLintPass<'_> for DefaultConstructedUnitStructs {
fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Call(fn_expr, &[]) = expr.kind if let ExprKind::Call(fn_expr, &[]) = expr.kind
// make sure we have a call to `Default::default` // make sure we have a call to `Default::default`
&& let ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(base, _)) = fn_expr.kind && let ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(base, _)) = fn_expr.kind
// make sure this isn't a type alias: // make sure this isn't a type alias:

View file

@ -60,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {
fn make_sugg( fn make_sugg(
cx: &LateContext<'_>, cx: &LateContext<'_>,
ty_path: &rustc_hir::QPath<'_>, ty_path: &QPath<'_>,
ctxt: SyntaxContext, ctxt: SyntaxContext,
applicability: &mut Applicability, applicability: &mut Applicability,
path: &str, path: &str,

View file

@ -79,7 +79,7 @@ fn is_path_self(e: &Expr<'_>) -> bool {
fn contains_trait_object(ty: Ty<'_>) -> bool { fn contains_trait_object(ty: Ty<'_>) -> bool {
match ty.kind() { match ty.kind() {
ty::Ref(_, ty, _) => contains_trait_object(*ty), ty::Ref(_, ty, _) => contains_trait_object(*ty),
ty::Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object), Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object),
ty::Dynamic(..) => true, ty::Dynamic(..) => true,
_ => false, _ => false,
} }

View file

@ -177,7 +177,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
} }
} }
fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {} fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
} }
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> { impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {

View file

@ -3,7 +3,7 @@ use clippy_utils::higher::VecArgs;
use clippy_utils::source::snippet_opt; use clippy_utils::source::snippet_opt;
use clippy_utils::ty::type_diagnostic_name; use clippy_utils::ty::type_diagnostic_name;
use clippy_utils::usage::{local_used_after_expr, local_used_in}; use clippy_utils::usage::{local_used_after_expr, local_used_in};
use clippy_utils::{get_path_from_caller_to_method_type, higher, is_adjusted, path_to_local, path_to_local_id}; use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, path_to_local, path_to_local_id};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BindingAnnotation, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, TyKind, Unsafety}; use rustc_hir::{BindingAnnotation, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, TyKind, Unsafety};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
if body.value.span.from_expansion() { if body.value.span.from_expansion() {
if body.params.is_empty() { if body.params.is_empty() {
if let Some(VecArgs::Vec(&[])) = higher::VecArgs::hir(cx, body.value) { if let Some(VecArgs::Vec(&[])) = VecArgs::hir(cx, body.value) {
// replace `|| vec![]` with `Vec::new` // replace `|| vec![]` with `Vec::new`
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,

View file

@ -552,9 +552,9 @@ fn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -
/// Returns true iff expr is some zero literal /// Returns true iff expr is some zero literal
fn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { fn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
match constant_simple(cx, cx.typeck_results(), expr) { match constant_simple(cx, cx.typeck_results(), expr) {
Some(Constant::Int(i)) => i == 0, Some(Int(i)) => i == 0,
Some(Constant::F32(f)) => f == 0.0, Some(F32(f)) => f == 0.0,
Some(Constant::F64(f)) => f == 0.0, Some(F64(f)) => f == 0.0,
_ => false, _ => false,
} }
} }

View file

@ -2,7 +2,7 @@ use rustc_errors::Diag;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LintContext}; use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Adt, Ty}; use rustc_middle::ty::{Adt, Ty};
use rustc_span::{sym, Span}; use rustc_span::{sym, Span};
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
@ -25,7 +25,7 @@ fn result_err_ty<'tcx>(
.tcx .tcx
.instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().output()) .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().output())
&& is_type_diagnostic_item(cx, ty, sym::Result) && is_type_diagnostic_item(cx, ty, sym::Result)
&& let ty::Adt(_, args) = ty.kind() && let Adt(_, args) = ty.kind()
{ {
let err_ty = args.type_at(1); let err_ty = args.type_at(1);
Some((hir_ty, err_ty)) Some((hir_ty, err_ty))

View file

@ -56,7 +56,7 @@ fn emit_lint(
index: usize, index: usize,
// The bindings that were implied, used for suggestion purposes since removing a bound with associated types // The bindings that were implied, used for suggestion purposes since removing a bound with associated types
// means we might need to then move it to a different bound // means we might need to then move it to a different bound
implied_bindings: &[rustc_hir::TypeBinding<'_>], implied_bindings: &[TypeBinding<'_>],
bound: &ImplTraitBound<'_>, bound: &ImplTraitBound<'_>,
) { ) {
let implied_by = snippet(cx, bound.span, ".."); let implied_by = snippet(cx, bound.span, "..");

View file

@ -1,5 +1,5 @@
use clippy_config::msrvs::{self, Msrv}; use clippy_config::msrvs::{self, Msrv};
use clippy_utils::diagnostics::{self, span_lint_and_sugg}; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_context; use clippy_utils::source::snippet_with_context;
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;
use clippy_utils::ty; use clippy_utils::ty;
@ -149,7 +149,7 @@ fn print_unchecked_duration_subtraction_sugg(
let left_expr = snippet_with_context(cx, left_expr.span, ctxt, "<instant>", &mut applicability).0; let left_expr = snippet_with_context(cx, left_expr.span, ctxt, "<instant>", &mut applicability).0;
let right_expr = snippet_with_context(cx, right_expr.span, ctxt, "<duration>", &mut applicability).0; let right_expr = snippet_with_context(cx, right_expr.span, ctxt, "<duration>", &mut applicability).0;
diagnostics::span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
UNCHECKED_DURATION_SUBTRACTION, UNCHECKED_DURATION_SUBTRACTION,
expr.span, expr.span,

View file

@ -88,7 +88,7 @@ fn err_upcast_comparison(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, alwa
fn upcast_comparison_bounds_err<'tcx>( fn upcast_comparison_bounds_err<'tcx>(
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
span: Span, span: Span,
rel: comparisons::Rel, rel: Rel,
lhs_bounds: Option<(FullInt, FullInt)>, lhs_bounds: Option<(FullInt, FullInt)>,
lhs: &'tcx Expr<'_>, lhs: &'tcx Expr<'_>,
rhs: &'tcx Expr<'_>, rhs: &'tcx Expr<'_>,

View file

@ -256,7 +256,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
.items() .items()
.flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(is_empty)) .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(is_empty))
.any(|i| { .any(|i| {
i.kind == ty::AssocKind::Fn i.kind == AssocKind::Fn
&& i.fn_has_self_parameter && i.fn_has_self_parameter
&& cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1 && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1
}); });
@ -594,7 +594,7 @@ fn is_empty_array(expr: &Expr<'_>) -> bool {
fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
/// Gets an `AssocItem` and return true if it matches `is_empty(self)`. /// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool { fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
if item.kind == ty::AssocKind::Fn { if item.kind == AssocKind::Fn {
let sig = cx.tcx.fn_sig(item.def_id).skip_binder(); let sig = cx.tcx.fn_sig(item.def_id).skip_binder();
let ty = sig.skip_binder(); let ty = sig.skip_binder();
ty.inputs().len() == 1 ty.inputs().len() == 1

View file

@ -16,11 +16,14 @@
rustc::diagnostic_outside_of_impl, rustc::diagnostic_outside_of_impl,
rustc::untranslatable_diagnostic rustc::untranslatable_diagnostic
)] )]
#![warn(trivial_casts, trivial_numeric_casts)] #![warn(
// warn on lints, that are included in `rust-lang/rust`s bootstrap trivial_casts,
#![warn(rust_2018_idioms, unused_lifetimes)] trivial_numeric_casts,
// warn on rustc internal lints rust_2018_idioms,
#![warn(rustc::internal)] unused_lifetimes,
unused_qualifications,
rustc::internal
)]
// Disable this rustc lint for now, as it was also done in rustc // Disable this rustc lint for now, as it was also done in rustc
#![allow(rustc::potential_query_instability)] #![allow(rustc::potential_query_instability)]

View file

@ -158,7 +158,7 @@ enum WarningType {
} }
impl WarningType { impl WarningType {
fn display(&self, suggested_format: String, cx: &EarlyContext<'_>, span: rustc_span::Span) { fn display(&self, suggested_format: String, cx: &EarlyContext<'_>, span: Span) {
match self { match self {
Self::MistypedLiteralSuffix => span_lint_and_sugg( Self::MistypedLiteralSuffix => span_lint_and_sugg(
cx, cx,
@ -302,11 +302,7 @@ impl LiteralDigitGrouping {
} }
// Returns `false` if the check fails // Returns `false` if the check fails
fn check_for_mistyped_suffix( fn check_for_mistyped_suffix(cx: &EarlyContext<'_>, span: Span, num_lit: &mut NumericLiteral<'_>) -> bool {
cx: &EarlyContext<'_>,
span: rustc_span::Span,
num_lit: &mut NumericLiteral<'_>,
) -> bool {
if num_lit.suffix.is_some() { if num_lit.suffix.is_some() {
return true; return true;
} }

View file

@ -109,7 +109,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
} }
} }
fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {} fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
} }
impl MutatePairDelegate<'_, '_> { impl MutatePairDelegate<'_, '_> {
@ -141,7 +141,7 @@ impl BreakAfterExprVisitor {
} }
} }
impl<'tcx> intravisit::Visitor<'tcx> for BreakAfterExprVisitor { impl<'tcx> Visitor<'tcx> for BreakAfterExprVisitor {
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
if self.past_candidate { if self.past_candidate {
return; return;

View file

@ -357,7 +357,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
for (ty, expr) in iter::zip( for (ty, expr) in iter::zip(
self.cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder(), self.cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder(),
std::iter::once(receiver).chain(args.iter()), iter::once(receiver).chain(args.iter()),
) { ) {
self.prefer_mutable = false; self.prefer_mutable = false;
if let ty::Ref(_, _, mutbl) = *ty.kind() { if let ty::Ref(_, _, mutbl) = *ty.kind() {

View file

@ -159,12 +159,9 @@ fn never_loop_expr<'tcx>(
| ExprKind::DropTemps(e) => never_loop_expr(cx, e, local_labels, main_loop_id), | ExprKind::DropTemps(e) => never_loop_expr(cx, e, local_labels, main_loop_id),
ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, local_labels, main_loop_id), ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, local_labels, main_loop_id),
ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, es.iter(), local_labels, main_loop_id), ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, es.iter(), local_labels, main_loop_id),
ExprKind::MethodCall(_, receiver, es, _) => never_loop_expr_all( ExprKind::MethodCall(_, receiver, es, _) => {
cx, never_loop_expr_all(cx, once(receiver).chain(es.iter()), local_labels, main_loop_id)
std::iter::once(receiver).chain(es.iter()), },
local_labels,
main_loop_id,
),
ExprKind::Struct(_, fields, base) => { ExprKind::Struct(_, fields, base) => {
let fields = never_loop_expr_all(cx, fields.iter().map(|f| f.expr), local_labels, main_loop_id); let fields = never_loop_expr_all(cx, fields.iter().map(|f| f.expr), local_labels, main_loop_id);
if let Some(base) = base { if let Some(base) = base {

View file

@ -42,7 +42,7 @@ pub(super) fn check<'tcx>(
}, },
[], [],
_, _,
) if method.ident.name == rustc_span::sym::iter => (arg, "&"), ) if method.ident.name == sym::iter => (arg, "&"),
ExprKind::MethodCall( ExprKind::MethodCall(
method, method,
Expr { Expr {
@ -60,7 +60,7 @@ pub(super) fn check<'tcx>(
}, },
[], [],
_, _,
) if method.ident.name == rustc_span::sym::into_iter => (arg, ""), ) if method.ident.name == sym::into_iter => (arg, ""),
// Only check for arrays edition 2021 or later, as this case will trigger a compiler error otherwise. // Only check for arrays edition 2021 or later, as this case will trigger a compiler error otherwise.
ExprKind::Array([arg]) if cx.tcx.sess.edition() >= Edition::Edition2021 => (arg, ""), ExprKind::Array([arg]) if cx.tcx.sess.edition() >= Edition::Edition2021 => (arg, ""),
_ => return, _ => return,

View file

@ -139,7 +139,7 @@ fn is_ty_conversion(expr: &Expr<'_>) -> bool {
if let ExprKind::Cast(..) = expr.kind { if let ExprKind::Cast(..) = expr.kind {
true true
} else if let ExprKind::MethodCall(path, _, [], _) = expr.kind } else if let ExprKind::MethodCall(path, _, [], _) = expr.kind
&& path.ident.name == rustc_span::sym::try_into && path.ident.name == sym::try_into
{ {
// This is only called for `usize` which implements `TryInto`. Therefore, // This is only called for `usize` which implements `TryInto`. Therefore,
// we don't have to check here if `self` implements the `TryInto` trait. // we don't have to check here if `self` implements the `TryInto` trait.

View file

@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_range_full; use clippy_utils::is_range_full;
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::{Expr, ExprKind, LangItem, QPath}; use rustc_hir::{Expr, ExprKind, LangItem, QPath};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -28,7 +27,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span
} }
} }
fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, types: &[rustc_span::Symbol]) -> bool { fn match_acceptable_type(cx: &LateContext<'_>, expr: &Expr<'_>, types: &[rustc_span::Symbol]) -> bool {
let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs(); let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
types.iter().any(|&ty| is_type_diagnostic_item(cx, expr_ty, ty)) types.iter().any(|&ty| is_type_diagnostic_item(cx, expr_ty, ty))
// String type is a lang item but not a diagnostic item for now so we need a separate check // String type is a lang item but not a diagnostic item for now so we need a separate check

View file

@ -16,20 +16,18 @@ use std::borrow::Cow;
use super::{MANUAL_FILTER_MAP, MANUAL_FIND_MAP, OPTION_FILTER_MAP, RESULT_FILTER_MAP}; use super::{MANUAL_FILTER_MAP, MANUAL_FIND_MAP, OPTION_FILTER_MAP, RESULT_FILTER_MAP};
fn is_method(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol) -> bool { fn is_method(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol) -> bool {
match &expr.kind { match &expr.kind {
hir::ExprKind::Path(QPath::TypeRelative(_, mname)) => mname.ident.name == method_name, ExprKind::Path(QPath::TypeRelative(_, mname)) => mname.ident.name == method_name,
hir::ExprKind::Path(QPath::Resolved(_, segments)) => { ExprKind::Path(QPath::Resolved(_, segments)) => segments.segments.last().unwrap().ident.name == method_name,
segments.segments.last().unwrap().ident.name == method_name ExprKind::MethodCall(segment, _, _, _) => segment.ident.name == method_name,
}, ExprKind::Closure(&Closure { body, .. }) => {
hir::ExprKind::MethodCall(segment, _, _, _) => segment.ident.name == method_name,
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
let closure_expr = peel_blocks(body.value); let closure_expr = peel_blocks(body.value);
match closure_expr.kind { match closure_expr.kind {
hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, receiver, ..) => { ExprKind::MethodCall(PathSegment { ident, .. }, receiver, ..) => {
if ident.name == method_name if ident.name == method_name
&& let hir::ExprKind::Path(path) = &receiver.kind && let ExprKind::Path(path) = &receiver.kind
&& let Res::Local(ref local) = cx.qpath_res(path, receiver.hir_id) && let Res::Local(ref local) = cx.qpath_res(path, receiver.hir_id)
&& !body.params.is_empty() && !body.params.is_empty()
{ {
@ -45,10 +43,10 @@ fn is_method(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol) ->
} }
} }
fn is_option_filter_map(cx: &LateContext<'_>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool { fn is_option_filter_map(cx: &LateContext<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {
is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_some)) is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_some))
} }
fn is_ok_filter_map(cx: &LateContext<'_>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool { fn is_ok_filter_map(cx: &LateContext<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {
is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_ok)) is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_ok))
} }
@ -267,10 +265,10 @@ impl<'tcx> OffendingFilterExpr<'tcx> {
/// is `filter(|x| x.is_some()).map(|x| x.unwrap())` /// is `filter(|x| x.is_some()).map(|x| x.unwrap())`
fn is_filter_some_map_unwrap( fn is_filter_some_map_unwrap(
cx: &LateContext<'_>, cx: &LateContext<'_>,
expr: &hir::Expr<'_>, expr: &Expr<'_>,
filter_recv: &hir::Expr<'_>, filter_recv: &Expr<'_>,
filter_arg: &hir::Expr<'_>, filter_arg: &Expr<'_>,
map_arg: &hir::Expr<'_>, map_arg: &Expr<'_>,
) -> bool { ) -> bool {
let iterator = is_trait_method(cx, expr, sym::Iterator); let iterator = is_trait_method(cx, expr, sym::Iterator);
let option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(filter_recv), sym::Option); let option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(filter_recv), sym::Option);
@ -279,12 +277,7 @@ fn is_filter_some_map_unwrap(
} }
/// is `filter(|x| x.is_ok()).map(|x| x.unwrap())` /// is `filter(|x| x.is_ok()).map(|x| x.unwrap())`
fn is_filter_ok_map_unwrap( fn is_filter_ok_map_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {
cx: &LateContext<'_>,
expr: &hir::Expr<'_>,
filter_arg: &hir::Expr<'_>,
map_arg: &hir::Expr<'_>,
) -> bool {
// result has no filter, so we only check for iterators // result has no filter, so we only check for iterators
let iterator = is_trait_method(cx, expr, sym::Iterator); let iterator = is_trait_method(cx, expr, sym::Iterator);
iterator && is_ok_filter_map(cx, filter_arg, map_arg) iterator && is_ok_filter_map(cx, filter_arg, map_arg)
@ -294,12 +287,12 @@ fn is_filter_ok_map_unwrap(
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub(super) fn check( pub(super) fn check(
cx: &LateContext<'_>, cx: &LateContext<'_>,
expr: &hir::Expr<'_>, expr: &Expr<'_>,
filter_recv: &hir::Expr<'_>, filter_recv: &Expr<'_>,
filter_arg: &hir::Expr<'_>, filter_arg: &Expr<'_>,
filter_span: Span, filter_span: Span,
map_recv: &hir::Expr<'_>, map_recv: &Expr<'_>,
map_arg: &hir::Expr<'_>, map_arg: &Expr<'_>,
map_span: Span, map_span: Span,
is_find: bool, is_find: bool,
) { ) {
@ -405,9 +398,9 @@ pub(super) fn check(
fn is_find_or_filter<'a>( fn is_find_or_filter<'a>(
cx: &LateContext<'a>, cx: &LateContext<'a>,
map_recv: &hir::Expr<'_>, map_recv: &Expr<'_>,
filter_arg: &hir::Expr<'_>, filter_arg: &Expr<'_>,
map_arg: &hir::Expr<'_>, map_arg: &Expr<'_>,
) -> Option<(Ident, CheckResult<'a>)> { ) -> Option<(Ident, CheckResult<'a>)> {
if is_trait_method(cx, map_recv, sym::Iterator) if is_trait_method(cx, map_recv, sym::Iterator)
// filter(|x| ...is_some())... // filter(|x| ...is_some())...

View file

@ -55,7 +55,7 @@ fn is_method(
} }
} }
match expr.kind { match expr.kind {
hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, recv, ..) => { ExprKind::MethodCall(hir::PathSegment { ident, .. }, recv, ..) => {
// compare the identifier of the receiver to the parameter // compare the identifier of the receiver to the parameter
// we are in a filter => closure has a single parameter and a single, non-block // we are in a filter => closure has a single parameter and a single, non-block
// expression, this means that the parameter shadows all outside variables with // expression, this means that the parameter shadows all outside variables with
@ -73,7 +73,7 @@ fn is_method(
// This is used to check for complete paths via `|a| std::option::Option::is_some(a)` // This is used to check for complete paths via `|a| std::option::Option::is_some(a)`
// this then unwraps to a path with `QPath::TypeRelative` // this then unwraps to a path with `QPath::TypeRelative`
// we pass the params as they've been passed to the current call through the closure // we pass the params as they've been passed to the current call through the closure
hir::ExprKind::Call(expr, [param]) => { ExprKind::Call(expr, [param]) => {
// this will hit the `QPath::TypeRelative` case and check that the method name is correct // this will hit the `QPath::TypeRelative` case and check that the method name is correct
if is_method(cx, expr, type_symbol, method_name, params) if is_method(cx, expr, type_symbol, method_name, params)
// we then check that this is indeed passing the parameter of the closure // we then check that this is indeed passing the parameter of the closure
@ -85,7 +85,7 @@ fn is_method(
} }
false false
}, },
hir::ExprKind::Path(QPath::TypeRelative(ty, mname)) => { ExprKind::Path(QPath::TypeRelative(ty, mname)) => {
let ty = cx.typeck_results().node_type(ty.hir_id); let ty = cx.typeck_results().node_type(ty.hir_id);
if let Some(did) = cx.tcx.get_diagnostic_item(type_symbol) if let Some(did) = cx.tcx.get_diagnostic_item(type_symbol)
&& ty.ty_adt_def() == cx.tcx.type_of(did).skip_binder().ty_adt_def() && ty.ty_adt_def() == cx.tcx.type_of(did).skip_binder().ty_adt_def()
@ -94,7 +94,7 @@ fn is_method(
} }
false false
}, },
hir::ExprKind::Closure(&hir::Closure { body, .. }) => { ExprKind::Closure(&hir::Closure { body, .. }) => {
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
let closure_expr = peel_blocks(body.value); let closure_expr = peel_blocks(body.value);
let params = body.params.iter().map(|param| param.pat).collect::<Vec<_>>(); let params = body.params.iter().map(|param| param.pat).collect::<Vec<_>>();
@ -107,8 +107,8 @@ fn is_method(
fn parent_is_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { fn parent_is_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
if let Some(expr) = get_parent_expr(cx, expr) if let Some(expr) = get_parent_expr(cx, expr)
&& is_trait_method(cx, expr, sym::Iterator) && is_trait_method(cx, expr, sym::Iterator)
&& let hir::ExprKind::MethodCall(path, _, _, _) = expr.kind && let ExprKind::MethodCall(path, _, _, _) = expr.kind
&& path.ident.name == rustc_span::sym::map && path.ident.name == sym::map
{ {
return true; return true;
} }
@ -148,7 +148,7 @@ fn expression_type(
{ {
return None; return None;
} }
if let hir::ExprKind::MethodCall(_, receiver, _, _) = expr.kind if let ExprKind::MethodCall(_, receiver, _, _) = expr.kind
&& let receiver_ty = cx.typeck_results().expr_ty(receiver) && let receiver_ty = cx.typeck_results().expr_ty(receiver)
&& let Some(iter_item_ty) = get_iterator_item_ty(cx, receiver_ty) && let Some(iter_item_ty) = get_iterator_item_ty(cx, receiver_ty)
{ {

View file

@ -60,7 +60,7 @@ pub(super) fn check<'tcx>(
} }
if let Op::NeedlessMove(expr) = op { if let Op::NeedlessMove(expr) = op {
let rustc_hir::ExprKind::Closure(closure) = expr.kind else { let ExprKind::Closure(closure) = expr.kind else {
return; return;
}; };
let body @ Body { params: [p], .. } = cx.tcx.hir().body(closure.body) else { let body @ Body { params: [p], .. } = cx.tcx.hir().body(closure.body) else {

View file

@ -50,7 +50,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_
let closure_body = cx.tcx.hir().body(body); let closure_body = cx.tcx.hir().body(body);
let closure_expr = peel_blocks(closure_body.value); let closure_expr = peel_blocks(closure_body.value);
match closure_body.params[0].pat.kind { match closure_body.params[0].pat.kind {
hir::PatKind::Ref(inner, hir::Mutability::Not) => { hir::PatKind::Ref(inner, Mutability::Not) => {
if let hir::PatKind::Binding(hir::BindingAnnotation::NONE, .., name, None) = inner.kind { if let hir::PatKind::Binding(hir::BindingAnnotation::NONE, .., name, None) = inner.kind {
if ident_eq(name, closure_expr) { if ident_eq(name, closure_expr) {
lint_explicit_closure(cx, e.span, recv.span, true, msrv); lint_explicit_closure(cx, e.span, recv.span, true, msrv);

View file

@ -4240,8 +4240,8 @@ impl_lint_pass!(Methods => [
/// Extracts a method call name, args, and `Span` of the method name. /// Extracts a method call name, args, and `Span` of the method name.
pub fn method_call<'tcx>( pub fn method_call<'tcx>(
recv: &'tcx hir::Expr<'tcx>, recv: &'tcx Expr<'tcx>,
) -> Option<(&'tcx str, &'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], Span, Span)> { ) -> Option<(&'tcx str, &'tcx Expr<'tcx>, &'tcx [Expr<'tcx>], Span, Span)> {
if let ExprKind::MethodCall(path, receiver, args, call_span) = recv.kind { if let ExprKind::MethodCall(path, receiver, args, call_span) = recv.kind {
if !args.iter().any(|e| e.span.from_expansion()) && !receiver.span.from_expansion() { if !args.iter().any(|e| e.span.from_expansion()) && !receiver.span.from_expansion() {
let name = path.ident.name.as_str(); let name = path.ident.name.as_str();
@ -4252,7 +4252,7 @@ pub fn method_call<'tcx>(
} }
impl<'tcx> LateLintPass<'tcx> for Methods { impl<'tcx> LateLintPass<'tcx> for Methods {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if expr.span.from_expansion() { if expr.span.from_expansion() {
return; return;
} }
@ -4260,12 +4260,12 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
self.check_methods(cx, expr); self.check_methods(cx, expr);
match expr.kind { match expr.kind {
hir::ExprKind::Call(func, args) => { ExprKind::Call(func, args) => {
from_iter_instead_of_collect::check(cx, expr, args, func); from_iter_instead_of_collect::check(cx, expr, args, func);
unnecessary_fallible_conversions::check_function(cx, expr, func); unnecessary_fallible_conversions::check_function(cx, expr, func);
manual_c_str_literals::check(cx, expr, func, args, &self.msrv); manual_c_str_literals::check(cx, expr, func, args, &self.msrv);
}, },
hir::ExprKind::MethodCall(method_call, receiver, args, _) => { ExprKind::MethodCall(method_call, receiver, args, _) => {
let method_span = method_call.ident.span; let method_span = method_call.ident.span;
or_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args); or_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args);
expect_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args); expect_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args);
@ -4277,7 +4277,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
single_char_pattern::check(cx, expr, method_call.ident.name, receiver, args); single_char_pattern::check(cx, expr, method_call.ident.name, receiver, args);
unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, &self.msrv); unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, &self.msrv);
}, },
hir::ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => { ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {
let mut info = BinaryExprInfo { let mut info = BinaryExprInfo {
expr, expr,
chain: lhs, chain: lhs,
@ -4999,9 +4999,9 @@ fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>,
/// Used for `lint_binary_expr_with_method_call`. /// Used for `lint_binary_expr_with_method_call`.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct BinaryExprInfo<'a> { struct BinaryExprInfo<'a> {
expr: &'a hir::Expr<'a>, expr: &'a Expr<'a>,
chain: &'a hir::Expr<'a>, chain: &'a Expr<'a>,
other: &'a hir::Expr<'a>, other: &'a Expr<'a>,
eq: bool, eq: bool,
} }

View file

@ -107,7 +107,7 @@ pub(super) fn check<'tcx>(
span.push_span_label(iter_call.span, "the iterator could be used here instead"); span.push_span_label(iter_call.span, "the iterator could be used here instead");
span_lint_hir_and_then( span_lint_hir_and_then(
cx, cx,
super::NEEDLESS_COLLECT, NEEDLESS_COLLECT,
collect_expr.hir_id, collect_expr.hir_id,
span, span,
NEEDLESS_COLLECT_MSG, NEEDLESS_COLLECT_MSG,

View file

@ -39,7 +39,7 @@ pub(super) fn check<'tcx>(
&& let closure_body = cx.tcx.hir().body(body) && let closure_body = cx.tcx.hir().body(body)
&& let Some(closure_arg) = closure_body.params.first() && let Some(closure_arg) = closure_body.params.first()
{ {
if let hir::PatKind::Ref(..) = closure_arg.pat.kind { if let PatKind::Ref(..) = closure_arg.pat.kind {
Some(search_snippet.replacen('&', "", 1)) Some(search_snippet.replacen('&', "", 1))
} else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind { } else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind {
// `find()` provides a reference to the item, but `any` does not, // `find()` provides a reference to the item, but `any` does not,

View file

@ -3,7 +3,6 @@ use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{get_parent_expr, path_to_local_id, usage}; use clippy_utils::{get_parent_expr, path_to_local_id, usage};
use rustc_ast::ast; use rustc_ast::ast;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat}; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat};
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -13,9 +12,9 @@ use rustc_span::symbol::sym;
pub(super) fn derefs_to_slice<'tcx>( pub(super) fn derefs_to_slice<'tcx>(
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx Expr<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Option<&'tcx hir::Expr<'tcx>> { ) -> Option<&'tcx Expr<'tcx>> {
fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool { fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {
match ty.kind() { match ty.kind() {
ty::Slice(_) => true, ty::Slice(_) => true,
@ -27,7 +26,7 @@ pub(super) fn derefs_to_slice<'tcx>(
} }
} }
if let hir::ExprKind::MethodCall(path, self_arg, ..) = &expr.kind { if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind {
if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(self_arg)) { if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(self_arg)) {
Some(self_arg) Some(self_arg)
} else { } else {
@ -51,10 +50,10 @@ pub(super) fn derefs_to_slice<'tcx>(
pub(super) fn get_hint_if_single_char_arg( pub(super) fn get_hint_if_single_char_arg(
cx: &LateContext<'_>, cx: &LateContext<'_>,
arg: &hir::Expr<'_>, arg: &Expr<'_>,
applicability: &mut Applicability, applicability: &mut Applicability,
) -> Option<String> { ) -> Option<String> {
if let hir::ExprKind::Lit(lit) = &arg.kind if let ExprKind::Lit(lit) = &arg.kind
&& let ast::LitKind::Str(r, style) = lit.node && let ast::LitKind::Str(r, style) = lit.node
&& let string = r.as_str() && let string = r.as_str()
&& string.chars().count() == 1 && string.chars().count() == 1

View file

@ -198,7 +198,7 @@ fn check_struct<'tcx>(
} }
impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx rustc_hir::Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
// is this an `impl Debug for X` block? // is this an `impl Debug for X` block?
if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, items, .. }) = item.kind if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, items, .. }) = item.kind
&& let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res && let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res

View file

@ -60,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed {
let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args); let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args);
check_arguments( check_arguments(
cx, cx,
std::iter::once(receiver).chain(arguments.iter()).collect(), iter::once(receiver).chain(arguments.iter()).collect(),
method_type, method_type,
path.ident.as_str(), path.ident.as_str(),
"method", "method",

View file

@ -92,8 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for Mutex {
behavior and not the internal type, consider using `Mutex<()>`" behavior and not the internal type, consider using `Mutex<()>`"
); );
match *mutex_param.kind() { match *mutex_param.kind() {
ty::Uint(t) if t != ty::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), ty::Uint(t) if t != UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
ty::Int(t) if t != ty::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), ty::Int(t) if t != IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
_ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg), _ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg),
}; };
} }

View file

@ -381,7 +381,7 @@ fn replace_types<'tcx>(
fn_sig: FnSig<'tcx>, fn_sig: FnSig<'tcx>,
arg_index: usize, arg_index: usize,
projection_predicates: &[ProjectionPredicate<'tcx>], projection_predicates: &[ProjectionPredicate<'tcx>],
args: &mut [ty::GenericArg<'tcx>], args: &mut [GenericArg<'tcx>],
) -> bool { ) -> bool {
let mut replaced = BitSet::new_empty(args.len()); let mut replaced = BitSet::new_empty(args.len());
@ -399,7 +399,7 @@ fn replace_types<'tcx>(
return false; return false;
} }
args[param_ty.index as usize] = ty::GenericArg::from(new_ty); args[param_ty.index as usize] = GenericArg::from(new_ty);
// The `replaced.insert(...)` check provides some protection against infinite loops. // The `replaced.insert(...)` check provides some protection against infinite loops.
if replaced.insert(param_ty.index) { if replaced.insert(param_ty.index) {
@ -414,7 +414,7 @@ fn replace_types<'tcx>(
)); ));
if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection) if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
&& args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty) && args[term_param_ty.index as usize] != GenericArg::from(projected_ty)
{ {
deque.push_back((*term_param_ty, projected_ty)); deque.push_back((*term_param_ty, projected_ty));
} }

View file

@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect {
} }
} }
fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) { fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if let Some(def_id) = path_to_local(expr) { if let Some(def_id) = path_to_local(expr) {
// FIXME(rust/#120456) - is `swap_remove` correct? // FIXME(rust/#120456) - is `swap_remove` correct?
self.underscore_bindings.swap_remove(&def_id); self.underscore_bindings.swap_remove(&def_id);

View file

@ -285,7 +285,7 @@ impl NonCopyConst {
let def_id = body_id.hir_id.owner.to_def_id(); let def_id = body_id.hir_id.owner.to_def_id();
let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id); let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id);
let instance = ty::Instance::new(def_id, args); let instance = ty::Instance::new(def_id, args);
let cid = rustc_middle::mir::interpret::GlobalId { let cid = GlobalId {
instance, instance,
promoted: None, promoted: None,
}; };
@ -534,7 +534,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
} }
} }
fn ignored_macro(cx: &LateContext<'_>, it: &rustc_hir::Item<'_>) -> bool { fn ignored_macro(cx: &LateContext<'_>, it: &Item<'_>) -> bool {
macro_backtrace(it.span).any(|macro_call| { macro_backtrace(it.span).any(|macro_call| {
matches!( matches!(
cx.tcx.get_diagnostic_name(macro_call.def_id), cx.tcx.get_diagnostic_name(macro_call.def_id),

View file

@ -628,7 +628,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
} }
}, },
ExprKind::MethodCall(name, self_arg, expr_args, _) => { ExprKind::MethodCall(name, self_arg, expr_args, _) => {
let i = std::iter::once(self_arg) let i = iter::once(self_arg)
.chain(expr_args.iter()) .chain(expr_args.iter())
.position(|arg| arg.hir_id == child_id) .position(|arg| arg.hir_id == child_id)
.unwrap_or(0); .unwrap_or(0);

View file

@ -306,9 +306,9 @@ impl QuestionMark {
} }
} }
fn is_try_block(cx: &LateContext<'_>, bl: &rustc_hir::Block<'_>) -> bool { fn is_try_block(cx: &LateContext<'_>, bl: &Block<'_>) -> bool {
if let Some(expr) = bl.expr if let Some(expr) = bl.expr
&& let rustc_hir::ExprKind::Call(callee, _) = expr.kind && let ExprKind::Call(callee, _) = expr.kind
{ {
is_path_lang_item(cx, callee, LangItem::TryTraitFromOutput) is_path_lang_item(cx, callee, LangItem::TryTraitFromOutput)
} else { } else {
@ -337,7 +337,7 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
} }
} }
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx rustc_hir::Block<'tcx>) { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
if is_try_block(cx, block) { if is_try_block(cx, block) {
*self *self
.try_block_depth_stack .try_block_depth_stack
@ -354,7 +354,7 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
self.try_block_depth_stack.pop(); self.try_block_depth_stack.pop();
} }
fn check_block_post(&mut self, cx: &LateContext<'tcx>, block: &'tcx rustc_hir::Block<'tcx>) { fn check_block_post(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
if is_try_block(cx, block) { if is_try_block(cx, block) {
*self *self
.try_block_depth_stack .try_block_depth_stack

View file

@ -56,7 +56,7 @@ impl ReturnVisitor {
impl<'tcx> Visitor<'tcx> for ReturnVisitor { impl<'tcx> Visitor<'tcx> for ReturnVisitor {
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Ret(_) | hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind { if let ExprKind::Ret(_) | ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind {
self.found_return = true; self.found_return = true;
} else { } else {
hir_visit::walk_expr(self, ex); hir_visit::walk_expr(self, ex);
@ -68,7 +68,7 @@ impl<'tcx> Visitor<'tcx> for ReturnVisitor {
/// Returns true for `async || whatever_expression`, but false for `|| async { whatever_expression /// Returns true for `async || whatever_expression`, but false for `|| async { whatever_expression
/// }`. /// }`.
fn is_async_closure(body: &hir::Body<'_>) -> bool { fn is_async_closure(body: &hir::Body<'_>) -> bool {
if let hir::ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind if let ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind
// checks whether it is `async || whatever_expression` // checks whether it is `async || whatever_expression`
&& let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)) && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure))
= innermost_closure_generated_by_desugar.kind = innermost_closure_generated_by_desugar.kind
@ -99,7 +99,7 @@ fn find_innermost_closure<'tcx>(
)> { )> {
let mut data = None; let mut data = None;
while let hir::ExprKind::Closure(closure) = expr.kind while let ExprKind::Closure(closure) = expr.kind
&& let body = cx.tcx.hir().body(closure.body) && let body = cx.tcx.hir().body(closure.body)
&& { && {
let mut visitor = ReturnVisitor::new(); let mut visitor = ReturnVisitor::new();
@ -137,7 +137,7 @@ fn get_parent_call_exprs<'tcx>(
) -> (&'tcx hir::Expr<'tcx>, usize) { ) -> (&'tcx hir::Expr<'tcx>, usize) {
let mut depth = 1; let mut depth = 1;
while let Some(parent) = get_parent_expr(cx, expr) while let Some(parent) = get_parent_expr(cx, expr)
&& let hir::ExprKind::Call(recv, _) = parent.kind && let ExprKind::Call(recv, _) = parent.kind
&& expr.span == recv.span && expr.span == recv.span
{ {
expr = parent; expr = parent;
@ -152,13 +152,13 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
return; return;
} }
if let hir::ExprKind::Call(recv, _) = expr.kind if let ExprKind::Call(recv, _) = expr.kind
// don't lint if the receiver is a call, too. // don't lint if the receiver is a call, too.
// we do this in order to prevent linting multiple times; consider: // we do this in order to prevent linting multiple times; consider:
// `(|| || 1)()()` // `(|| || 1)()()`
// ^^ we only want to lint for this call (but we walk up the calls to consider both calls). // ^^ we only want to lint for this call (but we walk up the calls to consider both calls).
// without this check, we'd end up linting twice. // without this check, we'd end up linting twice.
&& !matches!(recv.kind, hir::ExprKind::Call(..)) && !matches!(recv.kind, ExprKind::Call(..))
// Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is // Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is
// the same as the one the call is in. // the same as the one the call is in.
// For instance, let's assume `x!()` returns a closure: // For instance, let's assume `x!()` returns a closure:
@ -185,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
Sugg::hir_with_context(cx, body, full_expr.span.ctxt(), "..", &mut applicability); Sugg::hir_with_context(cx, body, full_expr.span.ctxt(), "..", &mut applicability);
if coroutine_kind.is_async() if coroutine_kind.is_async()
&& let hir::ExprKind::Closure(closure) = body.kind && let ExprKind::Closure(closure) = body.kind
{ {
// Like `async fn`, async closures are wrapped in an additional block // Like `async fn`, async closures are wrapped in an additional block
// to move all of the closure's arguments into the future. // to move all of the closure's arguments into the future.
@ -202,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
}; };
// `async x` is a syntax error, so it becomes `async { x }` // `async x` is a syntax error, so it becomes `async { x }`
if !matches!(body_expr.kind, hir::ExprKind::Block(_, _)) { if !matches!(body_expr.kind, ExprKind::Block(_, _)) {
hint = hint.blockify(); hint = hint.blockify();
} }
@ -210,7 +210,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
} }
let is_in_fn_call_arg = if let Node::Expr(expr) = cx.tcx.parent_hir_node(expr.hir_id) { let is_in_fn_call_arg = if let Node::Expr(expr) = cx.tcx.parent_hir_node(expr.hir_id) {
matches!(expr.kind, hir::ExprKind::Call(_, _)) matches!(expr.kind, ExprKind::Call(_, _))
} else { } else {
false false
}; };
@ -238,12 +238,12 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
path: &'tcx hir::Path<'tcx>, path: &'tcx hir::Path<'tcx>,
count: usize, count: usize,
} }
impl<'a, 'tcx> hir_visit::Visitor<'tcx> for ClosureUsageCount<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for ClosureUsageCount<'a, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies; type NestedFilter = nested_filter::OnlyBodies;
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Call(closure, _) = expr.kind if let ExprKind::Call(closure, _) = expr.kind
&& let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind && let ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind
&& self.path.segments[0].ident == path.segments[0].ident && self.path.segments[0].ident == path.segments[0].ident
&& self.path.res == path.res && self.path.res == path.res
{ {
@ -263,13 +263,13 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
for w in block.stmts.windows(2) { for w in block.stmts.windows(2) {
if let hir::StmtKind::Let(local) = w[0].kind if let hir::StmtKind::Let(local) = w[0].kind
&& let Option::Some(t) = local.init && let Some(t) = local.init
&& let hir::ExprKind::Closure { .. } = t.kind && let ExprKind::Closure { .. } = t.kind
&& let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind && let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind
&& let hir::StmtKind::Semi(second) = w[1].kind && let hir::StmtKind::Semi(second) = w[1].kind
&& let hir::ExprKind::Assign(_, call, _) = second.kind && let ExprKind::Assign(_, call, _) = second.kind
&& let hir::ExprKind::Call(closure, _) = call.kind && let ExprKind::Call(closure, _) = call.kind
&& let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind && let ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind
&& ident == path.segments[0].ident && ident == path.segments[0].ident
&& count_closure_usage(cx, block, path) == 1 && count_closure_usage(cx, block, path) == 1
{ {

View file

@ -59,7 +59,7 @@ fn is_same_type<'tcx>(cx: &LateContext<'tcx>, ty_resolved_path: hir::def::Res, f
fn func_hir_id_to_func_ty<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::hir_id::HirId) -> Option<Ty<'tcx>> { fn func_hir_id_to_func_ty<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::hir_id::HirId) -> Option<Ty<'tcx>> {
if let Some((defkind, func_defid)) = cx.typeck_results().type_dependent_def(hir_id) if let Some((defkind, func_defid)) = cx.typeck_results().type_dependent_def(hir_id)
&& defkind == hir::def::DefKind::AssocFn && defkind == DefKind::AssocFn
&& let Some(init_ty) = cx.tcx.type_of(func_defid).no_bound_vars() && let Some(init_ty) = cx.tcx.type_of(func_defid).no_bound_vars()
{ {
Some(init_ty) Some(init_ty)

View file

@ -59,7 +59,7 @@ impl_lint_pass!(ThreadLocalInitializerCanBeMadeConst => [THREAD_LOCAL_INITIALIZE
#[inline] #[inline]
fn is_thread_local_initializer( fn is_thread_local_initializer(
cx: &LateContext<'_>, cx: &LateContext<'_>,
fn_kind: rustc_hir::intravisit::FnKind<'_>, fn_kind: intravisit::FnKind<'_>,
span: rustc_span::Span, span: rustc_span::Span,
) -> Option<bool> { ) -> Option<bool> {
let macro_def_id = span.source_callee()?.macro_def_id?; let macro_def_id = span.source_callee()?.macro_def_id?;
@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for ThreadLocalInitializerCanBeMadeConst {
fn check_fn( fn check_fn(
&mut self, &mut self,
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
fn_kind: rustc_hir::intravisit::FnKind<'tcx>, fn_kind: intravisit::FnKind<'tcx>,
_: &'tcx rustc_hir::FnDecl<'tcx>, _: &'tcx rustc_hir::FnDecl<'tcx>,
body: &'tcx rustc_hir::Body<'tcx>, body: &'tcx rustc_hir::Body<'tcx>,
span: rustc_span::Span, span: rustc_span::Span,

View file

@ -200,7 +200,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
let item_has_safety_comment = item_has_safety_comment(cx, item); let item_has_safety_comment = item_has_safety_comment(cx, item);
match (&item.kind, item_has_safety_comment) { match (&item.kind, item_has_safety_comment) {
// lint unsafe impl without safety comment // lint unsafe impl without safety comment
(hir::ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.unsafety == hir::Unsafety::Unsafe => { (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.unsafety == hir::Unsafety::Unsafe => {
if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id()) if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id())
&& !is_unsafe_from_proc_macro(cx, item.span) && !is_unsafe_from_proc_macro(cx, item.span)
{ {
@ -222,7 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
} }
}, },
// lint safe impl with unnecessary safety comment // lint safe impl with unnecessary safety comment
(hir::ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.unsafety == hir::Unsafety::Normal => { (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.unsafety == hir::Unsafety::Normal => {
if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {
let (span, help_span) = mk_spans(pos); let (span, help_span) = mk_spans(pos);
@ -236,9 +236,9 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
); );
} }
}, },
(hir::ItemKind::Impl(_), _) => {}, (ItemKind::Impl(_), _) => {},
// const and static items only need a safety comment if their body is an unsafe block, lint otherwise // const and static items only need a safety comment if their body is an unsafe block, lint otherwise
(&hir::ItemKind::Const(.., body) | &hir::ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => { (&ItemKind::Const(.., body) | &ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => {
if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) { if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) {
let body = cx.tcx.hir().body(body); let body = cx.tcx.hir().body(body);
if !matches!( if !matches!(
@ -338,13 +338,13 @@ fn block_parents_have_safety_comment(
accept_comment_above_statement: bool, accept_comment_above_statement: bool,
accept_comment_above_attributes: bool, accept_comment_above_attributes: bool,
cx: &LateContext<'_>, cx: &LateContext<'_>,
id: hir::HirId, id: HirId,
) -> bool { ) -> bool {
let (span, hir_id) = match cx.tcx.parent_hir_node(id) { let (span, hir_id) = match cx.tcx.parent_hir_node(id) {
Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) { Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) {
Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id), Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id),
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..), kind: ItemKind::Const(..) | ItemKind::Static(..),
span, span,
owner_id, owner_id,
.. ..
@ -365,7 +365,7 @@ fn block_parents_have_safety_comment(
}) })
| Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id), | Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id),
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..), kind: ItemKind::Const(..) | ItemKind::Static(..),
span, span,
owner_id, owner_id,
.. ..
@ -605,11 +605,11 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
Node::Expr(e) => span = e.span, Node::Expr(e) => span = e.span,
Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::Local(_) => (), Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::Local(_) => (),
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Const(..) | ItemKind::Static(..), kind: ItemKind::Const(..) | ItemKind::Static(..),
.. ..
}) => maybe_global_var = true, }) => maybe_global_var = true,
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Mod(_), kind: ItemKind::Mod(_),
span: item_span, span: item_span,
.. ..
}) => { }) => {

View file

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro; use clippy_utils::is_from_proc_macro;
use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt}; use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{self as hir, Block, Expr, ExprKind, MatchSource, Node, StmtKind}; use rustc_hir::{Block, Expr, ExprKind, MatchSource, Node, StmtKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use super::{utils, UNIT_ARG}; use super::{utils, UNIT_ARG};
@ -19,7 +19,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if is_questionmark_desugar_marked_call(expr) { if is_questionmark_desugar_marked_call(expr) {
return; return;
} }
if let hir::Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id) if let Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id)
&& is_questionmark_desugar_marked_call(parent_expr) && is_questionmark_desugar_marked_call(parent_expr)
{ {
return; return;

View file

@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
hir::QPath::LangItem(..) => return, hir::QPath::LangItem(..) => return,
}; };
match constructor_symbol { match constructor_symbol {
sym::Some | sym::Ok if path.ident.name == rustc_span::sym::map => (), sym::Some | sym::Ok if path.ident.name == sym::map => (),
sym::Err if path.ident.name == sym::map_err => (), sym::Err if path.ident.name == sym::map_err => (),
_ => return, _ => return,
} }

View file

@ -215,7 +215,7 @@ macro_rules! always_pat {
/// in `alternatives[focus_idx + 1..]`. /// in `alternatives[focus_idx + 1..]`.
fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: usize) -> bool { fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: usize) -> bool {
// Extract the kind; we'll need to make some changes in it. // Extract the kind; we'll need to make some changes in it.
let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, PatKind::Wild); let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, Wild);
// We'll focus on `alternatives[focus_idx]`, // We'll focus on `alternatives[focus_idx]`,
// so we're draining from `alternatives[focus_idx + 1..]`. // so we're draining from `alternatives[focus_idx + 1..]`.
let start = focus_idx + 1; let start = focus_idx + 1;

View file

@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
if let Some(exp) = block.expr if let Some(exp) = block.expr
&& matches!( && matches!(
exp.kind, exp.kind,
hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, hir::MatchSource::Normal) ExprKind::If(_, _, _) | ExprKind::Match(_, _, hir::MatchSource::Normal)
) )
{ {
check_expr(cx, exp); check_expr(cx, exp);
@ -130,7 +130,7 @@ fn non_consuming_ok_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {
fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) { fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
match expr.kind { match expr.kind {
hir::ExprKind::If(cond, _, _) ExprKind::If(cond, _, _)
if let ExprKind::Let(hir::Let { pat, init, .. }) = cond.kind if let ExprKind::Let(hir::Let { pat, init, .. }) = cond.kind
&& is_ok_wild_or_dotdot_pattern(cx, pat) && is_ok_wild_or_dotdot_pattern(cx, pat)
&& let Some(op) = should_lint(cx, init) => && let Some(op) = should_lint(cx, init) =>
@ -140,7 +140,7 @@ fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
// we will capture only the case where the match is Ok( ) or Err( ) // we will capture only the case where the match is Ok( ) or Err( )
// prefer to match the minimum possible, and expand later if needed // prefer to match the minimum possible, and expand later if needed
// to avoid false positives on something as used as this // to avoid false positives on something as used as this
hir::ExprKind::Match(expr, [arm1, arm2], hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => { ExprKind::Match(expr, [arm1, arm2], hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {
if non_consuming_ok_arm(cx, arm1) && non_consuming_err_arm(cx, arm2) { if non_consuming_ok_arm(cx, arm1) && non_consuming_err_arm(cx, arm2) {
emit_lint(cx, expr.span, expr.hir_id, op, &[arm1.pat.span]); emit_lint(cx, expr.span, expr.hir_id, op, &[arm1.pat.span]);
} }
@ -148,7 +148,7 @@ fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
emit_lint(cx, expr.span, expr.hir_id, op, &[arm2.pat.span]); emit_lint(cx, expr.span, expr.hir_id, op, &[arm2.pat.span]);
} }
}, },
hir::ExprKind::Match(_, _, hir::MatchSource::Normal) => {}, ExprKind::Match(_, _, hir::MatchSource::Normal) => {},
_ if let Some(op) = should_lint(cx, expr) => { _ if let Some(op) = should_lint(cx, expr) => {
emit_lint(cx, expr.span, expr.hir_id, op, &[]); emit_lint(cx, expr.span, expr.hir_id, op, &[]);
}, },
@ -201,7 +201,7 @@ fn is_unreachable_or_panic(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
} }
fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
while let hir::ExprKind::MethodCall(path, receiver, ..) = expr.kind { while let ExprKind::MethodCall(path, receiver, ..) = expr.kind {
if matches!( if matches!(
path.ident.as_str(), path.ident.as_str(),
"unwrap" | "expect" | "unwrap_or" | "unwrap_or_else" | "ok" | "is_ok" | "is_err" | "or_else" | "or" "unwrap" | "expect" | "unwrap_or" | "unwrap_or_else" | "ok" | "is_ok" | "is_err" | "or_else" | "or"
@ -215,10 +215,10 @@ fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
} }
fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
while let hir::ExprKind::Call(func, [ref arg_0, ..]) = expr.kind while let ExprKind::Call(func, [ref arg_0, ..]) = expr.kind
&& matches!( && matches!(
func.kind, func.kind,
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..)) ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
) )
{ {
expr = arg_0; expr = arg_0;
@ -227,7 +227,7 @@ fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
} }
fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
while let hir::ExprKind::Match(res, _, _) = expr.kind { while let ExprKind::Match(res, _, _) = expr.kind {
expr = res; expr = res;
} }
expr expr
@ -236,11 +236,11 @@ fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
/// If `expr` is an (e).await, return the inner expression "e" that's being /// If `expr` is an (e).await, return the inner expression "e" that's being
/// waited on. Otherwise return None. /// waited on. Otherwise return None.
fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &hir::Expr<'a> { fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &hir::Expr<'a> {
if let hir::ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind { if let ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind {
if let hir::ExprKind::Call(func, [ref arg_0, ..]) = expr.kind { if let ExprKind::Call(func, [ref arg_0, ..]) = expr.kind {
if matches!( if matches!(
func.kind, func.kind,
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoFutureIntoFuture, ..)) ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoFutureIntoFuture, ..))
) { ) {
return arg_0; return arg_0;
} }
@ -251,7 +251,7 @@ fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &hir::Expr<'a> {
/// Check whether the current expr is a function call for an IO operation /// Check whether the current expr is a function call for an IO operation
fn check_io_mode(cx: &LateContext<'_>, call: &hir::Expr<'_>) -> Option<IoOp> { fn check_io_mode(cx: &LateContext<'_>, call: &hir::Expr<'_>) -> Option<IoOp> {
let hir::ExprKind::MethodCall(path, ..) = call.kind else { let ExprKind::MethodCall(path, ..) = call.kind else {
return None; return None;
}; };

View file

@ -59,7 +59,7 @@ declare_lint_pass!(UnwrapInResult=> [UNWRAP_IN_RESULT]);
impl<'tcx> LateLintPass<'tcx> for UnwrapInResult { impl<'tcx> LateLintPass<'tcx> for UnwrapInResult {
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
if let hir::ImplItemKind::Fn(ref _signature, _) = impl_item.kind if let ImplItemKind::Fn(ref _signature, _) = impl_item.kind
// first check if it's a method or function // first check if it's a method or function
// checking if its return type is `result` or `option` // checking if its return type is `result` or `option`
&& (is_type_diagnostic_item(cx, return_ty(cx, impl_item.owner_id), sym::Result) && (is_type_diagnostic_item(cx, return_ty(cx, impl_item.owner_id), sym::Result)

View file

@ -207,7 +207,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
} }
} }
fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) { fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx>) {
if !hir_ty.span.from_expansion() if !hir_ty.span.from_expansion()
&& self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS) && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS)
&& let Some(&StackItem::Check { && let Some(&StackItem::Check {
@ -286,7 +286,7 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector {
walk_inf(self, inf); walk_inf(self, inf);
} }
fn visit_ty(&mut self, hir_ty: &hir::Ty<'_>) { fn visit_ty(&mut self, hir_ty: &Ty<'_>) {
self.types_to_skip.push(hir_ty.hir_id); self.types_to_skip.push(hir_ty.hir_id);
walk_ty(self, hir_ty); walk_ty(self, hir_ty);

View file

@ -747,7 +747,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
} }
} }
fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool { fn has_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
let attrs = cx.tcx.hir().attrs(hir_id); let attrs = cx.tcx.hir().attrs(hir_id);
get_attr(cx.sess(), attrs, "author").count() > 0 get_attr(cx.sess(), attrs, "author").count() > 0
} }
@ -764,7 +764,7 @@ fn path_to_string(path: &QPath<'_>) -> Result<String, ()> {
} }
}, },
QPath::TypeRelative(ty, segment) => match &ty.kind { QPath::TypeRelative(ty, segment) => match &ty.kind {
hir::TyKind::Path(inner_path) => { TyKind::Path(inner_path) => {
inner(s, inner_path)?; inner(s, inner_path)?;
*s += ", "; *s += ", ";
write!(s, "{:?}", segment.ident.as_str()).unwrap(); write!(s, "{:?}", segment.ident.as_str()).unwrap();

View file

@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use clippy_utils::{is_expr_path_def_path, is_lint_allowed, peel_blocks_with_stmt, SpanlessEq}; use clippy_utils::{is_expr_path_def_path, is_lint_allowed, peel_blocks_with_stmt, SpanlessEq};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::{Closure, Expr, ExprKind}; use rustc_hir::{Closure, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -72,7 +71,7 @@ declare_clippy_lint! {
declare_lint_pass!(CollapsibleCalls => [COLLAPSIBLE_SPAN_LINT_CALLS]); declare_lint_pass!(CollapsibleCalls => [COLLAPSIBLE_SPAN_LINT_CALLS]);
impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls { impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if is_lint_allowed(cx, COLLAPSIBLE_SPAN_LINT_CALLS, expr.hir_id) { if is_lint_allowed(cx, COLLAPSIBLE_SPAN_LINT_CALLS, expr.hir_id) {
return; return;
} }

View file

@ -153,7 +153,7 @@ impl MetadataCollector {
lints: BinaryHeap::<LintMetadata>::default(), lints: BinaryHeap::<LintMetadata>::default(),
applicability_info: FxHashMap::<String, ApplicabilityInfo>::default(), applicability_info: FxHashMap::<String, ApplicabilityInfo>::default(),
config: get_configuration_metadata(), config: get_configuration_metadata(),
clippy_project_root: std::env::current_dir() clippy_project_root: env::current_dir()
.expect("failed to get current dir") .expect("failed to get current dir")
.ancestors() .ancestors()
.nth(1) .nth(1)
@ -243,7 +243,7 @@ Please use that command to update the file and do not edit it by hand.
.unwrap(); .unwrap();
// Write configuration links to CHANGELOG.md // Write configuration links to CHANGELOG.md
let changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap(); let changelog = fs::read_to_string(CHANGELOG_PATH).unwrap();
let mut changelog_file = File::create(CHANGELOG_PATH).unwrap(); let mut changelog_file = File::create(CHANGELOG_PATH).unwrap();
let position = changelog let position = changelog
.find("<!-- begin autogenerated links to configuration documentation -->") .find("<!-- begin autogenerated links to configuration documentation -->")
@ -912,7 +912,7 @@ impl<'a, 'hir> LintResolver<'a, 'hir> {
} }
} }
impl<'a, 'hir> intravisit::Visitor<'hir> for LintResolver<'a, 'hir> { impl<'a, 'hir> Visitor<'hir> for LintResolver<'a, 'hir> {
type NestedFilter = nested_filter::All; type NestedFilter = nested_filter::All;
fn nested_visit_map(&mut self) -> Self::Map { fn nested_visit_map(&mut self) -> Self::Map {
@ -963,7 +963,7 @@ impl<'a, 'hir> ApplicabilityResolver<'a, 'hir> {
} }
} }
impl<'a, 'hir> intravisit::Visitor<'hir> for ApplicabilityResolver<'a, 'hir> { impl<'a, 'hir> Visitor<'hir> for ApplicabilityResolver<'a, 'hir> {
type NestedFilter = nested_filter::All; type NestedFilter = nested_filter::All;
fn nested_visit_map(&mut self) -> Self::Map { fn nested_visit_map(&mut self) -> Self::Map {
@ -1042,7 +1042,7 @@ impl<'a, 'hir> IsMultiSpanScanner<'a, 'hir> {
} }
} }
impl<'a, 'hir> intravisit::Visitor<'hir> for IsMultiSpanScanner<'a, 'hir> { impl<'a, 'hir> Visitor<'hir> for IsMultiSpanScanner<'a, 'hir> {
type NestedFilter = nested_filter::All; type NestedFilter = nested_filter::All;
fn nested_visit_map(&mut self) -> Self::Map { fn nested_visit_map(&mut self) -> Self::Map {

View file

@ -4,7 +4,6 @@ use clippy_utils::{def_path_def_ids, is_lint_allowed, match_any_def_paths, peel_
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, ExprKind, Local, Mutability, Node}; use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
@ -49,7 +48,7 @@ pub struct UnnecessaryDefPath {
} }
impl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath { impl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if is_lint_allowed(cx, UNNECESSARY_DEF_PATH, expr.hir_id) { if is_lint_allowed(cx, UNNECESSARY_DEF_PATH, expr.hir_id) {
return; return;
} }
@ -213,7 +212,7 @@ impl UnnecessaryDefPath {
} }
} }
fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Vec<String>> { fn path_to_matched_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Vec<String>> {
match peel_hir_expr_refs(expr).0.kind { match peel_hir_expr_refs(expr).0.kind {
ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) { ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) {
Res::Local(hir_id) => { Res::Local(hir_id) => {

View file

@ -97,8 +97,8 @@ pub fn eq_path_seg(l: &PathSegment, r: &PathSegment) -> bool {
pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool { pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool {
match (l, r) { match (l, r) {
(GenericArgs::AngleBracketed(l), GenericArgs::AngleBracketed(r)) => over(&l.args, &r.args, eq_angle_arg), (AngleBracketed(l), AngleBracketed(r)) => over(&l.args, &r.args, eq_angle_arg),
(GenericArgs::Parenthesized(l), GenericArgs::Parenthesized(r)) => { (Parenthesized(l), Parenthesized(r)) => {
over(&l.inputs, &r.inputs, |l, r| eq_ty(l, r)) && eq_fn_ret_ty(&l.output, &r.output) over(&l.inputs, &r.inputs, |l, r| eq_ty(l, r)) && eq_fn_ret_ty(&l.output, &r.output)
}, },
_ => false, _ => false,
@ -304,25 +304,25 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
(ExternCrate(l), ExternCrate(r)) => l == r, (ExternCrate(l), ExternCrate(r)) => l == r,
(Use(l), Use(r)) => eq_use_tree(l, r), (Use(l), Use(r)) => eq_use_tree(l, r),
( (
Static(box ast::StaticItem { Static(box StaticItem {
ty: lt, ty: lt,
mutability: lm, mutability: lm,
expr: le, expr: le,
}), }),
Static(box ast::StaticItem { Static(box StaticItem {
ty: rt, ty: rt,
mutability: rm, mutability: rm,
expr: re, expr: re,
}), }),
) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re), ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
( (
Const(box ast::ConstItem { Const(box ConstItem {
defaultness: ld, defaultness: ld,
generics: lg, generics: lg,
ty: lt, ty: lt,
expr: le, expr: le,
}), }),
Const(box ast::ConstItem { Const(box ConstItem {
defaultness: rd, defaultness: rd,
generics: rg, generics: rg,
ty: rt, ty: rt,
@ -493,13 +493,13 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
use AssocItemKind::*; use AssocItemKind::*;
match (l, r) { match (l, r) {
( (
Const(box ast::ConstItem { Const(box ConstItem {
defaultness: ld, defaultness: ld,
generics: lg, generics: lg,
ty: lt, ty: lt,
expr: le, expr: le,
}), }),
Const(box ast::ConstItem { Const(box ConstItem {
defaultness: rd, defaultness: rd,
generics: rg, generics: rg,
ty: rt, ty: rt,
@ -523,14 +523,14 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r)) eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
}, },
( (
Type(box ast::TyAlias { Type(box TyAlias {
defaultness: ld, defaultness: ld,
generics: lg, generics: lg,
bounds: lb, bounds: lb,
ty: lt, ty: lt,
.. ..
}), }),
Type(box ast::TyAlias { Type(box TyAlias {
defaultness: rd, defaultness: rd,
generics: rg, generics: rg,
bounds: rb, bounds: rb,

View file

@ -24,7 +24,7 @@ use std::iter;
/// A `LitKind`-like enum to fold constant `Expr`s into. /// A `LitKind`-like enum to fold constant `Expr`s into.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Constant<'tcx> { pub enum Constant<'tcx> {
Adt(rustc_middle::mir::Const<'tcx>), Adt(mir::Const<'tcx>),
/// A `String` (e.g., "abc"). /// A `String` (e.g., "abc").
Str(String), Str(String),
/// A binary string (e.g., `b"abc"`). /// A binary string (e.g., `b"abc"`).
@ -207,7 +207,7 @@ impl<'tcx> Constant<'tcx> {
.zip(r) .zip(r)
.zip(tys) .zip(tys)
.map(|((li, ri), cmp_type)| Self::partial_cmp(tcx, cmp_type, li, ri)) .map(|((li, ri), cmp_type)| Self::partial_cmp(tcx, cmp_type, li, ri))
.find(|r| r.map_or(true, |o| o != Ordering::Equal)) .find(|r| r.map_or(true, |o| o != Equal))
.unwrap_or_else(|| Some(l.len().cmp(&r.len()))), .unwrap_or_else(|| Some(l.len().cmp(&r.len()))),
_ => None, _ => None,
}, },
@ -217,7 +217,7 @@ impl<'tcx> Constant<'tcx> {
}; };
iter::zip(l, r) iter::zip(l, r)
.map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri)) .map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri))
.find(|r| r.map_or(true, |o| o != Ordering::Equal)) .find(|r| r.map_or(true, |o| o != Equal))
.unwrap_or_else(|| Some(l.len().cmp(&r.len()))) .unwrap_or_else(|| Some(l.len().cmp(&r.len())))
}, },
(Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => { (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => {
@ -361,7 +361,7 @@ pub enum FullInt {
impl PartialEq for FullInt { impl PartialEq for FullInt {
#[must_use] #[must_use]
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal self.cmp(other) == Equal
} }
} }
@ -579,7 +579,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
/// Lookup a possibly constant expression from an `ExprKind::Path` and apply a function on it. /// Lookup a possibly constant expression from an `ExprKind::Path` and apply a function on it.
fn fetch_path_and_apply<T, F>(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'tcx>, f: F) -> Option<T> fn fetch_path_and_apply<T, F>(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'tcx>, f: F) -> Option<T>
where where
F: FnOnce(&mut Self, rustc_middle::mir::Const<'tcx>) -> Option<T>, F: FnOnce(&mut Self, mir::Const<'tcx>) -> Option<T>,
{ {
let res = self.typeck_results.qpath_res(qpath, id); let res = self.typeck_results.qpath_res(qpath, id);
match res { match res {
@ -612,7 +612,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
.tcx .tcx
.const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), qpath.span()) .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), qpath.span())
.ok() .ok()
.map(|val| rustc_middle::mir::Const::from_value(val, ty))?; .map(|val| mir::Const::from_value(val, ty))?;
f(self, result) f(self, result)
}, },
_ => None, _ => None,

View file

@ -16,11 +16,11 @@ use rustc_span::{sym, symbol, Span};
/// `for pat in arg { body }` becomes `(pat, arg, body)`. Returns `(pat, arg, body, span)`. /// `for pat in arg { body }` becomes `(pat, arg, body)`. Returns `(pat, arg, body, span)`.
pub struct ForLoop<'tcx> { pub struct ForLoop<'tcx> {
/// `for` loop item /// `for` loop item
pub pat: &'tcx hir::Pat<'tcx>, pub pat: &'tcx Pat<'tcx>,
/// `IntoIterator` argument /// `IntoIterator` argument
pub arg: &'tcx hir::Expr<'tcx>, pub arg: &'tcx Expr<'tcx>,
/// `for` loop body /// `for` loop body
pub body: &'tcx hir::Expr<'tcx>, pub body: &'tcx Expr<'tcx>,
/// Compare this against `hir::Destination.target` /// Compare this against `hir::Destination.target`
pub loop_id: HirId, pub loop_id: HirId,
/// entire `for` loop span /// entire `for` loop span
@ -30,13 +30,13 @@ pub struct ForLoop<'tcx> {
impl<'tcx> ForLoop<'tcx> { impl<'tcx> ForLoop<'tcx> {
/// Parses a desugared `for` loop /// Parses a desugared `for` loop
pub fn hir(expr: &Expr<'tcx>) -> Option<Self> { pub fn hir(expr: &Expr<'tcx>) -> Option<Self> {
if let hir::ExprKind::DropTemps(e) = expr.kind if let ExprKind::DropTemps(e) = expr.kind
&& let hir::ExprKind::Match(iterexpr, [arm], hir::MatchSource::ForLoopDesugar) = e.kind && let ExprKind::Match(iterexpr, [arm], MatchSource::ForLoopDesugar) = e.kind
&& let hir::ExprKind::Call(_, [arg]) = iterexpr.kind && let ExprKind::Call(_, [arg]) = iterexpr.kind
&& let hir::ExprKind::Loop(block, ..) = arm.body.kind && let ExprKind::Loop(block, ..) = arm.body.kind
&& let [stmt] = block.stmts && let [stmt] = block.stmts
&& let hir::StmtKind::Expr(e) = stmt.kind && let hir::StmtKind::Expr(e) = stmt.kind
&& let hir::ExprKind::Match(_, [_, some_arm], _) = e.kind && let ExprKind::Match(_, [_, some_arm], _) = e.kind
&& let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind && let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind
{ {
return Some(Self { return Some(Self {
@ -209,28 +209,28 @@ impl<'hir> IfOrIfLet<'hir> {
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Range<'a> { pub struct Range<'a> {
/// The lower bound of the range, or `None` for ranges such as `..X`. /// The lower bound of the range, or `None` for ranges such as `..X`.
pub start: Option<&'a hir::Expr<'a>>, pub start: Option<&'a Expr<'a>>,
/// The upper bound of the range, or `None` for ranges such as `X..`. /// The upper bound of the range, or `None` for ranges such as `X..`.
pub end: Option<&'a hir::Expr<'a>>, pub end: Option<&'a Expr<'a>>,
/// Whether the interval is open or closed. /// Whether the interval is open or closed.
pub limits: ast::RangeLimits, pub limits: ast::RangeLimits,
} }
impl<'a> Range<'a> { impl<'a> Range<'a> {
/// Higher a `hir` range to something similar to `ast::ExprKind::Range`. /// Higher a `hir` range to something similar to `ast::ExprKind::Range`.
pub fn hir(expr: &'a hir::Expr<'_>) -> Option<Range<'a>> { pub fn hir(expr: &'a Expr<'_>) -> Option<Range<'a>> {
/// Finds the field named `name` in the field. Always return `Some` for /// Finds the field named `name` in the field. Always return `Some` for
/// convenience. /// convenience.
fn get_field<'c>(name: &str, fields: &'c [hir::ExprField<'_>]) -> Option<&'c hir::Expr<'c>> { fn get_field<'c>(name: &str, fields: &'c [hir::ExprField<'_>]) -> Option<&'c Expr<'c>> {
let expr = &fields.iter().find(|field| field.ident.name.as_str() == name)?.expr; let expr = &fields.iter().find(|field| field.ident.name.as_str() == name)?.expr;
Some(expr) Some(expr)
} }
match expr.kind { match expr.kind {
hir::ExprKind::Call(path, args) ExprKind::Call(path, args)
if matches!( if matches!(
path.kind, path.kind,
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, ..)) ExprKind::Path(QPath::LangItem(hir::LangItem::RangeInclusiveNew, ..))
) => ) =>
{ {
Some(Range { Some(Range {
@ -239,28 +239,28 @@ impl<'a> Range<'a> {
limits: ast::RangeLimits::Closed, limits: ast::RangeLimits::Closed,
}) })
}, },
hir::ExprKind::Struct(path, fields, None) => match &path { ExprKind::Struct(path, fields, None) => match &path {
hir::QPath::LangItem(hir::LangItem::RangeFull, ..) => Some(Range { QPath::LangItem(hir::LangItem::RangeFull, ..) => Some(Range {
start: None, start: None,
end: None, end: None,
limits: ast::RangeLimits::HalfOpen, limits: ast::RangeLimits::HalfOpen,
}), }),
hir::QPath::LangItem(hir::LangItem::RangeFrom, ..) => Some(Range { QPath::LangItem(hir::LangItem::RangeFrom, ..) => Some(Range {
start: Some(get_field("start", fields)?), start: Some(get_field("start", fields)?),
end: None, end: None,
limits: ast::RangeLimits::HalfOpen, limits: ast::RangeLimits::HalfOpen,
}), }),
hir::QPath::LangItem(hir::LangItem::Range, ..) => Some(Range { QPath::LangItem(hir::LangItem::Range, ..) => Some(Range {
start: Some(get_field("start", fields)?), start: Some(get_field("start", fields)?),
end: Some(get_field("end", fields)?), end: Some(get_field("end", fields)?),
limits: ast::RangeLimits::HalfOpen, limits: ast::RangeLimits::HalfOpen,
}), }),
hir::QPath::LangItem(hir::LangItem::RangeToInclusive, ..) => Some(Range { QPath::LangItem(hir::LangItem::RangeToInclusive, ..) => Some(Range {
start: None, start: None,
end: Some(get_field("end", fields)?), end: Some(get_field("end", fields)?),
limits: ast::RangeLimits::Closed, limits: ast::RangeLimits::Closed,
}), }),
hir::QPath::LangItem(hir::LangItem::RangeTo, ..) => Some(Range { QPath::LangItem(hir::LangItem::RangeTo, ..) => Some(Range {
start: None, start: None,
end: Some(get_field("end", fields)?), end: Some(get_field("end", fields)?),
limits: ast::RangeLimits::HalfOpen, limits: ast::RangeLimits::HalfOpen,
@ -275,17 +275,17 @@ impl<'a> Range<'a> {
/// Represents the pre-expansion arguments of a `vec!` invocation. /// Represents the pre-expansion arguments of a `vec!` invocation.
pub enum VecArgs<'a> { pub enum VecArgs<'a> {
/// `vec![elem; len]` /// `vec![elem; len]`
Repeat(&'a hir::Expr<'a>, &'a hir::Expr<'a>), Repeat(&'a Expr<'a>, &'a Expr<'a>),
/// `vec![a, b, c]` /// `vec![a, b, c]`
Vec(&'a [hir::Expr<'a>]), Vec(&'a [Expr<'a>]),
} }
impl<'a> VecArgs<'a> { impl<'a> VecArgs<'a> {
/// Returns the arguments of the `vec!` macro if this expression was expanded /// Returns the arguments of the `vec!` macro if this expression was expanded
/// from `vec!`. /// from `vec!`.
pub fn hir(cx: &LateContext<'_>, expr: &'a hir::Expr<'_>) -> Option<VecArgs<'a>> { pub fn hir(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<VecArgs<'a>> {
if let hir::ExprKind::Call(fun, args) = expr.kind if let ExprKind::Call(fun, args) = expr.kind
&& let hir::ExprKind::Path(ref qpath) = fun.kind && let ExprKind::Path(ref qpath) = fun.kind
&& is_expn_of(fun.span, "vec").is_some() && is_expn_of(fun.span, "vec").is_some()
&& let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id() && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
{ {
@ -294,8 +294,8 @@ impl<'a> VecArgs<'a> {
Some(VecArgs::Repeat(&args[0], &args[1])) Some(VecArgs::Repeat(&args[0], &args[1]))
} else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 { } else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 {
// `vec![a, b, c]` case // `vec![a, b, c]` case
if let hir::ExprKind::Call(_, [arg]) = &args[0].kind if let ExprKind::Call(_, [arg]) = &args[0].kind
&& let hir::ExprKind::Array(args) = arg.kind && let ExprKind::Array(args) = arg.kind
{ {
Some(VecArgs::Vec(args)) Some(VecArgs::Vec(args))
} else { } else {

View file

@ -16,12 +16,14 @@
rustc::diagnostic_outside_of_impl, rustc::diagnostic_outside_of_impl,
rustc::untranslatable_diagnostic rustc::untranslatable_diagnostic
)] )]
// warn on the same lints as `clippy_lints` #![warn(
#![warn(trivial_casts, trivial_numeric_casts)] trivial_casts,
// warn on lints, that are included in `rust-lang/rust`s bootstrap trivial_numeric_casts,
#![warn(rust_2018_idioms, unused_lifetimes)] rust_2018_idioms,
// warn on rustc internal lints unused_lifetimes,
#![warn(rustc::internal)] unused_qualifications,
rustc::internal
)]
// FIXME: switch to something more ergonomic here, once available. // FIXME: switch to something more ergonomic here, once available.
// (Currently there is no way to opt into sysroot crates without `extern crate`.) // (Currently there is no way to opt into sysroot crates without `extern crate`.)
@ -349,7 +351,7 @@ pub fn is_def_id_trait_method(cx: &LateContext<'_>, def_id: LocalDefId) -> bool
/// refers to an item of the trait `Default`, which is associated with the /// refers to an item of the trait `Default`, which is associated with the
/// `diag_item` of `sym::Default`. /// `diag_item` of `sym::Default`.
pub fn is_trait_item(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) -> bool { pub fn is_trait_item(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) -> bool {
if let hir::ExprKind::Path(ref qpath) = expr.kind { if let ExprKind::Path(ref qpath) = expr.kind {
cx.qpath_res(qpath, expr.hir_id) cx.qpath_res(qpath, expr.hir_id)
.opt_def_id() .opt_def_id()
.map_or(false, |def_id| is_diag_trait_item(cx, def_id, diag_item)) .map_or(false, |def_id| is_diag_trait_item(cx, def_id, diag_item))
@ -723,8 +725,8 @@ pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, def_id: LocalDefId) ->
let hir_id = cx.tcx.local_def_id_to_hir_id(def_id); let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
let parent_impl = cx.tcx.hir().get_parent_item(hir_id); let parent_impl = cx.tcx.hir().get_parent_item(hir_id);
if parent_impl != hir::CRATE_OWNER_ID if parent_impl != hir::CRATE_OWNER_ID
&& let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id) && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id)
&& let hir::ItemKind::Impl(impl_) = &item.kind && let ItemKind::Impl(impl_) = &item.kind
{ {
return impl_.of_trait.as_ref(); return impl_.of_trait.as_ref();
} }
@ -830,7 +832,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
/// Returns true if the expr is equal to `Default::default` when evaluated. /// Returns true if the expr is equal to `Default::default` when evaluated.
pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) -> bool { pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) -> bool {
if let hir::ExprKind::Path(ref repl_func_qpath) = repl_func.kind if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind
&& let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id() && let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id()
&& (is_diag_trait_item(cx, repl_def_id, sym::Default) && (is_diag_trait_item(cx, repl_def_id, sym::Default)
|| is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath)) || is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath))
@ -1295,7 +1297,7 @@ pub fn contains_name<'tcx>(name: Symbol, expr: &'tcx Expr<'_>, cx: &LateContext<
/// Returns `true` if `expr` contains a return expression /// Returns `true` if `expr` contains a return expression
pub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool { pub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool {
for_each_expr(expr, |e| { for_each_expr(expr, |e| {
if matches!(e.kind, hir::ExprKind::Ret(..)) { if matches!(e.kind, ExprKind::Ret(..)) {
ControlFlow::Break(()) ControlFlow::Break(())
} else { } else {
ControlFlow::Continue(()) ControlFlow::Continue(())
@ -1311,7 +1313,7 @@ pub fn get_parent_expr<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>) -> Option<&'t
/// This retrieves the parent for the given `HirId` if it's an expression. This is useful for /// This retrieves the parent for the given `HirId` if it's an expression. This is useful for
/// constraint lints /// constraint lints
pub fn get_parent_expr_for_hir<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::HirId) -> Option<&'tcx Expr<'tcx>> { pub fn get_parent_expr_for_hir<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
match cx.tcx.parent_hir_node(hir_id) { match cx.tcx.parent_hir_node(hir_id) {
Node::Expr(parent) => Some(parent), Node::Expr(parent) => Some(parent),
_ => None, _ => None,
@ -1635,13 +1637,13 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
} }
/// Convenience function to get the return type of a function. /// Convenience function to get the return type of a function.
pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId) -> Ty<'tcx> { pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId) -> Ty<'tcx> {
let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().output(); let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().output();
cx.tcx.instantiate_bound_regions_with_erased(ret_ty) cx.tcx.instantiate_bound_regions_with_erased(ret_ty)
} }
/// Convenience function to get the nth argument type of a function. /// Convenience function to get the nth argument type of a function.
pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId, nth: usize) -> Ty<'tcx> { pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId, nth: usize) -> Ty<'tcx> {
let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().input(nth); let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().input(nth);
cx.tcx.instantiate_bound_regions_with_erased(arg) cx.tcx.instantiate_bound_regions_with_erased(arg)
} }
@ -1652,8 +1654,8 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_
if let ExprKind::Path(ref qp) = fun.kind { if let ExprKind::Path(ref qp) = fun.kind {
let res = cx.qpath_res(qp, fun.hir_id); let res = cx.qpath_res(qp, fun.hir_id);
return match res { return match res {
def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true, Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id), Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
_ => false, _ => false,
}; };
} }
@ -1667,7 +1669,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
fn is_enum_variant(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool { fn is_enum_variant(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool {
matches!( matches!(
cx.qpath_res(qpath, id), cx.qpath_res(qpath, id),
def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _) Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _)
) )
} }
@ -1823,26 +1825,26 @@ pub fn strip_pat_refs<'hir>(mut pat: &'hir Pat<'hir>) -> &'hir Pat<'hir> {
pat pat
} }
pub fn int_bits(tcx: TyCtxt<'_>, ity: rustc_ty::IntTy) -> u64 { pub fn int_bits(tcx: TyCtxt<'_>, ity: IntTy) -> u64 {
Integer::from_int_ty(&tcx, ity).size().bits() Integer::from_int_ty(&tcx, ity).size().bits()
} }
#[expect(clippy::cast_possible_wrap)] #[expect(clippy::cast_possible_wrap)]
/// Turn a constant int byte representation into an i128 /// Turn a constant int byte representation into an i128
pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: rustc_ty::IntTy) -> i128 { pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: IntTy) -> i128 {
let amt = 128 - int_bits(tcx, ity); let amt = 128 - int_bits(tcx, ity);
((u as i128) << amt) >> amt ((u as i128) << amt) >> amt
} }
#[expect(clippy::cast_sign_loss)] #[expect(clippy::cast_sign_loss)]
/// clip unused bytes /// clip unused bytes
pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: rustc_ty::IntTy) -> u128 { pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: IntTy) -> u128 {
let amt = 128 - int_bits(tcx, ity); let amt = 128 - int_bits(tcx, ity);
((u as u128) << amt) >> amt ((u as u128) << amt) >> amt
} }
/// clip unused bytes /// clip unused bytes
pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: rustc_ty::UintTy) -> u128 { pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: UintTy) -> u128 {
let bits = Integer::from_uint_ty(&tcx, ity).size().bits(); let bits = Integer::from_uint_ty(&tcx, ity).size().bits();
let amt = 128 - bits; let amt = 128 - bits;
(u << amt) >> amt (u << amt) >> amt
@ -2007,7 +2009,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let did = match expr.kind { let did = match expr.kind {
ExprKind::Call(path, _) => { ExprKind::Call(path, _) => {
if let ExprKind::Path(ref qpath) = path.kind if let ExprKind::Path(ref qpath) = path.kind
&& let def::Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id) && let Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id)
{ {
Some(did) Some(did)
} else { } else {
@ -2218,7 +2220,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
/// ``` /// ```
pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool { pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {
if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) { if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) {
matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) matches!(item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }))
} else { } else {
false false
} }
@ -2254,7 +2256,7 @@ pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {
pub fn fn_def_id_with_node_args<'tcx>( pub fn fn_def_id_with_node_args<'tcx>(
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
expr: &Expr<'_>, expr: &Expr<'_>,
) -> Option<(DefId, rustc_ty::GenericArgsRef<'tcx>)> { ) -> Option<(DefId, GenericArgsRef<'tcx>)> {
let typeck = cx.typeck_results(); let typeck = cx.typeck_results();
match &expr.kind { match &expr.kind {
ExprKind::MethodCall(..) => Some(( ExprKind::MethodCall(..) => Some((
@ -2500,7 +2502,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym
/// Checks if the function containing the given `HirId` is a `#[test]` function /// Checks if the function containing the given `HirId` is a `#[test]` function
/// ///
/// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function /// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function
pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool {
with_test_item_names(tcx, tcx.parent_module(id), |names| { with_test_item_names(tcx, tcx.parent_module(id), |names| {
tcx.hir() tcx.hir()
.parent_iter(id) .parent_iter(id)
@ -2523,7 +2525,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
/// ///
/// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent
/// use [`is_in_cfg_test`] /// use [`is_in_cfg_test`]
pub fn is_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {
tcx.hir().attrs(id).iter().any(|attr| { tcx.hir().attrs(id).iter().any(|attr| {
if attr.has_name(sym::cfg) if attr.has_name(sym::cfg)
&& let Some(items) = attr.meta_item_list() && let Some(items) = attr.meta_item_list()
@ -2538,7 +2540,7 @@ pub fn is_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
} }
/// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied /// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied
pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {
tcx.hir() tcx.hir()
.parent_id_iter(id) .parent_id_iter(id)
.any(|parent_id| is_cfg_test(tcx, parent_id)) .any(|parent_id| is_cfg_test(tcx, parent_id))

View file

@ -429,7 +429,7 @@ pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId)
pub fn find_format_arg_expr<'hir, 'ast>( pub fn find_format_arg_expr<'hir, 'ast>(
start: &'hir Expr<'hir>, start: &'hir Expr<'hir>,
target: &'ast FormatArgument, target: &'ast FormatArgument,
) -> Result<&'hir rustc_hir::Expr<'hir>, &'ast rustc_ast::Expr> { ) -> Result<&'hir Expr<'hir>, &'ast rustc_ast::Expr> {
let SpanData { let SpanData {
lo, lo,
hi, hi,

View file

@ -111,7 +111,7 @@ pub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool {
} }
/// Convenience wrapper around `visit_local_usage`. /// Convenience wrapper around `visit_local_usage`.
pub fn used_exactly_once(mir: &Body<'_>, local: rustc_middle::mir::Local) -> Option<bool> { pub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option<bool> {
visit_local_usage( visit_local_usage(
&[local], &[local],
mir, mir,

View file

@ -41,7 +41,7 @@ pub const ONE: Sugg<'static> = Sugg::NonParen(Cow::Borrowed("1"));
pub const EMPTY: Sugg<'static> = Sugg::NonParen(Cow::Borrowed("")); pub const EMPTY: Sugg<'static> = Sugg::NonParen(Cow::Borrowed(""));
impl Display for Sugg<'_> { impl Display for Sugg<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self { match *self {
Sugg::NonParen(ref s) | Sugg::MaybeParen(ref s) => s.fmt(f), Sugg::NonParen(ref s) | Sugg::MaybeParen(ref s) => s.fmt(f),
Sugg::BinOp(op, ref lhs, ref rhs) => binop_to_string(op, lhs, rhs).fmt(f), Sugg::BinOp(op, ref lhs, ref rhs) => binop_to_string(op, lhs, rhs).fmt(f),
@ -124,48 +124,48 @@ impl<'a> Sugg<'a> {
} }
match expr.kind { match expr.kind {
hir::ExprKind::AddrOf(..) ExprKind::AddrOf(..)
| hir::ExprKind::If(..) | ExprKind::If(..)
| hir::ExprKind::Let(..) | ExprKind::Let(..)
| hir::ExprKind::Closure { .. } | ExprKind::Closure { .. }
| hir::ExprKind::Unary(..) | ExprKind::Unary(..)
| hir::ExprKind::Match(..) => Sugg::MaybeParen(get_snippet(expr.span)), | ExprKind::Match(..) => Sugg::MaybeParen(get_snippet(expr.span)),
hir::ExprKind::Continue(..) ExprKind::Continue(..)
| hir::ExprKind::Yield(..) | ExprKind::Yield(..)
| hir::ExprKind::Array(..) | ExprKind::Array(..)
| hir::ExprKind::Block(..) | ExprKind::Block(..)
| hir::ExprKind::Break(..) | ExprKind::Break(..)
| hir::ExprKind::Call(..) | ExprKind::Call(..)
| hir::ExprKind::Field(..) | ExprKind::Field(..)
| hir::ExprKind::Index(..) | ExprKind::Index(..)
| hir::ExprKind::InlineAsm(..) | ExprKind::InlineAsm(..)
| hir::ExprKind::OffsetOf(..) | ExprKind::OffsetOf(..)
| hir::ExprKind::ConstBlock(..) | ExprKind::ConstBlock(..)
| hir::ExprKind::Lit(..) | ExprKind::Lit(..)
| hir::ExprKind::Loop(..) | ExprKind::Loop(..)
| hir::ExprKind::MethodCall(..) | ExprKind::MethodCall(..)
| hir::ExprKind::Path(..) | ExprKind::Path(..)
| hir::ExprKind::Repeat(..) | ExprKind::Repeat(..)
| hir::ExprKind::Ret(..) | ExprKind::Ret(..)
| hir::ExprKind::Become(..) | ExprKind::Become(..)
| hir::ExprKind::Struct(..) | ExprKind::Struct(..)
| hir::ExprKind::Tup(..) | ExprKind::Tup(..)
| hir::ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)), | ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)),
hir::ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet), ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet),
hir::ExprKind::Assign(lhs, rhs, _) => { ExprKind::Assign(lhs, rhs, _) => {
Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span)) Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span))
}, },
hir::ExprKind::AssignOp(op, lhs, rhs) => { ExprKind::AssignOp(op, lhs, rhs) => {
Sugg::BinOp(hirbinop2assignop(op), get_snippet(lhs.span), get_snippet(rhs.span)) Sugg::BinOp(hirbinop2assignop(op), get_snippet(lhs.span), get_snippet(rhs.span))
}, },
hir::ExprKind::Binary(op, lhs, rhs) => Sugg::BinOp( ExprKind::Binary(op, lhs, rhs) => Sugg::BinOp(
AssocOp::from_ast_binop(op.node), AssocOp::from_ast_binop(op.node),
get_snippet(lhs.span), get_snippet(lhs.span),
get_snippet(rhs.span), get_snippet(rhs.span),
), ),
hir::ExprKind::Cast(lhs, ty) | ExprKind::Cast(lhs, ty) |
//FIXME(chenyukang), remove this after type ascription is removed from AST //FIXME(chenyukang), remove this after type ascription is removed from AST
hir::ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)), ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)),
} }
} }
@ -508,7 +508,7 @@ impl<T> ParenHelper<T> {
} }
impl<T: Display> Display for ParenHelper<T> { impl<T: Display> Display for ParenHelper<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
if self.paren { if self.paren {
write!(f, "({})", self.wrapped) write!(f, "({})", self.wrapped)
} else { } else {
@ -801,7 +801,7 @@ pub struct DerefClosure {
/// ///
/// note: this only works on single line immutable closures with exactly one input parameter. /// note: this only works on single line immutable closures with exactly one input parameter.
pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Option<DerefClosure> { pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Option<DerefClosure> {
if let hir::ExprKind::Closure(&Closure { if let ExprKind::Closure(&Closure {
fn_decl, def_id, body, .. fn_decl, def_id, body, ..
}) = closure.kind }) = closure.kind
{ {

View file

@ -91,7 +91,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
return true; return true;
} }
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *inner_ty.kind() { if let ty::Alias(ty::Opaque, AliasTy { def_id, .. }) = *inner_ty.kind() {
if !seen.insert(def_id) { if !seen.insert(def_id) {
return false; return false;
} }
@ -301,7 +301,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
cause: ObligationCause::dummy(), cause: ObligationCause::dummy(),
param_env, param_env,
recursion_depth: 0, recursion_depth: 0,
predicate: ty::Binder::dummy(trait_ref).to_predicate(tcx), predicate: Binder::dummy(trait_ref).to_predicate(tcx),
}; };
infcx infcx
.evaluate_obligation(&obligation) .evaluate_obligation(&obligation)
@ -327,7 +327,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
is_must_use_ty(cx, *ty) is_must_use_ty(cx, *ty)
}, },
ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {
for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() { for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() {
if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() { if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) { if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
@ -356,13 +356,13 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
// not succeed // not succeed
/// Checks if `Ty` is normalizable. This function is useful /// Checks if `Ty` is normalizable. This function is useful
/// to avoid crashes on `layout_of`. /// to avoid crashes on `layout_of`.
pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
is_normalizable_helper(cx, param_env, ty, &mut FxHashMap::default()) is_normalizable_helper(cx, param_env, ty, &mut FxHashMap::default())
} }
fn is_normalizable_helper<'tcx>( fn is_normalizable_helper<'tcx>(
cx: &LateContext<'tcx>, cx: &LateContext<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
cache: &mut FxHashMap<Ty<'tcx>, bool>, cache: &mut FxHashMap<Ty<'tcx>, bool>,
) -> bool { ) -> bool {
@ -372,7 +372,7 @@ fn is_normalizable_helper<'tcx>(
// prevent recursive loops, false-negative is better than endless loop leading to stack overflow // prevent recursive loops, false-negative is better than endless loop leading to stack overflow
cache.insert(ty, false); cache.insert(ty, false);
let infcx = cx.tcx.infer_ctxt().build(); let infcx = cx.tcx.infer_ctxt().build();
let cause = rustc_middle::traits::ObligationCause::dummy(); let cause = ObligationCause::dummy();
let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() { let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
match ty.kind() { match ty.kind() {
ty::Adt(def, args) => def.variants().iter().all(|variant| { ty::Adt(def, args) => def.variants().iter().all(|variant| {
@ -446,7 +446,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb
/// Checks if the type is equal to a lang item. /// Checks if the type is equal to a lang item.
/// ///
/// Returns `false` if the `LangItem` is not defined. /// Returns `false` if the `LangItem` is not defined.
pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool { pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: LangItem) -> bool {
match ty.kind() { match ty.kind() {
ty::Adt(adt, _) => cx.tcx.lang_items().get(lang_item) == Some(adt.did()), ty::Adt(adt, _) => cx.tcx.lang_items().get(lang_item) == Some(adt.did()),
_ => false, _ => false,
@ -726,7 +726,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
Some(ExprFnSig::Closure(decl, subs.as_closure().sig())) Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))
}, },
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))), ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => sig_from_bounds( ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) => sig_from_bounds(
cx, cx,
ty, ty,
cx.tcx.item_bounds(def_id).iter_instantiated(cx.tcx, args), cx.tcx.item_bounds(def_id).iter_instantiated(cx.tcx, args),
@ -899,7 +899,7 @@ pub fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
if let ty::Adt(adt, _) = ty.kind() if let ty::Adt(adt, _) = ty.kind()
&& let &[krate, .., name] = &*cx.get_def_path(adt.did()) && let &[krate, .., name] = &*cx.get_def_path(adt.did())
&& let sym::libc | sym::core | sym::std = krate && let sym::libc | sym::core | sym::std = krate
&& name == rustc_span::sym::c_void && name == sym::c_void
{ {
true true
} else { } else {
@ -1134,7 +1134,7 @@ pub fn make_projection<'tcx>(
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
assert_generic_args_match(tcx, assoc_item.def_id, args); assert_generic_args_match(tcx, assoc_item.def_id, args);
Some(ty::AliasTy::new(tcx, assoc_item.def_id, args)) Some(AliasTy::new(tcx, assoc_item.def_id, args))
} }
helper( helper(
tcx, tcx,
@ -1251,7 +1251,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
); );
return None; return None;
} }
let cause = rustc_middle::traits::ObligationCause::dummy(); let cause = ObligationCause::dummy();
match tcx match tcx
.infer_ctxt() .infer_ctxt()
.build() .build()
@ -1269,7 +1269,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
} }
pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
let cause = rustc_middle::traits::ObligationCause::dummy(); let cause = ObligationCause::dummy();
match tcx.infer_ctxt().build().at(&cause, param_env).query_normalize(ty) { match tcx.infer_ctxt().build().at(&cause, param_env).query_normalize(ty) {
Ok(ty) => ty.value, Ok(ty) => ty.value,
Err(_) => ty, Err(_) => ty,

View file

@ -83,15 +83,15 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
self.update(cmt); self.update(cmt);
} }
fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {} fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
} }
pub struct ParamBindingIdCollector { pub struct ParamBindingIdCollector {
pub binding_hir_ids: Vec<hir::HirId>, pub binding_hir_ids: Vec<HirId>,
} }
impl<'tcx> ParamBindingIdCollector { impl<'tcx> ParamBindingIdCollector {
fn collect_binding_hir_ids(body: &'tcx hir::Body<'tcx>) -> Vec<hir::HirId> { fn collect_binding_hir_ids(body: &'tcx hir::Body<'tcx>) -> Vec<HirId> {
let mut hir_ids: Vec<hir::HirId> = Vec::new(); let mut hir_ids: Vec<HirId> = Vec::new();
for param in body.params { for param in body.params {
let mut finder = ParamBindingIdCollector { let mut finder = ParamBindingIdCollector {
binding_hir_ids: Vec::new(), binding_hir_ids: Vec::new(),
@ -104,7 +104,7 @@ impl<'tcx> ParamBindingIdCollector {
hir_ids hir_ids
} }
} }
impl<'tcx> intravisit::Visitor<'tcx> for ParamBindingIdCollector { impl<'tcx> Visitor<'tcx> for ParamBindingIdCollector {
fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) { fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
if let hir::PatKind::Binding(_, hir_id, ..) = pat.kind { if let hir::PatKind::Binding(_, hir_id, ..) = pat.kind {
self.binding_hir_ids.push(hir_id); self.binding_hir_ids.push(hir_id);
@ -115,7 +115,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for ParamBindingIdCollector {
pub struct BindingUsageFinder<'a, 'tcx> { pub struct BindingUsageFinder<'a, 'tcx> {
cx: &'a LateContext<'tcx>, cx: &'a LateContext<'tcx>,
binding_ids: Vec<hir::HirId>, binding_ids: Vec<HirId>,
usage_found: bool, usage_found: bool,
} }
impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> { impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {
@ -129,16 +129,16 @@ impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {
finder.usage_found finder.usage_found
} }
} }
impl<'a, 'tcx> intravisit::Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> {
type NestedFilter = nested_filter::OnlyBodies; type NestedFilter = nested_filter::OnlyBodies;
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
if !self.usage_found { if !self.usage_found {
intravisit::walk_expr(self, expr); intravisit::walk_expr(self, expr);
} }
} }
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) { fn visit_path(&mut self, path: &hir::Path<'tcx>, _: HirId) {
if let Res::Local(id) = path.res { if let Res::Local(id) = path.res {
if self.binding_ids.contains(&id) { if self.binding_ids.contains(&id) {
self.usage_found = true; self.usage_found = true;

View file

@ -180,9 +180,9 @@ pub fn for_each_expr_with_closures<'tcx, B, C: Continue>(
} }
/// returns `true` if expr contains match expr desugared from try /// returns `true` if expr contains match expr desugared from try
fn contains_try(expr: &hir::Expr<'_>) -> bool { fn contains_try(expr: &Expr<'_>) -> bool {
for_each_expr(expr, |e| { for_each_expr(expr, |e| {
if matches!(e.kind, hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) { if matches!(e.kind, ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) {
ControlFlow::Break(()) ControlFlow::Break(())
} else { } else {
ControlFlow::Continue(()) ControlFlow::Continue(())
@ -191,9 +191,9 @@ fn contains_try(expr: &hir::Expr<'_>) -> bool {
.is_some() .is_some()
} }
pub fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir hir::Expr<'hir>, callback: F) -> bool pub fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir Expr<'hir>, callback: F) -> bool
where where
F: FnMut(&'hir hir::Expr<'hir>) -> bool, F: FnMut(&'hir Expr<'hir>) -> bool,
{ {
struct RetFinder<F> { struct RetFinder<F> {
in_stmt: bool, in_stmt: bool,
@ -236,37 +236,37 @@ where
} }
} }
impl<'hir, F: FnMut(&'hir hir::Expr<'hir>) -> bool> intravisit::Visitor<'hir> for RetFinder<F> { impl<'hir, F: FnMut(&'hir Expr<'hir>) -> bool> Visitor<'hir> for RetFinder<F> {
fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'_>) { fn visit_stmt(&mut self, stmt: &'hir Stmt<'_>) {
intravisit::walk_stmt(&mut *self.inside_stmt(true), stmt); intravisit::walk_stmt(&mut *self.inside_stmt(true), stmt);
} }
fn visit_expr(&mut self, expr: &'hir hir::Expr<'_>) { fn visit_expr(&mut self, expr: &'hir Expr<'_>) {
if self.failed { if self.failed {
return; return;
} }
if self.in_stmt { if self.in_stmt {
match expr.kind { match expr.kind {
hir::ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr), ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr),
_ => intravisit::walk_expr(self, expr), _ => walk_expr(self, expr),
} }
} else { } else {
match expr.kind { match expr.kind {
hir::ExprKind::If(cond, then, else_opt) => { ExprKind::If(cond, then, else_opt) => {
self.inside_stmt(true).visit_expr(cond); self.inside_stmt(true).visit_expr(cond);
self.visit_expr(then); self.visit_expr(then);
if let Some(el) = else_opt { if let Some(el) = else_opt {
self.visit_expr(el); self.visit_expr(el);
} }
}, },
hir::ExprKind::Match(cond, arms, _) => { ExprKind::Match(cond, arms, _) => {
self.inside_stmt(true).visit_expr(cond); self.inside_stmt(true).visit_expr(cond);
for arm in arms { for arm in arms {
self.visit_expr(arm.body); self.visit_expr(arm.body);
} }
}, },
hir::ExprKind::Block(..) => intravisit::walk_expr(self, expr), ExprKind::Block(..) => walk_expr(self, expr),
hir::ExprKind::Ret(Some(expr)) => self.visit_expr(expr), ExprKind::Ret(Some(expr)) => self.visit_expr(expr),
_ => self.failed |= !(self.cb)(expr), _ => self.failed |= !(self.cb)(expr),
} }
} }
@ -316,7 +316,7 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
is_const: bool, is_const: bool,
} }
impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {
type NestedFilter = rustc_hir::intravisit::nested_filter::None; type NestedFilter = intravisit::nested_filter::None;
fn visit_expr(&mut self, e: &'tcx Expr<'_>) { fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if !self.is_const { if !self.is_const {

View file

@ -5,6 +5,13 @@
// When a new lint is introduced, we can search the results for new warnings and check for false // When a new lint is introduced, we can search the results for new warnings and check for false
// positives. // positives.
#![warn(
trivial_casts,
trivial_numeric_casts,
rust_2018_idioms,
unused_lifetimes,
unused_qualifications
)]
#![allow(clippy::collapsible_else_if)] #![allow(clippy::collapsible_else_if)]
mod config; mod config;
@ -189,13 +196,13 @@ impl CrateSource {
// don't download/extract if we already have done so // don't download/extract if we already have done so
if !krate_file_path.is_file() { if !krate_file_path.is_file() {
// create a file path to download and write the crate data into // create a file path to download and write the crate data into
let mut krate_dest = std::fs::File::create(&krate_file_path).unwrap(); let mut krate_dest = fs::File::create(&krate_file_path).unwrap();
let mut krate_req = get(&url).unwrap().into_reader(); let mut krate_req = get(&url).unwrap().into_reader();
// copy the crate into the file // copy the crate into the file
std::io::copy(&mut krate_req, &mut krate_dest).unwrap(); io::copy(&mut krate_req, &mut krate_dest).unwrap();
// unzip the tarball // unzip the tarball
let ungz_tar = flate2::read::GzDecoder::new(std::fs::File::open(&krate_file_path).unwrap()); let ungz_tar = flate2::read::GzDecoder::new(fs::File::open(&krate_file_path).unwrap());
// extract the tar archive // extract the tar archive
let mut archive = tar::Archive::new(ungz_tar); let mut archive = tar::Archive::new(ungz_tar);
archive.unpack(&extract_dir).expect("Failed to extract!"); archive.unpack(&extract_dir).expect("Failed to extract!");
@ -257,7 +264,7 @@ impl CrateSource {
}, },
CrateSource::Path { name, path, options } => { CrateSource::Path { name, path, options } => {
fn is_cache_dir(entry: &DirEntry) -> bool { fn is_cache_dir(entry: &DirEntry) -> bool {
std::fs::read(entry.path().join("CACHEDIR.TAG")) fs::read(entry.path().join("CACHEDIR.TAG"))
.map(|x| x.starts_with(b"Signature: 8a477f597d28d172789f06886806bc55")) .map(|x| x.starts_with(b"Signature: 8a477f597d28d172789f06886806bc55"))
.unwrap_or(false) .unwrap_or(false)
} }
@ -268,7 +275,7 @@ impl CrateSource {
let dest_crate_root = PathBuf::from(LINTCHECK_SOURCES).join(name); let dest_crate_root = PathBuf::from(LINTCHECK_SOURCES).join(name);
if dest_crate_root.exists() { if dest_crate_root.exists() {
println!("Deleting existing directory at {dest_crate_root:?}"); println!("Deleting existing directory at {dest_crate_root:?}");
std::fs::remove_dir_all(&dest_crate_root).unwrap(); fs::remove_dir_all(&dest_crate_root).unwrap();
} }
println!("Copying {path:?} to {dest_crate_root:?}"); println!("Copying {path:?} to {dest_crate_root:?}");
@ -281,9 +288,9 @@ impl CrateSource {
let metadata = entry_path.symlink_metadata().unwrap(); let metadata = entry_path.symlink_metadata().unwrap();
if metadata.is_dir() { if metadata.is_dir() {
std::fs::create_dir(dest_path).unwrap(); fs::create_dir(dest_path).unwrap();
} else if metadata.is_file() { } else if metadata.is_file() {
std::fs::copy(entry_path, dest_path).unwrap(); fs::copy(entry_path, dest_path).unwrap();
} }
} }
@ -330,7 +337,7 @@ impl Crate {
); );
} }
let cargo_clippy_path = std::fs::canonicalize(cargo_clippy_path).unwrap(); let cargo_clippy_path = fs::canonicalize(cargo_clippy_path).unwrap();
let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir"); let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir");
@ -353,7 +360,7 @@ impl Crate {
clippy_args.push("--cap-lints=warn"); clippy_args.push("--cap-lints=warn");
} else { } else {
clippy_args.push("--cap-lints=allow"); clippy_args.push("--cap-lints=allow");
clippy_args.extend(lint_filter.iter().map(std::string::String::as_str)); clippy_args.extend(lint_filter.iter().map(String::as_str));
} }
if let Some(server) = server { if let Some(server) = server {
@ -454,7 +461,7 @@ fn build_clippy() {
/// Read a `lintcheck_crates.toml` file /// Read a `lintcheck_crates.toml` file
fn read_crates(toml_path: &Path) -> (Vec<CrateSource>, RecursiveOptions) { fn read_crates(toml_path: &Path) -> (Vec<CrateSource>, RecursiveOptions) {
let toml_content: String = let toml_content: String =
std::fs::read_to_string(toml_path).unwrap_or_else(|_| panic!("Failed to read {}", toml_path.display())); fs::read_to_string(toml_path).unwrap_or_else(|_| panic!("Failed to read {}", toml_path.display()));
let crate_list: SourceList = let crate_list: SourceList =
toml::from_str(&toml_content).unwrap_or_else(|e| panic!("Failed to parse {}: \n{e}", toml_path.display())); toml::from_str(&toml_content).unwrap_or_else(|e| panic!("Failed to parse {}: \n{e}", toml_path.display()));
// parse the hashmap of the toml file into a list of crates // parse the hashmap of the toml file into a list of crates
@ -549,7 +556,7 @@ fn main() {
} }
// assert that we launch lintcheck from the repo root (via cargo lintcheck) // assert that we launch lintcheck from the repo root (via cargo lintcheck)
if std::fs::metadata("lintcheck/Cargo.toml").is_err() { if fs::metadata("lintcheck/Cargo.toml").is_err() {
eprintln!("lintcheck needs to be run from clippy's repo root!\nUse `cargo lintcheck` alternatively."); eprintln!("lintcheck needs to be run from clippy's repo root!\nUse `cargo lintcheck` alternatively.");
std::process::exit(3); std::process::exit(3);
} }
@ -570,7 +577,7 @@ fn main() {
cargo_clippy_path.display() cargo_clippy_path.display()
); );
let clippy_ver = std::process::Command::new(&cargo_clippy_path) let clippy_ver = Command::new(&cargo_clippy_path)
.arg("--version") .arg("--version")
.output() .output()
.map(|o| String::from_utf8_lossy(&o.stdout).into_owned()) .map(|o| String::from_utf8_lossy(&o.stdout).into_owned())
@ -699,7 +706,7 @@ fn main() {
/// read the previous stats from the lintcheck-log file /// read the previous stats from the lintcheck-log file
fn read_stats_from_file(file_path: &Path) -> HashMap<String, usize> { fn read_stats_from_file(file_path: &Path) -> HashMap<String, usize> {
let file_content: String = match std::fs::read_to_string(file_path).ok() { let file_content: String = match fs::read_to_string(file_path).ok() {
Some(content) => content, Some(content) => content,
None => { None => {
return HashMap::new(); return HashMap::new();
@ -779,17 +786,17 @@ fn print_stats(old_stats: HashMap<String, usize>, new_stats: HashMap<&String, us
/// ///
/// This function panics if creating one of the dirs fails. /// This function panics if creating one of the dirs fails.
fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) { fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) {
std::fs::create_dir("target/lintcheck/").unwrap_or_else(|err| { fs::create_dir("target/lintcheck/").unwrap_or_else(|err| {
assert_eq!( assert_eq!(
err.kind(), err.kind(),
ErrorKind::AlreadyExists, ErrorKind::AlreadyExists,
"cannot create lintcheck target dir" "cannot create lintcheck target dir"
); );
}); });
std::fs::create_dir(krate_download_dir).unwrap_or_else(|err| { fs::create_dir(krate_download_dir).unwrap_or_else(|err| {
assert_eq!(err.kind(), ErrorKind::AlreadyExists, "cannot create crate download dir"); assert_eq!(err.kind(), ErrorKind::AlreadyExists, "cannot create crate download dir");
}); });
std::fs::create_dir(extract_dir).unwrap_or_else(|err| { fs::create_dir(extract_dir).unwrap_or_else(|err| {
assert_eq!( assert_eq!(
err.kind(), err.kind(),
ErrorKind::AlreadyExists, ErrorKind::AlreadyExists,
@ -816,7 +823,7 @@ fn lintcheck_test() {
"--crates-toml", "--crates-toml",
"lintcheck/test_sources.toml", "lintcheck/test_sources.toml",
]; ];
let status = std::process::Command::new(env::var("CARGO").unwrap_or("cargo".into())) let status = Command::new(env::var("CARGO").unwrap_or("cargo".into()))
.args(args) .args(args)
.current_dir("..") // repo root .current_dir("..") // repo root
.status(); .status();