From 043bfcc7c4e1ccce4b8b064b5833fdefc855c089 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Fri, 24 Jul 2026 17:05:01 +0200 Subject: [PATCH 1/3] - implement `GenericArgs::terms` and use where needed. - be explicit when only needing types of `GenericArgs` --- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 1 + compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 3 ++- compiler/rustc_middle/src/ty/generic_args.rs | 5 +++++ compiler/rustc_middle/src/ty/print/pretty.rs | 4 +--- .../src/function_item_references.rs | 4 +--- .../src/error_reporting/infer/need_type_info.rs | 2 +- .../src/error_reporting/traits/ambiguity.rs | 7 +------ .../src/traits/auto_trait.rs | 4 ++-- .../src/traits/select/mod.rs | 2 ++ src/tools/clippy/clippy_lints/src/manual_bits.rs | 2 +- src/tools/clippy/clippy_lints/src/methods/lib.rs | 2 +- .../src/methods/manual_str_repeat.rs | 2 +- .../src/methods/map_collect_result_unit.rs | 2 +- .../clippy/clippy_lints/src/methods/ok_expect.rs | 4 +++- .../clippy_lints/src/size_of_in_element_count.rs | 8 ++++++-- .../src/transmute/transmute_undefined_repr.rs | 16 ++++++++++------ .../clippy_lints/src/useless_conversion.rs | 4 ++-- tests/ui/lint/function-item-references.rs | 4 ++-- tests/ui/lint/function-item-references.stderr | 4 ++-- 20 files changed, 46 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 370d43d35d3ac..07a129fe236f2 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1849,7 +1849,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { assert_eq!(tcx.trait_impl_of_assoc(def_id), None); self.prove_clauses( - args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())), + args.terms().map(|t| ty::ClauseKind::WellFormed(t.into())), locations, ConstraintCategory::Boring, ); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 6e64fa7d04a93..d08e8a3c4f42f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1431,6 +1431,7 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>( ty: Ty<'tcx>, ) -> SmallVec> { if let ty::Adt(def, args) = *ty.kind() { + // FIXME: also do consts? if args.types().next().is_some() { let generics = cx.tcx.generics_of(def.did()); let names = get_parameter_names(cx, generics); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 580b7a89484d4..3c31be8b7d038 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -284,7 +284,7 @@ impl<'ll, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { generics: &ty::Generics, args: GenericArgsRef<'tcx>, ) -> &'ll DIArray { - if args.types().next().is_none() { + if args.terms().next().is_none() { return create_DIArray(DIB(cx), &[]); } @@ -293,6 +293,7 @@ impl<'ll, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let names = get_parameter_names(cx, generics); iter::zip(args, names) .filter_map(|(kind, name)| { + // FIXME: debug info for consts (using `createTemplateValueParameter`?) kind.as_type().map(|ty| { let actual_type = cx.tcx.normalize_erasing_regions( cx.typing_env(), diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index a9ca6bfef5534..fceb737dc8365 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -518,6 +518,11 @@ impl<'tcx> GenericArgs<'tcx> { self.iter().filter_map(|k| k.as_const()) } + #[inline] + pub fn terms(&self) -> impl DoubleEndedIterator> { + self.iter().filter_map(|k| k.as_term()) + } + /// Returns generic arguments that are not lifetimes. #[inline] pub fn non_erasable_generics(&self) -> impl DoubleEndedIterator> { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3c7e3b63ee9b5..885921b9d9bd9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2305,9 +2305,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { // `Foo<...>`. if let Some(arg) = args.types().next() { if let ty::Adt(_, arg_args) = arg.kind() { - if arg_args.consts().next().is_none() - && arg_args.types().next().is_none() - { + if arg_args.terms().next().is_none() { // Single param type with no type or const parameters: // `Foo>`. true diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 41d16c00ff64b..a7b27f824e9e2 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -164,9 +164,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { other_abi => format!("extern {other_abi} "), }; let ident = self.tcx.item_ident(fn_id); - let ty_params = fn_args.types().map(|ty| format!("{ty}")); - let const_params = fn_args.consts().map(|c| format!("{c}")); - let params = ty_params.chain(const_params).join(", "); + let params = fn_args.terms().map(|term| format!("{term}")).join(", "); let num_args = fn_sig.inputs().map_bound(|inputs| inputs.len()).skip_binder(); let variadic = if fn_sig.c_variadic() { ", ..." } else { "" }; let ret = if fn_sig.output().skip_binder().is_unit() { "" } else { " -> _" }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index f9b484cc6cadd..dd41ddfd456d3 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -677,7 +677,7 @@ impl<'tcx> InferSourceKind<'tcx> { || matches!( ty.kind(), ty::Adt(_, args) - if args.types().count() == 0 && args.consts().count() == 0 + if args.terms().next().is_none() ) { // `ty` is either `_`, a primitive type like `u32` or a type with no type or diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 5e2e9f67103dd..2e627ba768e2c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -255,12 +255,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Pick the first generic parameter that still contains inference variables as the one // we're going to emit an error for. If there are none (see above), fall back to // a more general error. - let term = data - .trait_ref - .args - .iter() - .filter_map(ty::GenericArg::as_term) - .find(|s| s.has_non_region_infer()); + let term = data.trait_ref.args.terms().find(|s| s.has_non_region_infer()); let mut err = if let Some(term) = term { let candidates: Vec<_> = self diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 691290f75495b..3ce02617c3898 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -455,7 +455,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let new_args = new_trait.trait_ref.args; let old_args = old_trait.trait_ref.args; - if !new_args.types().eq(old_args.types()) { + if !new_args.terms().eq(old_args.terms()) { // We can't compare lifetimes if the types are different, // so skip checking `old_clause`. return true; @@ -625,7 +625,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { } fn is_param_no_infer(&self, args: GenericArgsRef<'tcx>) -> bool { - self.is_of_param(args.type_at(0)) && !args.types().any(|t| t.has_infer_types()) + self.is_of_param(args.type_at(0)) && !args.terms().any(|t| t.has_infer_types()) } pub fn is_of_param(&self, ty: Ty<'tcx>) -> bool { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 58f2d0c7f33ac..86a2c6d49842e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1237,6 +1237,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // This suffices to allow chains like `FnMut` implemented in // terms of `Fn` etc, but we could probably make this more // precise still. + // + // FIXME(min_generic_const_args): Consider consts as well? let unbound_input_types = stack.fresh_trait_pred.skip_binder().trait_ref.args.types().any(|ty| ty.is_fresh()); diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs index dd64381033d41..149480511098f 100644 --- a/src/tools/clippy/clippy_lints/src/manual_bits.rs +++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs @@ -102,7 +102,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option< cx.typeck_results() .node_args(count_func.hir_id) .types() - .next() + .nth(0) // the `T` in `size_of::` .map(|resolved_ty| (real_ty_span, resolved_ty)) } else { None diff --git a/src/tools/clippy/clippy_lints/src/methods/lib.rs b/src/tools/clippy/clippy_lints/src/methods/lib.rs index 84038283bcf8f..ceab607d8d96b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/lib.rs +++ b/src/tools/clippy/clippy_lints/src/methods/lib.rs @@ -22,7 +22,7 @@ impl SelfKind { } else if let ty::Adt(adt_def, args) = ty.kind() && matches!(cx.tcx.get_diagnostic_name(adt_def.did()), Some(sym::Rc | sym::Arc)) { - args.types().next() == Some(parent_ty) + args.iter().filter_map(ty::GenericArg::as_type).nth(0) == Some(parent_ty) } else { false } diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs index 457549d1091c0..70a37a5767fa4 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs @@ -19,7 +19,7 @@ enum RepeatKind { fn get_ty_param(ty: Ty<'_>) -> Option> { if let ty::Adt(_, subs) = ty.kind() { - subs.types().next() + subs.iter().filter_map(ty::GenericArg::as_type).nth(0) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs b/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs index 1112fbc2a1c74..127232d14c64a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs @@ -14,7 +14,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, iter: &hir::Expr let collect_ret_ty = cx.typeck_results().expr_ty(expr); if collect_ret_ty.is_diag_item(cx, sym::Result) && let ty::Adt(_, args) = collect_ret_ty.kind() - && let Some(result_t) = args.types().next() + && let Some(result_t) = args.iter().filter_map(ty::GenericArg::as_type).nth(0) && result_t.is_unit() // get parts for snippet { diff --git a/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs b/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs index 5f1cae130daed..19c6d65d73145 100644 --- a/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs @@ -37,7 +37,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr /// Given a `Result` type, return its error type (`E`). fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option> { match ty.kind() { - ty::Adt(adt, args) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => args.types().nth(1), + ty::Adt(adt, args) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => { + args.iter().filter_map(ty::GenericArg::as_type).nth(1) + }, _ => None, } } diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs index 3623039aece15..c135283a702d0 100644 --- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs +++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs @@ -43,7 +43,11 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, inverted: Some(sym::mem_size_of | sym::mem_size_of_val) ) { - cx.typeck_results().node_args(count_func.hir_id).types().next() + cx.typeck_results() + .node_args(count_func.hir_id) + .iter() + .filter_map(ty::GenericArg::as_type) + .nth(0) } else { None } @@ -92,7 +96,7 @@ fn get_pointee_ty_and_count_expr<'tcx>( )) // Get the pointee type - && let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).types().next() + && let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).iter().filter_map(ty::GenericArg::as_type).nth(0) { return Some((pointee_ty, count)); } diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index 05f4071406477..e7957fe10257b 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -323,12 +323,16 @@ fn is_size_pair(ty: Ty<'_>) -> bool { } fn same_except_params<'tcx>(subs1: GenericArgsRef<'tcx>, subs2: GenericArgsRef<'tcx>) -> bool { - // TODO: check const parameters as well. Currently this will consider `Array<5>` the same as - // `Array<6>` - for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) { - match (ty1.kind(), ty2.kind()) { - (ty::Param(_), _) | (_, ty::Param(_)) => (), - (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (), + for (t1, t2) in subs1.terms().zip(subs2.terms()).filter(|(t1, t2)| t1 != t2) { + match (t1.kind(), t2.kind()) { + (ty::TermKind::Ty(ty1), ty::TermKind::Ty(ty2)) => match (ty1.kind(), ty2.kind()) { + (ty::Param(_), _) | (_, ty::Param(_)) => (), + (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (), + _ => return false, + }, + // FIXME: check const parameters better as well. Currently this will consider `Array<5>` the same as + // `Array<6>` + (ty::TermKind::Const(c1), ty::TermKind::Const(c2)) if c1 == c2 => todo!(), _ => return false, } } diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index 2961ee7081533..8a5816cc4dc4e 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -399,7 +399,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { && let b = cx.typeck_results().expr_ty(recv) && a.is_diag_item(cx, sym::Result) && let ty::Adt(_, args) = a.kind() - && let Some(a_type) = args.types().next() + && let Some(a_type) = args.iter().filter_map(GenericArg::as_type).nth(0) && same_type_modulo_regions(a_type, b) { span_lint_and_help( @@ -424,7 +424,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { if name == sym::try_from_fn && a.is_diag_item(cx, sym::Result) && let ty::Adt(_, args) = a.kind() - && let Some(a_type) = args.types().next() + && let Some(a_type) = args.iter().filter_map(GenericArg::as_type).nth(0) && same_type_modulo_regions(a_type, b) { let hint = format!("consider removing `{}()`", snippet(cx, path.span, "TryFrom::try_from")); diff --git a/tests/ui/lint/function-item-references.rs b/tests/ui/lint/function-item-references.rs index 5afd8341473f3..739e5fab8a35e 100644 --- a/tests/ui/lint/function-item-references.rs +++ b/tests/ui/lint/function-item-references.rs @@ -16,7 +16,7 @@ unsafe extern "C" fn variadic(_x: u32, _args: ...) { } fn take_generic_ref<'a, T>(_x: &'a T) { } fn take_generic_array(_x: [T; N]) { } fn multiple_generic(_x: T, _y: U) { } -fn multiple_generic_arrays(_x: [T; N], _y: [U; M]) { } +fn multiple_generic_arrays(_x: [T; N], _y: [U; M]) { } //function references passed to these functions should never lint fn call_fn(f: &dyn Fn(u32) -> u32, x: u32) { f(x); } @@ -120,7 +120,7 @@ fn main() { //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &multiple_generic::); //~^ WARNING taking a reference to a function item does not give a function pointer - println!("{:p}", &multiple_generic_arrays::); + println!("{:p}", &multiple_generic_arrays::); //~^ WARNING taking a reference to a function item does not give a function pointer println!("{:p}", &std::env::var::); //~^ WARNING taking a reference to a function item does not give a function pointer diff --git a/tests/ui/lint/function-item-references.stderr b/tests/ui/lint/function-item-references.stderr index 837a4b2087fdf..f2c7a03fc8f70 100644 --- a/tests/ui/lint/function-item-references.stderr +++ b/tests/ui/lint/function-item-references.stderr @@ -127,8 +127,8 @@ LL | println!("{:p}", &multiple_generic::); warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:123:22 | -LL | println!("{:p}", &multiple_generic_arrays::); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `multiple_generic_arrays` to obtain a function pointer: `multiple_generic_arrays:: as fn(_, _)` +LL | println!("{:p}", &multiple_generic_arrays::); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `multiple_generic_arrays` to obtain a function pointer: `multiple_generic_arrays:: as fn(_, _)` warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:125:22 From ef954bc23e5e52a1cdbe92b108a63e451f10627e Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Sat, 8 Aug 2026 10:53:43 +0200 Subject: [PATCH 2/3] use `next().and_then(as_type)` instead of `filter_map(as_type).nth(0)` --- src/tools/clippy/clippy_lints/src/manual_bits.rs | 5 +++-- src/tools/clippy/clippy_lints/src/methods/lib.rs | 2 +- .../clippy/clippy_lints/src/methods/manual_str_repeat.rs | 2 +- .../clippy_lints/src/methods/map_collect_result_unit.rs | 2 +- src/tools/clippy/clippy_lints/src/methods/ok_expect.rs | 2 +- .../clippy/clippy_lints/src/size_of_in_element_count.rs | 6 +++--- .../clippy_lints/src/transmute/transmute_undefined_repr.rs | 6 +++--- src/tools/clippy/clippy_lints/src/useless_conversion.rs | 4 ++-- 8 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs index 149480511098f..32c18fc3fd57a 100644 --- a/src/tools/clippy/clippy_lints/src/manual_bits.rs +++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs @@ -101,8 +101,9 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option< { cx.typeck_results() .node_args(count_func.hir_id) - .types() - .nth(0) // the `T` in `size_of::` + .iter() + .next() // the `T` in `size_of::` + .and_then(ty::GenericArg::as_type) .map(|resolved_ty| (real_ty_span, resolved_ty)) } else { None diff --git a/src/tools/clippy/clippy_lints/src/methods/lib.rs b/src/tools/clippy/clippy_lints/src/methods/lib.rs index ceab607d8d96b..9246ed331ee94 100644 --- a/src/tools/clippy/clippy_lints/src/methods/lib.rs +++ b/src/tools/clippy/clippy_lints/src/methods/lib.rs @@ -22,7 +22,7 @@ impl SelfKind { } else if let ty::Adt(adt_def, args) = ty.kind() && matches!(cx.tcx.get_diagnostic_name(adt_def.did()), Some(sym::Rc | sym::Arc)) { - args.iter().filter_map(ty::GenericArg::as_type).nth(0) == Some(parent_ty) + args.iter().next().and_then(ty::GenericArg::as_type) == Some(parent_ty) } else { false } diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs index 70a37a5767fa4..744919b5a9362 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs @@ -19,7 +19,7 @@ enum RepeatKind { fn get_ty_param(ty: Ty<'_>) -> Option> { if let ty::Adt(_, subs) = ty.kind() { - subs.iter().filter_map(ty::GenericArg::as_type).nth(0) + subs.iter().next().and_then(ty::GenericArg::as_type) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs b/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs index 127232d14c64a..abefde55f5b62 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs @@ -14,7 +14,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, iter: &hir::Expr let collect_ret_ty = cx.typeck_results().expr_ty(expr); if collect_ret_ty.is_diag_item(cx, sym::Result) && let ty::Adt(_, args) = collect_ret_ty.kind() - && let Some(result_t) = args.iter().filter_map(ty::GenericArg::as_type).nth(0) + && let Some(result_t) = args.iter().next().and_then(ty::GenericArg::as_type) && result_t.is_unit() // get parts for snippet { diff --git a/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs b/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs index 19c6d65d73145..2f4afd4eb1c3e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs @@ -38,7 +38,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option> { match ty.kind() { ty::Adt(adt, args) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => { - args.iter().filter_map(ty::GenericArg::as_type).nth(1) + args.iter().nth(1).and_then(ty::GenericArg::as_type) }, _ => None, } diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs index c135283a702d0..76e2eda6c4bc4 100644 --- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs +++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs @@ -46,8 +46,8 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, inverted: cx.typeck_results() .node_args(count_func.hir_id) .iter() - .filter_map(ty::GenericArg::as_type) - .nth(0) + .next() + .and_then(ty::GenericArg::as_type) } else { None } @@ -96,7 +96,7 @@ fn get_pointee_ty_and_count_expr<'tcx>( )) // Get the pointee type - && let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).iter().filter_map(ty::GenericArg::as_type).nth(0) + && let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).iter().next().and_then(ty::GenericArg::as_type) { return Some((pointee_ty, count)); } diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index e7957fe10257b..297164aa00601 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -330,9 +330,9 @@ fn same_except_params<'tcx>(subs1: GenericArgsRef<'tcx>, subs2: GenericArgsRef<' (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (), _ => return false, }, - // FIXME: check const parameters better as well. Currently this will consider `Array<5>` the same as - // `Array<6>` - (ty::TermKind::Const(c1), ty::TermKind::Const(c2)) if c1 == c2 => todo!(), + // FIXME: check const parameters better as well. Is it still possible to treat equal + // consts as unequal? + (ty::TermKind::Const(c1), ty::TermKind::Const(c2)) if c1 == c2 => return true, _ => return false, } } diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index 8a5816cc4dc4e..bee045e609e96 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -399,7 +399,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { && let b = cx.typeck_results().expr_ty(recv) && a.is_diag_item(cx, sym::Result) && let ty::Adt(_, args) = a.kind() - && let Some(a_type) = args.iter().filter_map(GenericArg::as_type).nth(0) + && let Some(a_type) = args.iter().next().and_then(GenericArg::as_type) && same_type_modulo_regions(a_type, b) { span_lint_and_help( @@ -424,7 +424,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { if name == sym::try_from_fn && a.is_diag_item(cx, sym::Result) && let ty::Adt(_, args) = a.kind() - && let Some(a_type) = args.iter().filter_map(GenericArg::as_type).nth(0) + && let Some(a_type) = args.iter().next().and_then(GenericArg::as_type) && same_type_modulo_regions(a_type, b) { let hint = format!("consider removing `{}()`", snippet(cx, path.span, "TryFrom::try_from")); From 1fc152fc89604e751e769e7ec819a99e24990051 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Mon, 10 Aug 2026 12:59:26 +0200 Subject: [PATCH 3/3] fix ci failure and fixup const check in clippy lint --- .../clippy/clippy_lints/src/methods/manual_str_repeat.rs | 2 +- src/tools/clippy/clippy_lints/src/methods/ok_expect.rs | 4 +--- .../clippy_lints/src/transmute/transmute_undefined_repr.rs | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs index 744919b5a9362..457549d1091c0 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs @@ -19,7 +19,7 @@ enum RepeatKind { fn get_ty_param(ty: Ty<'_>) -> Option> { if let ty::Adt(_, subs) = ty.kind() { - subs.iter().next().and_then(ty::GenericArg::as_type) + subs.types().next() } else { None } diff --git a/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs b/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs index 2f4afd4eb1c3e..4c38d9d378e51 100644 --- a/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs @@ -37,9 +37,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr /// Given a `Result` type, return its error type (`E`). fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option> { match ty.kind() { - ty::Adt(adt, args) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => { - args.iter().nth(1).and_then(ty::GenericArg::as_type) - }, + ty::Adt(adt, args) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => args.iter().nth(1)?.as_type(), _ => None, } } diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index 297164aa00601..83eca20266684 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -330,9 +330,9 @@ fn same_except_params<'tcx>(subs1: GenericArgsRef<'tcx>, subs2: GenericArgsRef<' (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (), _ => return false, }, - // FIXME: check const parameters better as well. Is it still possible to treat equal - // consts as unequal? - (ty::TermKind::Const(c1), ty::TermKind::Const(c2)) if c1 == c2 => return true, + // FIXME: check const parameters better as well. Currently this will consider `Array<5>` the same as + // `Array<6>` + (ty::TermKind::Const(_), ty::TermKind::Const(_)) => {}, _ => return false, } }