Skip to content

Commit f54362f

Browse files
borsflip1995
authored andcommitted
Auto merge of #11953 - Jarcho:issue_11952, r=Alexendoo
Fix binder handling in `unnecessary_to_owned` fixes #11952 The use of `rebind` instead of `EarlyBinder::bind` isn't technically needed, but it is the semantically correct operation. changelog: None
1 parent bdb77cc commit f54362f

File tree

4 files changed

+150
-103
lines changed

4 files changed

+150
-103
lines changed

Diff for: src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ use rustc_lint::LateContext;
1515
use rustc_middle::mir::Mutability;
1616
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
1717
use rustc_middle::ty::{
18-
self, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate,
19-
TraitPredicate, Ty,
18+
self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty,
2019
};
2120
use rustc_span::{sym, Symbol};
2221
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -375,6 +374,7 @@ fn get_input_traits_and_projections<'tcx>(
375374
(trait_predicates, projection_predicates)
376375
}
377376

377+
#[expect(clippy::too_many_lines)]
378378
fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<'a>) -> bool {
379379
for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) {
380380
match node {
@@ -403,22 +403,21 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
403403
if let Some((callee_def_id, call_generic_args, recv, call_args)) =
404404
get_callee_generic_args_and_args(cx, parent_expr)
405405
{
406-
// FIXME: the `instantiate_identity()` below seems incorrect, since we eventually
407-
// call `tcx.try_instantiate_and_normalize_erasing_regions` further down
408-
// (i.e., we are explicitly not in the identity context).
409-
let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder();
406+
let bound_fn_sig = cx.tcx.fn_sig(callee_def_id);
407+
let fn_sig = bound_fn_sig.skip_binder();
410408
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
411-
&& let Some(param_ty) = fn_sig.inputs().get(arg_index)
412-
&& let ty::Param(ParamTy { index: param_index , ..}) = param_ty.kind()
409+
&& let param_ty = fn_sig.input(arg_index).skip_binder()
410+
&& let ty::Param(ParamTy { index: param_index , ..}) = *param_ty.kind()
413411
// https://github.com/rust-lang/rust-clippy/issues/9504 and https://github.com/rust-lang/rust-clippy/issues/10021
414-
&& (*param_index as usize) < call_generic_args.len()
412+
&& (param_index as usize) < call_generic_args.len()
415413
{
416414
if fn_sig
415+
.skip_binder()
417416
.inputs()
418417
.iter()
419418
.enumerate()
420419
.filter(|(i, _)| *i != arg_index)
421-
.any(|(_, ty)| ty.contains(*param_ty))
420+
.any(|(_, ty)| ty.contains(param_ty))
422421
{
423422
return false;
424423
}
@@ -430,7 +429,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
430429
.iter()
431430
.filter(|predicate| {
432431
if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
433-
&& trait_predicate.trait_ref.self_ty() == *param_ty
432+
&& trait_predicate.trait_ref.self_ty() == param_ty
434433
{
435434
true
436435
} else {
@@ -441,15 +440,15 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
441440
let new_subst = cx
442441
.tcx
443442
.mk_args_from_iter(call_generic_args.iter().enumerate().map(|(i, t)| {
444-
if i == (*param_index as usize) {
443+
if i == param_index as usize {
445444
GenericArg::from(ty)
446445
} else {
447446
t
448447
}
449448
}));
450449

451450
if trait_predicates.any(|predicate| {
452-
let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, new_subst);
451+
let predicate = bound_fn_sig.rebind(predicate).instantiate(cx.tcx, new_subst);
453452
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
454453
!cx.tcx
455454
.infer_ctxt()
@@ -459,12 +458,12 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
459458
return false;
460459
}
461460

462-
let output_ty = fn_sig.output();
463-
if output_ty.contains(*param_ty) {
461+
let output_ty = cx.tcx.erase_late_bound_regions(fn_sig.output());
462+
if output_ty.contains(param_ty) {
464463
if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions(
465464
new_subst,
466465
cx.param_env,
467-
EarlyBinder::bind(output_ty),
466+
bound_fn_sig.rebind(output_ty),
468467
) {
469468
expr = parent_expr;
470469
ty = new_ty;

Diff for: src/tools/clippy/tests/ui/unnecessary_to_owned.fixed

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
1+
#![allow(
2+
clippy::needless_borrow,
3+
clippy::needless_borrows_for_generic_args,
4+
clippy::ptr_arg,
5+
clippy::manual_async_fn,
6+
clippy::needless_lifetimes
7+
)]
28
#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
39

410
use std::borrow::Cow;
@@ -506,3 +512,18 @@ mod issue_10033 {
506512
}
507513
}
508514
}
515+
516+
mod issue_11952 {
517+
use core::future::{Future, IntoFuture};
518+
519+
fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {
520+
async move {
521+
let _y = y;
522+
Ok(())
523+
}
524+
}
525+
526+
fn bar() {
527+
IntoFuture::into_future(foo([], &0));
528+
}
529+
}

Diff for: src/tools/clippy/tests/ui/unnecessary_to_owned.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
1+
#![allow(
2+
clippy::needless_borrow,
3+
clippy::needless_borrows_for_generic_args,
4+
clippy::ptr_arg,
5+
clippy::manual_async_fn,
6+
clippy::needless_lifetimes
7+
)]
28
#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
39

410
use std::borrow::Cow;
@@ -506,3 +512,18 @@ mod issue_10033 {
506512
}
507513
}
508514
}
515+
516+
mod issue_11952 {
517+
use core::future::{Future, IntoFuture};
518+
519+
fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {
520+
async move {
521+
let _y = y;
522+
Ok(())
523+
}
524+
}
525+
526+
fn bar() {
527+
IntoFuture::into_future(foo([].to_vec(), &0));
528+
}
529+
}

0 commit comments

Comments
 (0)