Fix ICE in unnecessary_to_owned

Fixes #9504

Compiler generated call `into_iter` nodes return empty substs
which we need when checking it's predicates. Handle this by
simply exitting when we encounter one. This change introduces
false negatives in place of the ICEs.
This commit is contained in:
Michael Wright 2022-09-21 07:02:52 +02:00
parent 1f66a3e8d0
commit a783d54207
3 changed files with 23 additions and 1 deletions

View File

@ -8,7 +8,7 @@
use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty};
use clippy_utils::{meets_msrv, msrvs};
use rustc_errors::Applicability;
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, Node};
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
use rustc_middle::mir::Mutability;
@ -380,6 +380,10 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
Node::Expr(parent_expr) => {
if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
{
if cx.tcx.lang_items().require(LangItem::IntoFutureIntoFuture) == Ok(callee_def_id) {
return false;
}
let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
&& let Some(param_ty) = fn_sig.inputs().get(arg_index)

View File

@ -417,3 +417,12 @@ mod issue_9351 {
predicates_are_satisfied(id("abc".to_string()));
}
}
mod issue_9504 {
#![allow(dead_code)]
async fn foo<S: AsRef<str>>(_: S) {}
async fn bar() {
foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;
}
}

View File

@ -417,3 +417,12 @@ pub fn main() {
predicates_are_satisfied(id("abc".to_string()));
}
}
mod issue_9504 {
#![allow(dead_code)]
async fn foo<S: AsRef<str>>(_: S) {}
async fn bar() {
foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;
}
}