diff --git a/clippy.toml b/clippy.toml index 4a1805f75235..8c405ac6a4e8 100644 --- a/clippy.toml +++ b/clippy.toml @@ -2,6 +2,6 @@ avoid-breaking-exported-api = false # use the various `span_lint_*` methods instead, which also add a link to the docs disallowed-methods = [ - "rustc_lint::context::LintContext::struct_span_lint", - "rustc_middle::ty::context::TyCtxt::struct_span_lint_hir" + "rustc_lint::context::LintContext::span_lint", + "rustc_middle::ty::context::TyCtxt::node_span_lint" ] diff --git a/clippy_lints/src/async_yields_async.rs b/clippy_lints/src/async_yields_async.rs index bb08ac7508bc..eeaa3de3725f 100644 --- a/clippy_lints/src/async_yields_async.rs +++ b/clippy_lints/src/async_yields_async.rs @@ -45,50 +45,72 @@ declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]); impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - // For functions, with explicitly defined types, don't warn. - // XXXkhuey maybe we should? - if let ExprKind::Closure(Closure { - kind: - ClosureKind::Coroutine(CoroutineKind::Desugared( - CoroutineDesugaring::Async, - CoroutineSource::Block | CoroutineSource::Closure, - )), + let ExprKind::Closure(Closure { + kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, kind)), body: body_id, .. }) = expr.kind - { - if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() { - let typeck_results = cx.tcx.typeck_body(*body_id); - let body = cx.tcx.hir().body(*body_id); - let expr_ty = typeck_results.expr_ty(body.value); + else { + return; + }; - if implements_trait(cx, expr_ty, future_trait_def_id, &[]) { - let return_expr_span = match &body.value.kind { - // XXXkhuey there has to be a better way. - ExprKind::Block(block, _) => block.expr.map(|e| e.span), - ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span), - _ => None, - }; - if let Some(return_expr_span) = return_expr_span { - span_lint_hir_and_then( - cx, - ASYNC_YIELDS_ASYNC, - body.value.hir_id, + let body_expr = match kind { + CoroutineSource::Fn => { + // For functions, with explicitly defined types, don't warn. + // XXXkhuey maybe we should? + return; + }, + CoroutineSource::Block => cx.tcx.hir().body(*body_id).value, + CoroutineSource::Closure => { + // Like `async fn`, async closures are wrapped in an additional block + // to move all of the closure's arguments into the future. + + let async_closure_body = cx.tcx.hir().body(*body_id).value; + let ExprKind::Block(block, _) = async_closure_body.kind else { + return; + }; + let Some(block_expr) = block.expr else { + return; + }; + let ExprKind::DropTemps(body_expr) = block_expr.kind else { + return; + }; + body_expr + }, + }; + + let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() else { + return; + }; + + let typeck_results = cx.tcx.typeck_body(*body_id); + let expr_ty = typeck_results.expr_ty(body_expr); + + if implements_trait(cx, expr_ty, future_trait_def_id, &[]) { + let return_expr_span = match &body_expr.kind { + // XXXkhuey there has to be a better way. + ExprKind::Block(block, _) => block.expr.map(|e| e.span), + ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span), + _ => None, + }; + if let Some(return_expr_span) = return_expr_span { + span_lint_hir_and_then( + cx, + ASYNC_YIELDS_ASYNC, + body_expr.hir_id, + return_expr_span, + "an async construct yields a type which is itself awaitable", + |db| { + db.span_label(body_expr.span, "outer async construct"); + db.span_label(return_expr_span, "awaitable value not awaited"); + db.span_suggestion( return_expr_span, - "an async construct yields a type which is itself awaitable", - |db| { - db.span_label(body.value.span, "outer async construct"); - db.span_label(return_expr_span, "awaitable value not awaited"); - db.span_suggestion( - return_expr_span, - "consider awaiting this value", - format!("{}.await", snippet(cx, return_expr_span, "..")), - Applicability::MaybeIncorrect, - ); - }, + "consider awaiting this value", + format!("{}.await", snippet(cx, return_expr_span, "..")), + Applicability::MaybeIncorrect, ); - } - } + }, + ); } } } diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs index 3761ba81f521..bb86b6f30759 100644 --- a/clippy_lints/src/casts/unnecessary_cast.rs +++ b/clippy_lints/src/casts/unnecessary_cast.rs @@ -107,7 +107,7 @@ pub(super) fn check<'tcx>( && let Some(src) = snippet_opt(cx, cast_expr.span) && cast_to.is_floating_point() && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node) - && let from_nbits = 128 - n.leading_zeros() + && let from_nbits = 128 - n.get().leading_zeros() && let to_nbits = fp_ty_mantissa_nbits(cast_to) && from_nbits != 0 && to_nbits != 0 diff --git a/clippy_lints/src/default_union_representation.rs b/clippy_lints/src/default_union_representation.rs index db01ff2cd220..bfd89bfd2c72 100644 --- a/clippy_lints/src/default_union_representation.rs +++ b/clippy_lints/src/default_union_representation.rs @@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation { /// (ZST fields having an arbitrary offset is completely inconsequential, and /// if there is only one field left after ignoring ZST fields then the offset /// of that field does not matter either.) -fn is_union_with_two_non_zst_fields(cx: &LateContext<'_>, item: &Item<'_>) -> bool { +fn is_union_with_two_non_zst_fields<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { if let ItemKind::Union(..) = &item.kind && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() { diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index aaef163ad554..8ff54dfcfa0d 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -830,6 +830,7 @@ impl TyCoercionStability { | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) + | TyKind::InferDelegation(..) | TyKind::Err(_) => Self::Reborrow, }; } diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index 081cbcb770fb..6144ec7b3cac 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -386,7 +386,8 @@ fn check_unsafe_derive_deserialize<'tcx>( && cx .tcx .inherent_impls(def.did()) - .iter() + .into_iter() + .flatten() .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local())) .any(|imp| has_unsafe(cx, imp)) { @@ -451,12 +452,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id) && !has_non_exhaustive_attr(cx.tcx, *adt) && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id) - && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(),&[]) + && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[]) // If all of our fields implement `Eq`, we can implement `Eq` too && adt .all_fields() .map(|f| f.ty(cx.tcx, args)) - .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(), &[])) + .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])) { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/doc/needless_doctest_main.rs b/clippy_lints/src/doc/needless_doctest_main.rs index a744b69ecb47..8dde4f227ed1 100644 --- a/clippy_lints/src/doc/needless_doctest_main.rs +++ b/clippy_lints/src/doc/needless_doctest_main.rs @@ -6,7 +6,7 @@ use clippy_utils::diagnostics::span_lint; use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind}; use rustc_data_structures::sync::Lrc; use rustc_errors::emitter::HumanEmitter; -use rustc_errors::DiagCtxt; +use rustc_errors::{DiagCtxt, DiagnosticBuilder}; use rustc_lint::LateContext; use rustc_parse::maybe_new_parser_from_source_str; use rustc_parse::parser::ForceCollect; @@ -53,7 +53,7 @@ pub fn check( let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) { Ok(p) => p, Err(errs) => { - drop(errs); + errs.into_iter().for_each(DiagnosticBuilder::cancel); return (false, test_attr_spans); }, }; diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs index 3c4352942526..4e728d61b853 100644 --- a/clippy_lints/src/equatable_if_let.rs +++ b/clippy_lints/src/equatable_if_let.rs @@ -51,7 +51,8 @@ fn unary_pattern(pat: &Pat<'_>) -> bool { | PatKind::Binding(..) | PatKind::Wild | PatKind::Never - | PatKind::Or(_) => false, + | PatKind::Or(_) + | PatKind::Err(_) => false, PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)), PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a), PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x), diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 788fe8287278..87f6f5e7959e 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -210,7 +210,7 @@ enum ImplicitHasherType<'tcx> { impl<'tcx> ImplicitHasherType<'tcx> { /// Checks that `ty` is a target type without a `BuildHasher`. - fn new(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'_>) -> Option { + fn new(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Option { if let TyKind::Path(QPath::Resolved(None, path)) = hir_ty.kind { let params: Vec<_> = path .segments diff --git a/clippy_lints/src/implicit_saturating_add.rs b/clippy_lints/src/implicit_saturating_add.rs index cc74844f2942..b8d7e8f3b07c 100644 --- a/clippy_lints/src/implicit_saturating_add.rs +++ b/clippy_lints/src/implicit_saturating_add.rs @@ -3,6 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_expr; use clippy_utils::source::snippet_with_context; use rustc_ast::ast::{LitIntType, LitKind}; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -69,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { && clippy_utils::SpanlessEq::new(cx).eq_expr(l, target) && BinOpKind::Add == op1.node && let ExprKind::Lit(lit) = value.kind - && let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node + && let LitKind::Int(Pu128(1), LitIntType::Unsuffixed) = lit.node && block.expr.is_none() { let mut app = Applicability::MachineApplicable; diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs index 81df1a889c78..127c73ed637b 100644 --- a/clippy_lints/src/implicit_saturating_sub.rs +++ b/clippy_lints/src/implicit_saturating_sub.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::{higher, is_integer_literal, peel_blocks_with_stmt, SpanlessEq}; use rustc_ast::ast::LitKind; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; @@ -86,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub { match cond_num_val.kind { ExprKind::Lit(cond_lit) => { // Check if the constant is zero - if let LitKind::Int(0, _) = cond_lit.node { + if let LitKind::Int(Pu128(0), _) = cond_lit.node { if cx.typeck_results().expr_ty(cond_left).is_signed() { } else { print_lint_and_sugg(cx, var_name, expr); diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs index e4781752e757..1127f00abde0 100644 --- a/clippy_lints/src/inherent_impl.rs +++ b/clippy_lints/src/inherent_impl.rs @@ -53,9 +53,12 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { // List of spans to lint. (lint_span, first_span) let mut lint_spans = Vec::new(); + let Ok(impls) = cx.tcx.crate_inherent_impls(()) else { + return; + }; let inherent_impls = cx .tcx - .with_stable_hashing_context(|hcx| cx.tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true)); + .with_stable_hashing_context(|hcx| impls.inherent_impls.to_sorted(&hcx, true)); for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| { impls.len() > 1 diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs index 903d3a2ab896..82a37bb4f278 100644 --- a/clippy_lints/src/iter_without_into_iter.rs +++ b/clippy_lints/src/iter_without_into_iter.rs @@ -139,7 +139,7 @@ fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl Iter fn adt_has_inherent_method(cx: &LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> bool { if let Some(ty_did) = ty.ty_adt_def().map(ty::AdtDef::did) { - cx.tcx.inherent_impls(ty_did).iter().any(|&did| { + cx.tcx.inherent_impls(ty_did).into_iter().flatten().any(|&did| { cx.tcx .associated_items(did) .filter_by_name_unhygienic(method_name) diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index c09d3d1862b0..c1ab020117ca 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -441,7 +441,8 @@ fn check_for_is_empty( let is_empty = cx .tcx .inherent_impls(impl_ty) - .iter() + .into_iter() + .flatten() .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty)) .find(|item| item.kind == AssocKind::Fn); @@ -605,7 +606,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { /// Checks the inherent impl's items for an `is_empty(self)` method. fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool { let is_empty = sym!(is_empty); - cx.tcx.inherent_impls(id).iter().any(|imp| { + cx.tcx.inherent_impls(id).into_iter().flatten().any(|imp| { cx.tcx .associated_items(*imp) .filter_by_name_unhygienic(is_empty) diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs index c7980060807c..814ccaa36f5a 100644 --- a/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/clippy_lints/src/loops/explicit_iter_loop.rs @@ -118,7 +118,7 @@ fn is_ref_iterable<'tcx>( .liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder()) && let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output && let param_env = cx.tcx.param_env(fn_id) - && implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, fn_id, &[]) + && implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, Some(fn_id), &[]) && let Some(into_iter_ty) = make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty]) && let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty) diff --git a/clippy_lints/src/loops/manual_memcpy.rs b/clippy_lints/src/loops/manual_memcpy.rs index fda6c9749d43..58f713d81871 100644 --- a/clippy_lints/src/loops/manual_memcpy.rs +++ b/clippy_lints/src/loops/manual_memcpy.rs @@ -461,7 +461,7 @@ fn is_array_length_equal_to_range(cx: &LateContext<'_>, start: &Expr<'_>, end: & if let ExprKind::Lit(lit) = expr.kind && let ast::LitKind::Int(value, _) = lit.node { - Some(value) + Some(value.get()) } else { None } diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs index 4acf46f73c90..08b8a9e2ff07 100644 --- a/clippy_lints/src/loops/needless_range_loop.rs +++ b/clippy_lints/src/loops/needless_range_loop.rs @@ -209,8 +209,8 @@ fn is_end_eq_array_len<'tcx>( && let Some(arr_len) = arr_len_const.try_eval_target_usize(cx.tcx, cx.param_env) { return match limits { - ast::RangeLimits::Closed => end_int + 1 >= arr_len.into(), - ast::RangeLimits::HalfOpen => end_int >= arr_len.into(), + ast::RangeLimits::Closed => end_int.get() + 1 >= arr_len.into(), + ast::RangeLimits::HalfOpen => end_int.get() >= arr_len.into(), }; } diff --git a/clippy_lints/src/manual_bits.rs b/clippy_lints/src/manual_bits.rs index 96c652283daa..aa02e4e7a434 100644 --- a/clippy_lints/src/manual_bits.rs +++ b/clippy_lints/src/manual_bits.rs @@ -3,6 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_expr; use clippy_utils::source::snippet_with_context; use rustc_ast::ast::LitKind; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath}; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -62,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits { && let Some((real_ty, resolved_ty, other_expr)) = get_one_size_of_ty(cx, left_expr, right_expr) && matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_)) && let ExprKind::Lit(lit) = &other_expr.kind - && let LitKind::Int(8, _) = lit.node + && let LitKind::Int(Pu128(8), _) = lit.node { let mut app = Applicability::MachineApplicable; let ty_snip = snippet_with_context(cx, real_ty.span, ctxt, "..", &mut app).0; diff --git a/clippy_lints/src/manual_range_patterns.rs b/clippy_lints/src/manual_range_patterns.rs index d585290f7773..ec60de92c4ba 100644 --- a/clippy_lints/src/manual_range_patterns.rs +++ b/clippy_lints/src/manual_range_patterns.rs @@ -45,7 +45,7 @@ fn expr_as_i128(expr: &Expr<'_>) -> Option { && let LitKind::Int(num, _) = lit.node { // Intentionally not handling numbers greater than i128::MAX (for u128 literals) for now. - num.try_into().ok() + num.get().try_into().ok() } else { None } diff --git a/clippy_lints/src/manual_strip.rs b/clippy_lints/src/manual_strip.rs index 7b04fd28b896..bcd024360024 100644 --- a/clippy_lints/src/manual_strip.rs +++ b/clippy_lints/src/manual_strip.rs @@ -161,7 +161,7 @@ fn eq_pattern_length<'tcx>(cx: &LateContext<'tcx>, pattern: &Expr<'_>, expr: &'t .. }) = expr.kind { - constant_length(cx, pattern).map_or(false, |length| length == *n) + constant_length(cx, pattern).map_or(false, |length| *n == length) } else { len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg)) } diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs index c823d07e2bd3..d645e6c6c05c 100644 --- a/clippy_lints/src/matches/match_same_arms.rs +++ b/clippy_lints/src/matches/match_same_arms.rs @@ -11,7 +11,7 @@ use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, P use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::Symbol; +use rustc_span::{ErrorGuaranteed, Symbol}; use super::MATCH_SAME_ARMS; @@ -167,6 +167,8 @@ enum NormalizedPat<'a> { /// contains everything afterwards. Note that either side, or both sides, may contain zero /// patterns. Slice(&'a [Self], Option<&'a [Self]>), + /// A placeholder for a pattern that wasn't well formed in some way. + Err(ErrorGuaranteed), } #[derive(Clone, Copy)] @@ -291,7 +293,7 @@ impl<'a> NormalizedPat<'a> { LitKind::ByteStr(ref bytes, _) | LitKind::CStr(ref bytes, _) => Self::LitBytes(bytes), LitKind::Byte(val) => Self::LitInt(val.into()), LitKind::Char(val) => Self::LitInt(val.into()), - LitKind::Int(val, _) => Self::LitInt(val), + LitKind::Int(val, _) => Self::LitInt(val.get()), LitKind::Bool(val) => Self::LitBool(val), LitKind::Float(..) | LitKind::Err => Self::Wild, }, @@ -303,7 +305,7 @@ impl<'a> NormalizedPat<'a> { None => 0, Some(e) => match &e.kind { ExprKind::Lit(lit) => match lit.node { - LitKind::Int(val, _) => val, + LitKind::Int(val, _) => val.get(), LitKind::Char(val) => val.into(), LitKind::Byte(val) => val.into(), _ => return Self::Wild, @@ -315,7 +317,7 @@ impl<'a> NormalizedPat<'a> { None => (u128::MAX, RangeEnd::Included), Some(e) => match &e.kind { ExprKind::Lit(lit) => match lit.node { - LitKind::Int(val, _) => (val, bounds), + LitKind::Int(val, _) => (val.get(), bounds), LitKind::Char(val) => (val.into(), bounds), LitKind::Byte(val) => (val.into(), bounds), _ => return Self::Wild, @@ -329,6 +331,7 @@ impl<'a> NormalizedPat<'a> { arena.alloc_from_iter(front.iter().map(|pat| Self::from_pat(cx, arena, pat))), wild_pat.map(|_| &*arena.alloc_from_iter(back.iter().map(|pat| Self::from_pat(cx, arena, pat)))), ), + PatKind::Err(guar) => Self::Err(guar), } } diff --git a/clippy_lints/src/methods/get_first.rs b/clippy_lints/src/methods/get_first.rs index e1f1e4893558..55fcf3728940 100644 --- a/clippy_lints/src/methods/get_first.rs +++ b/clippy_lints/src/methods/get_first.rs @@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; use rustc_ast::LitKind; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; @@ -20,7 +21,7 @@ pub(super) fn check<'tcx>( && let Some(impl_id) = cx.tcx.impl_of_method(method_id) && let identity = cx.tcx.type_of(impl_id).instantiate_identity() && let hir::ExprKind::Lit(Spanned { - node: LitKind::Int(0, _), + node: LitKind::Int(Pu128(0), _), .. }) = arg.kind { diff --git a/clippy_lints/src/methods/iter_out_of_bounds.rs b/clippy_lints/src/methods/iter_out_of_bounds.rs index 29e69b111de6..f198849c5c0c 100644 --- a/clippy_lints/src/methods/iter_out_of_bounds.rs +++ b/clippy_lints/src/methods/iter_out_of_bounds.rs @@ -13,7 +13,7 @@ fn expr_as_u128(cx: &LateContext<'_>, e: &Expr<'_>) -> Option { if let ExprKind::Lit(lit) = expr_or_init(cx, e).kind && let LitKind::Int(n, _) = lit.node { - Some(n) + Some(n.get()) } else { None } diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index e38c66f6741d..0602eeaa7041 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -73,7 +73,8 @@ pub(super) fn check<'tcx>( let has_suggested_method = receiver_ty.ty_adt_def().is_some_and(|adt_def| { cx.tcx .inherent_impls(adt_def.did()) - .iter() + .into_iter() + .flatten() .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg)) .any(|assoc| { assoc.fn_has_self_parameter diff --git a/clippy_lints/src/methods/seek_from_current.rs b/clippy_lints/src/methods/seek_from_current.rs index 63d41677feed..e45c7962f13f 100644 --- a/clippy_lints/src/methods/seek_from_current.rs +++ b/clippy_lints/src/methods/seek_from_current.rs @@ -1,4 +1,5 @@ use rustc_ast::ast::{LitIntType, LitKind}; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; @@ -41,7 +42,7 @@ fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) // check if argument of `SeekFrom::Current` is `0` if args.len() == 1 && let ExprKind::Lit(lit) = args[0].kind - && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node + && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node { return true; } diff --git a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs index 9f38460357ba..cc4cb47e35c6 100644 --- a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs +++ b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs @@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::implements_trait; use clippy_utils::{is_expr_used_or_unified, match_def_path, paths}; use rustc_ast::ast::{LitIntType, LitKind}; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; @@ -31,7 +32,7 @@ pub(super) fn check<'tcx>( && match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START) && args1.len() == 1 && let ExprKind::Lit(lit) = args1[0].kind - && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node + && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node { let method_call_span = expr.span.with_lo(name_span.lo()); span_lint_and_then( diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs index ebbdde48b450..f3577ef6082b 100644 --- a/clippy_lints/src/methods/unnecessary_fold.rs +++ b/clippy_lints/src/methods/unnecessary_fold.rs @@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; use clippy_utils::{is_trait_method, path_to_local_id, peel_blocks, strip_pat_refs}; use rustc_ast::ast; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::PatKind; @@ -150,7 +151,7 @@ pub(super) fn check( }, ); }, - ast::LitKind::Int(0, _) => check_fold_with_op( + ast::LitKind::Int(Pu128(0), _) => check_fold_with_op( cx, expr, acc, @@ -162,7 +163,7 @@ pub(super) fn check( method_name: "sum", }, ), - ast::LitKind::Int(1, _) => { + ast::LitKind::Int(Pu128(1), _) => { check_fold_with_op( cx, expr, diff --git a/clippy_lints/src/methods/vec_resize_to_zero.rs b/clippy_lints/src/methods/vec_resize_to_zero.rs index 9e87fb45aa65..3e271a606115 100644 --- a/clippy_lints/src/methods/vec_resize_to_zero.rs +++ b/clippy_lints/src/methods/vec_resize_to_zero.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::is_type_diagnostic_item; use rustc_ast::LitKind; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; @@ -20,7 +21,7 @@ pub(super) fn check<'tcx>( && let Some(impl_id) = cx.tcx.impl_of_method(method_id) && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Vec) && let ExprKind::Lit(Spanned { - node: LitKind::Int(0, _), + node: LitKind::Int(Pu128(0), _), .. }) = count_arg.kind && let ExprKind::Lit(Spanned { diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index bbc4d0a0f9a5..0e4d39c99902 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -7,6 +7,7 @@ use clippy_utils::source::snippet; use clippy_utils::visitors::for_each_expr; use clippy_utils::{eq_expr_value, hash_expr, higher}; use rustc_ast::{LitKind, RangeLimits}; +use rustc_data_structures::packed::Pu128; use rustc_data_structures::unhash::UnhashMap; use rustc_errors::{Applicability, Diagnostic}; use rustc_hir::{BinOp, Block, Body, Expr, ExprKind, UnOp}; @@ -102,8 +103,8 @@ fn len_comparison<'hir>( ) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> { macro_rules! int_lit_pat { ($id:ident) => { - ExprKind::Lit(Spanned { - node: LitKind::Int($id, _), + ExprKind::Lit(&Spanned { + node: LitKind::Int(Pu128($id), _), .. }) }; @@ -112,13 +113,13 @@ fn len_comparison<'hir>( // normalize comparison, `v.len() > 4` becomes `4 < v.len()` // this simplifies the logic a bit let (op, left, right) = normalize_comparison(bin_op.node, left, right)?; - match (op, &left.kind, &right.kind) { - (Rel::Lt, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanLength, *left as usize, right)), - (Rel::Lt, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanInt, *right as usize, left)), - (Rel::Le, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanOrEqualLength, *left as usize, right)), - (Rel::Le, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanOrEqualInt, *right as usize, left)), - (Rel::Eq, int_lit_pat!(left), _) => Some((LengthComparison::LengthEqualInt, *left as usize, right)), - (Rel::Eq, _, int_lit_pat!(right)) => Some((LengthComparison::LengthEqualInt, *right as usize, left)), + match (op, left.kind, right.kind) { + (Rel::Lt, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanLength, left as usize, right)), + (Rel::Lt, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanInt, right as usize, left)), + (Rel::Le, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanOrEqualLength, left as usize, right)), + (Rel::Le, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanOrEqualInt, right as usize, left)), + (Rel::Eq, int_lit_pat!(left), _) => Some((LengthComparison::LengthEqualInt, left as usize, right)), + (Rel::Eq, _, int_lit_pat!(right)) => Some((LengthComparison::LengthEqualInt, right as usize, left)), _ => None, } } @@ -206,14 +207,14 @@ impl<'hir> IndexEntry<'hir> { /// for `..=5` this returns `Some(5)` fn upper_index_expr(expr: &Expr<'_>) -> Option { if let ExprKind::Lit(lit) = &expr.kind - && let LitKind::Int(index, _) = lit.node + && let LitKind::Int(Pu128(index), _) = lit.node { Some(index as usize) } else if let Some(higher::Range { end: Some(end), limits, .. }) = higher::Range::hir(expr) && let ExprKind::Lit(lit) = &end.kind - && let LitKind::Int(index @ 1.., _) = lit.node + && let LitKind::Int(Pu128(index @ 1..), _) = lit.node { match limits { RangeLimits::HalfOpen => Some(index as usize - 1), diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs index c081dec9b6b7..929efb6c574d 100644 --- a/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -151,7 +151,7 @@ impl ArithmeticSideEffects { if let hir::ExprKind::Lit(lit) = actual.kind && let ast::LitKind::Int(n, _) = lit.node { - return Some(n); + return Some(n.get()); } if let Some(Constant::Int(n)) = constant(cx, cx.typeck_results(), expr) { return Some(n); diff --git a/clippy_lints/src/operators/verbose_bit_mask.rs b/clippy_lints/src/operators/verbose_bit_mask.rs index fbf65e92b322..a6aba33e431a 100644 --- a/clippy_lints/src/operators/verbose_bit_mask.rs +++ b/clippy_lints/src/operators/verbose_bit_mask.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::sugg::Sugg; use rustc_ast::ast::LitKind; +use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; @@ -19,9 +20,9 @@ pub(super) fn check<'tcx>( && let ExprKind::Binary(op1, left1, right1) = &left.kind && BinOpKind::BitAnd == op1.node && let ExprKind::Lit(lit) = &right1.kind - && let LitKind::Int(n, _) = lit.node + && let LitKind::Int(Pu128(n), _) = lit.node && let ExprKind::Lit(lit1) = &right.kind - && let LitKind::Int(0, _) = lit1.node + && let LitKind::Int(Pu128(0), _) = lit1.node && n.leading_zeros() == n.count_zeros() && n > u128::from(threshold) { diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs index c62c351e7167..3416a93e3c4a 100644 --- a/clippy_lints/src/redundant_clone.rs +++ b/clippy_lints/src/redundant_clone.rs @@ -257,9 +257,9 @@ fn is_call_with_ref_arg<'tcx>( .. } = kind && args.len() == 1 - && let mir::Operand::Move(mir::Place { local, .. }) = &args[0] + && let mir::Operand::Move(mir::Place { local, .. }) = &args[0].node && let ty::FnDef(def_id, _) = *func.ty(mir, cx.tcx).kind() - && let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].ty(mir, cx.tcx)) + && let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].node.ty(mir, cx.tcx)) && !is_copy(cx, inner_ty) { Some((def_id, *local, inner_ty, destination.as_local()?)) diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs index cde08dfcc748..334e6770ae40 100644 --- a/clippy_lints/src/redundant_closure_call.rs +++ b/clippy_lints/src/redundant_closure_call.rs @@ -5,7 +5,9 @@ use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor}; -use rustc_hir::{intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Node}; +use rustc_hir::{ + intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node, +}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; @@ -166,10 +168,22 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { if coroutine_kind.is_async() && let hir::ExprKind::Closure(closure) = body.kind { - let async_closure_body = cx.tcx.hir().body(closure.body); + // Like `async fn`, async closures are wrapped in an additional block + // to move all of the closure's arguments into the future. + + let async_closure_body = cx.tcx.hir().body(closure.body).value; + let ExprKind::Block(block, _) = async_closure_body.kind else { + return; + }; + let Some(block_expr) = block.expr else { + return; + }; + let ExprKind::DropTemps(body_expr) = block_expr.kind else { + return; + }; // `async x` is a syntax error, so it becomes `async { x }` - if !matches!(async_closure_body.value.kind, hir::ExprKind::Block(_, _)) { + if !matches!(body_expr.kind, hir::ExprKind::Block(_, _)) { hint = hint.blockify(); } diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 81efec65343d..7882bfdd09fa 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -314,9 +314,9 @@ impl_lint_pass!(Types => [BOX_COLLECTION, VEC_BOX, OPTION_OPTION, LINKEDLIST, BO impl<'tcx> LateLintPass<'tcx> for Types { fn check_fn( &mut self, - cx: &LateContext<'_>, + cx: &LateContext<'tcx>, fn_kind: FnKind<'_>, - decl: &FnDecl<'_>, + decl: &FnDecl<'tcx>, _: &Body<'_>, _: Span, def_id: LocalDefId, @@ -346,7 +346,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { ); } - fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id); match item.kind { @@ -363,7 +363,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { } } - fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'tcx>) { match item.kind { ImplItemKind::Const(ty, _) => { let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx @@ -391,7 +391,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { } } - fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) { + fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &hir::FieldDef<'tcx>) { let is_exported = cx.effective_visibilities.is_exported(field.def_id); self.check_ty( @@ -404,7 +404,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { ); } - fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'_>) { + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'tcx>) { let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id); let context = CheckTyContext { @@ -421,7 +421,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { } } - fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) { + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) { if let Some(ty) = local.ty { self.check_ty( cx, @@ -444,7 +444,7 @@ impl Types { } } - fn check_fn_decl(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>, context: CheckTyContext) { + fn check_fn_decl<'tcx>(&mut self, cx: &LateContext<'tcx>, decl: &FnDecl<'tcx>, context: CheckTyContext) { // Ignore functions in trait implementations as they are usually forced by the trait definition. // // FIXME: ideally we would like to warn *if the complicated type can be simplified*, but it's hard @@ -466,7 +466,7 @@ impl Types { /// lint found. /// /// The parameter `is_local` distinguishes the context of the type. - fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, mut context: CheckTyContext) { + fn check_ty<'tcx>(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, mut context: CheckTyContext) { if hir_ty.span.from_expansion() { return; } diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs index 5a986254fad5..a0d609501a0c 100644 --- a/clippy_lints/src/types/redundant_allocation.rs +++ b/clippy_lints/src/types/redundant_allocation.rs @@ -11,7 +11,7 @@ use rustc_span::symbol::sym; use super::{utils, REDUNDANT_ALLOCATION}; -pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath: &QPath<'tcx>, def_id: DefId) -> bool { let mut applicability = Applicability::MaybeIncorrect; let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() { "Box" diff --git a/clippy_lints/src/types/vec_box.rs b/clippy_lints/src/types/vec_box.rs index 9d5066199bde..a285f771f1b1 100644 --- a/clippy_lints/src/types/vec_box.rs +++ b/clippy_lints/src/types/vec_box.rs @@ -13,10 +13,10 @@ use rustc_span::symbol::sym; use super::VEC_BOX; -pub(super) fn check( - cx: &LateContext<'_>, +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'_>, - qpath: &QPath<'_>, + qpath: &QPath<'tcx>, def_id: DefId, box_size_threshold: u64, ) -> bool { diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs index 2c2830020872..209035804e43 100644 --- a/clippy_lints/src/unconditional_recursion.rs +++ b/clippy_lints/src/unconditional_recursion.rs @@ -77,7 +77,7 @@ fn get_ty_def_id(ty: Ty<'_>) -> Option { } } -fn get_hir_ty_def_id(tcx: TyCtxt<'_>, hir_ty: rustc_hir::Ty<'_>) -> Option { +fn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Option { let TyKind::Path(qpath) = hir_ty.kind else { return None }; match qpath { QPath::Resolved(_, path) => path.res.opt_def_id(), @@ -237,7 +237,7 @@ fn check_to_string(cx: &LateContext<'_>, method_span: Span, method_def_id: Local } } -fn is_default_method_on_current_ty(tcx: TyCtxt<'_>, qpath: QPath<'_>, implemented_ty_id: DefId) -> bool { +fn is_default_method_on_current_ty<'tcx>(tcx: TyCtxt<'tcx>, qpath: QPath<'tcx>, implemented_ty_id: DefId) -> bool { match qpath { QPath::Resolved(_, path) => match path.segments { [first, .., last] => last.ident.name == kw::Default && first.res.opt_def_id() == Some(implemented_ty_id), diff --git a/clippy_lints/src/uninhabited_references.rs b/clippy_lints/src/uninhabited_references.rs index 903593ecfd7d..6732a43a19ec 100644 --- a/clippy_lints/src/uninhabited_references.rs +++ b/clippy_lints/src/uninhabited_references.rs @@ -57,11 +57,11 @@ impl LateLintPass<'_> for UninhabitedReferences { } } - fn check_fn( + fn check_fn<'tcx>( &mut self, - cx: &LateContext<'_>, + cx: &LateContext<'tcx>, kind: FnKind<'_>, - fndecl: &'_ FnDecl<'_>, + fndecl: &'_ FnDecl<'tcx>, _: &'_ Body<'_>, span: Span, _: LocalDefId, diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs index 77adcdd0e6bf..7246214f9bf8 100644 --- a/clippy_lints/src/unnested_or_patterns.rs +++ b/clippy_lints/src/unnested_or_patterns.rs @@ -226,7 +226,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec>, focus_idx: us // Therefore they are not some form of constructor `C`, // with which a pattern `C(p_0)` may be formed, // which we would want to join with other `C(p_j)`s. - Ident(.., None) | Lit(_) | Wild | Never | Path(..) | Range(..) | Rest | MacCall(_) + Ident(.., None) | Lit(_) | Wild | Err(_) | Never | Path(..) | Range(..) | Rest | MacCall(_) // Skip immutable refs, as grouping them saves few characters, // and almost always requires adding parens (increasing noisiness). // In the case of only two patterns, replacement adds net characters. diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index fa033838ef35..a1b08d105b9d 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -207,7 +207,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { } } - fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) { + fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) { if !hir_ty.span.from_expansion() && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS) && let Some(&StackItem::Check { diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 8d38b87e1d79..b26ebe5cee32 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -710,6 +710,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { self.slice(start, |pat| self.pat(pat)); self.slice(end, |pat| self.pat(pat)); }, + PatKind::Err(_) => kind!("Err"), } } diff --git a/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs b/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs index 5059712d69c1..df37619227c8 100644 --- a/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs +++ b/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs @@ -41,7 +41,6 @@ impl CompilerLintFunctions { pub fn new() -> Self { let mut map = FxHashMap::default(); map.insert("span_lint", "utils::span_lint"); - map.insert("struct_span_lint", "utils::span_lint"); map.insert("lint", "utils::span_lint"); map.insert("span_lint_note", "utils::span_lint_and_note"); map.insert("span_lint_help", "utils::span_lint_and_help"); diff --git a/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/clippy_lints/src/utils/internal_lints/invalid_paths.rs index 4fb615e1d579..c62ae8d718db 100644 --- a/clippy_lints/src/utils/internal_lints/invalid_paths.rs +++ b/clippy_lints/src/utils/internal_lints/invalid_paths.rs @@ -71,7 +71,9 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool { SimplifiedType::Str, ] .iter() - .flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter().copied()); + .flat_map(|&ty| cx.tcx.incoherent_impls(ty).into_iter()) + .flatten() + .copied(); for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) { let lang_item_path = cx.get_def_path(item_def_id); if path_syms.starts_with(&lang_item_path) { diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs index b36c4ef91dc6..81d4a26e9da4 100644 --- a/clippy_lints/src/zero_sized_map_values.rs +++ b/clippy_lints/src/zero_sized_map_values.rs @@ -44,7 +44,7 @@ declare_clippy_lint! { declare_lint_pass!(ZeroSizedMapValues => [ZERO_SIZED_MAP_VALUES]); impl LateLintPass<'_> for ZeroSizedMapValues { - fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) { + fn check_ty<'tcx>(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) { if !hir_ty.span.from_expansion() && !in_trait_impl(cx, hir_ty.hir_id) && let ty = ty_from_hir_ty(cx, hir_ty) @@ -82,7 +82,7 @@ fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool { false } -fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> { +fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { cx.maybe_typeck_results() .and_then(|results| { if results.hir_owner == hir_ty.hir_id.owner { diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 727f93c83274..61b38391d9e0 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -275,7 +275,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option>) -> Constan LitKind::Byte(b) => Constant::Int(u128::from(b)), LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(Lrc::clone(s)), LitKind::Char(c) => Constant::Char(c), - LitKind::Int(n, _) => Constant::Int(n), + LitKind::Int(n, _) => Constant::Int(n.get()), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { ast::FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()), ast::FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()), diff --git a/clippy_utils/src/diagnostics.rs b/clippy_utils/src/diagnostics.rs index 77fa075b806e..5199959c0f2b 100644 --- a/clippy_utils/src/diagnostics.rs +++ b/clippy_utils/src/diagnostics.rs @@ -47,7 +47,7 @@ fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) { /// ``` pub fn span_lint(cx: &T, lint: &'static Lint, sp: impl Into, msg: &str) { #[expect(clippy::disallowed_methods)] - cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { + cx.span_lint(lint, sp, msg.to_string(), |diag| { docs_link(diag, lint); }); } @@ -81,7 +81,7 @@ pub fn span_lint_and_help( help: &str, ) { #[expect(clippy::disallowed_methods)] - cx.struct_span_lint(lint, span, msg.to_string(), |diag| { + cx.span_lint(lint, span, msg.to_string(), |diag| { let help = help.to_string(); if let Some(help_span) = help_span { diag.span_help(help_span, help); @@ -124,7 +124,7 @@ pub fn span_lint_and_note( note: &str, ) { #[expect(clippy::disallowed_methods)] - cx.struct_span_lint(lint, span, msg.to_string(), |diag| { + cx.span_lint(lint, span, msg.to_string(), |diag| { let note = note.to_string(); if let Some(note_span) = note_span { diag.span_note(note_span, note); @@ -146,7 +146,7 @@ where F: FnOnce(&mut Diagnostic), { #[expect(clippy::disallowed_methods)] - cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { + cx.span_lint(lint, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); }); @@ -154,7 +154,7 @@ where pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) { #[expect(clippy::disallowed_methods)] - cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { + cx.tcx.node_span_lint(lint, hir_id, sp, msg.to_string(), |diag| { docs_link(diag, lint); }); } @@ -168,7 +168,7 @@ pub fn span_lint_hir_and_then( f: impl FnOnce(&mut Diagnostic), ) { #[expect(clippy::disallowed_methods)] - cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { + cx.tcx.node_span_lint(lint, hir_id, sp, msg.to_string(), |diag| { f(diag); docs_link(diag, lint); }); diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 2b22e8a3370b..4fa93ad23c36 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -1007,7 +1007,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } e.hash(&mut self.s); }, - PatKind::Never | PatKind::Wild => {}, + PatKind::Never | PatKind::Wild | PatKind::Err(_) => {}, } } @@ -1108,7 +1108,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { TyKind::Typeof(anon_const) => { self.hash_body(anon_const.body); }, - TyKind::Err(_) | TyKind::Infer | TyKind::Never => {}, + TyKind::Err(_) | TyKind::Infer | TyKind::Never | TyKind::InferDelegation(..) => {}, } } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index cdf8528f48a2..4e499ff4cc61 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -80,6 +80,7 @@ use std::sync::{Mutex, MutexGuard, OnceLock}; use itertools::Itertools; use rustc_ast::ast::{self, LitKind, RangeLimits}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::packed::Pu128; use rustc_data_structures::unhash::UnhashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, LOCAL_CRATE}; @@ -534,10 +535,16 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator SimplifiedType::Uint(UintTy::U128), "f32" => SimplifiedType::Float(FloatTy::F32), "f64" => SimplifiedType::Float(FloatTy::F64), - _ => return [].iter().copied(), + #[allow(trivial_casts)] + _ => { + return Result::<_, rustc_errors::ErrorGuaranteed>::Ok(&[] as &[_]) + .into_iter() + .flatten() + .copied(); + }, }; - tcx.incoherent_impls(ty).iter().copied() + tcx.incoherent_impls(ty).into_iter().flatten().copied() } fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec { @@ -663,7 +670,8 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Vec { // `impl S { ... }` let inherent_impl_children = tcx .inherent_impls(def_id) - .iter() + .into_iter() + .flatten() .flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment)); let direct_children = item_children_by_name(tcx, def_id, segment); @@ -836,7 +844,7 @@ pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) -> pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { match &e.kind { ExprKind::Lit(lit) => match lit.node { - LitKind::Bool(false) | LitKind::Int(0, _) => true, + LitKind::Bool(false) | LitKind::Int(Pu128(0), _) => true, LitKind::Str(s, _) => s.is_empty(), _ => false, }, @@ -1709,7 +1717,6 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable. PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)), PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat), - PatKind::Lit(..) | PatKind::Range(..) => true, PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id), PatKind::Or(pats) => { // TODO: should be the honest check, that pats is exhaustive set @@ -1733,6 +1740,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { }, } }, + PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) => true, } } diff --git a/clippy_utils/src/mir/possible_borrower.rs b/clippy_utils/src/mir/possible_borrower.rs index 703985b9d4b3..f9cc5f191253 100644 --- a/clippy_utils/src/mir/possible_borrower.rs +++ b/clippy_utils/src/mir/possible_borrower.rs @@ -104,7 +104,7 @@ impl<'a, 'b, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'b, let mut mutable_borrowers = vec![]; for op in args { - match op { + match &op.node { mir::Operand::Copy(p) | mir::Operand::Move(p) => { if let ty::Ref(_, _, Mutability::Mut) = self.body.local_decls[p.local].ty.kind() { mutable_borrowers.push(p.local); diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 668ea9fcf3b4..81f4fcc2133d 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -345,7 +345,7 @@ fn check_terminator<'tcx>( check_operand(tcx, func, span, body)?; for arg in args { - check_operand(tcx, arg, span, body)?; + check_operand(tcx, &arg.node, span, body)?; } Ok(()) } else { diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 61d0663aa839..11bb16ff6c5b 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -214,36 +214,22 @@ pub fn implements_trait<'tcx>( trait_id: DefId, args: &[GenericArg<'tcx>], ) -> bool { - let callee_id = cx - .enclosing_body - .map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id()); - implements_trait_with_env_from_iter( - cx.tcx, - cx.param_env, - ty, - trait_id, - callee_id, - args.iter().map(|&x| Some(x)), - ) + implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, None, args.iter().map(|&x| Some(x))) } /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context. +/// +/// The `callee_id` argument is used to determine whether this is a function call in a `const fn` +/// environment, used for checking const traits. pub fn implements_trait_with_env<'tcx>( tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, trait_id: DefId, - callee_id: DefId, + callee_id: Option, args: &[GenericArg<'tcx>], ) -> bool { - implements_trait_with_env_from_iter( - tcx, - param_env, - ty, - trait_id, - Some(callee_id), - args.iter().map(|&x| Some(x)), - ) + implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x))) } /// Same as `implements_trait_from_env` but takes the arguments as an iterator. @@ -258,6 +244,13 @@ pub fn implements_trait_with_env_from_iter<'tcx>( // Clippy shouldn't have infer types assert!(!ty.has_infer()); + // If a `callee_id` is passed, then we assert that it is a body owner + // through calling `body_owner_kind`, which would panic if the callee + // does not have a body. + if let Some(callee_id) = callee_id { + let _ = tcx.hir().body_owner_kind(callee_id); + } + let ty = tcx.erase_regions(ty); if ty.has_escaping_bound_vars() { return false; diff --git a/rust-toolchain b/rust-toolchain index 2589d46e7da0..d2d56e59ee3f 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-01-11" +channel = "nightly-2024-01-25" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/tests/ui-internal/disallow_struct_span_lint.rs b/tests/ui-internal/disallow_span_lint.rs similarity index 83% rename from tests/ui-internal/disallow_struct_span_lint.rs rename to tests/ui-internal/disallow_span_lint.rs index c81d54918cbb..b9b4a07d29d0 100644 --- a/tests/ui-internal/disallow_struct_span_lint.rs +++ b/tests/ui-internal/disallow_span_lint.rs @@ -11,7 +11,7 @@ use rustc_lint::{Lint, LintContext}; use rustc_middle::ty::TyCtxt; pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into, msg: impl Into) { - cx.struct_span_lint(lint, span, msg, |_| {}); + cx.span_lint(lint, span, msg, |_| {}); } pub fn b( @@ -21,7 +21,7 @@ pub fn b( span: impl Into, msg: impl Into, ) { - tcx.struct_span_lint_hir(lint, hir_id, span, msg, |_| {}); + tcx.node_span_lint(lint, hir_id, span, msg, |_| {}); } fn main() {} diff --git a/tests/ui-internal/disallow_span_lint.stderr b/tests/ui-internal/disallow_span_lint.stderr new file mode 100644 index 000000000000..5ca183d41a93 --- /dev/null +++ b/tests/ui-internal/disallow_span_lint.stderr @@ -0,0 +1,17 @@ +error: use of a disallowed method `rustc_lint::context::LintContext::span_lint` + --> $DIR/disallow_span_lint.rs:14:5 + | +LL | cx.span_lint(lint, span, msg, |_| {}); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::disallowed-methods` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]` + +error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint` + --> $DIR/disallow_span_lint.rs:24:5 + | +LL | tcx.node_span_lint(lint, hir_id, span, msg, |_| {}); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui-internal/disallow_struct_span_lint.stderr b/tests/ui-internal/disallow_struct_span_lint.stderr deleted file mode 100644 index 7d424124f2b1..000000000000 --- a/tests/ui-internal/disallow_struct_span_lint.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: use of a disallowed method `rustc_lint::context::LintContext::struct_span_lint` - --> $DIR/disallow_struct_span_lint.rs:14:5 - | -LL | cx.struct_span_lint(lint, span, msg, |_| {}); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D clippy::disallowed-methods` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]` - -error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::struct_span_lint_hir` - --> $DIR/disallow_struct_span_lint.rs:24:5 - | -LL | tcx.struct_span_lint_hir(lint, hir_id, span, msg, |_| {}); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui-toml/pub_underscore_fields/exported/clippy.toml b/tests/ui-toml/pub_underscore_fields/exported/clippy.toml index 2b79cbd46e4b..9e472bd14ba5 100644 --- a/tests/ui-toml/pub_underscore_fields/exported/clippy.toml +++ b/tests/ui-toml/pub_underscore_fields/exported/clippy.toml @@ -1 +1 @@ -pub-underscore-fields-behavior = "PubliclyExported" \ No newline at end of file +pub-underscore-fields-behavior = "PubliclyExported" diff --git a/tests/ui/author/blocks.stdout b/tests/ui/author/blocks.stdout index 62de661f8ff8..8c4d71e68f80 100644 --- a/tests/ui/author/blocks.stdout +++ b/tests/ui/author/blocks.stdout @@ -48,7 +48,11 @@ if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_ && expr2 = &cx.tcx.hir().body(body_id1).value && let ExprKind::Block(block, None) = expr2.kind && block.stmts.is_empty() - && block.expr.is_none() + && let Some(trailing_expr) = block.expr + && let ExprKind::DropTemps(expr3) = trailing_expr.kind + && let ExprKind::Block(block1, None) = expr3.kind + && block1.stmts.is_empty() + && block1.expr.is_none() { // report your lint here } diff --git a/tests/ui/let_underscore_lock.rs b/tests/ui/let_underscore_lock.rs index ccac73be79e4..28d8dd498319 100644 --- a/tests/ui/let_underscore_lock.rs +++ b/tests/ui/let_underscore_lock.rs @@ -26,6 +26,7 @@ fn main() { let _ = p_rw; } +#[allow(let_underscore_lock)] fn uplifted() { // shouldn't lint std locks as they were uplifted as rustc's `let_underscore_lock` diff --git a/tests/ui/unknown_clippy_lints.fixed b/tests/ui/unknown_clippy_lints.fixed index cba32ce6b772..c0ccd41c19ab 100644 --- a/tests/ui/unknown_clippy_lints.fixed +++ b/tests/ui/unknown_clippy_lints.fixed @@ -7,10 +7,12 @@ #[warn(clippy::if_not_else)] #[warn(clippy::unnecessary_cast)] #[warn(clippy::useless_transmute)] -// Shouldn't suggest rustc lint name(`dead_code`) -#[warn(clippy::eq_op)] +// Should suggest rustc lint name(`dead_code`) +#[warn(dead_code)] // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) #[warn(clippy::unused_self)] // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) #[warn(clippy::redundant_static_lifetimes)] +// issue #118183, should report `missing_docs` from rustc lint +#[warn(missing_docs)] fn main() {} diff --git a/tests/ui/unknown_clippy_lints.rs b/tests/ui/unknown_clippy_lints.rs index c15d541974f0..7a59ad364aa7 100644 --- a/tests/ui/unknown_clippy_lints.rs +++ b/tests/ui/unknown_clippy_lints.rs @@ -7,10 +7,12 @@ #[warn(clippy::if_not_els)] #[warn(clippy::UNNecsaRy_cAst)] #[warn(clippy::useles_transute)] -// Shouldn't suggest rustc lint name(`dead_code`) +// Should suggest rustc lint name(`dead_code`) #[warn(clippy::dead_cod)] // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) #[warn(clippy::unused_colle)] // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) #[warn(clippy::const_static_lifetim)] +// issue #118183, should report `missing_docs` from rustc lint +#[warn(clippy::missing_docs)] fn main() {} diff --git a/tests/ui/unknown_clippy_lints.stderr b/tests/ui/unknown_clippy_lints.stderr index ee82db31c2c2..432c7f72e32e 100644 --- a/tests/ui/unknown_clippy_lints.stderr +++ b/tests/ui/unknown_clippy_lints.stderr @@ -35,7 +35,12 @@ error: unknown lint: `clippy::dead_cod` --> $DIR/unknown_clippy_lints.rs:11:8 | LL | #[warn(clippy::dead_cod)] - | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op` + | ^^^^^^^^^^^^^^^^ + | +help: a lint with a similar name exists in `rustc` lints + | +LL | #[warn(dead_code)] + | ~~~~~~~~~ error: unknown lint: `clippy::unused_colle` --> $DIR/unknown_clippy_lints.rs:13:8 @@ -49,5 +54,16 @@ error: unknown lint: `clippy::const_static_lifetim` LL | #[warn(clippy::const_static_lifetim)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::redundant_static_lifetimes` -error: aborting due to 8 previous errors +error: unknown lint: `clippy::missing_docs` + --> $DIR/unknown_clippy_lints.rs:17:8 + | +LL | #[warn(clippy::missing_docs)] + | ^^^^^^^^^^^^^^^^^^^^ + | +help: a lint with a similar name exists in `rustc` lints + | +LL | #[warn(missing_docs)] + | ~~~~~~~~~~~~ + +error: aborting due to 9 previous errors