Fix clippy's missing substs

This commit is contained in:
Oli Scherer 2022-11-18 19:58:07 +00:00
parent c7828221e3
commit f60e43ee05
6 changed files with 19 additions and 13 deletions

View file

@ -466,12 +466,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
if let Some(def_id) = trait_ref.trait_def_id(); if let Some(def_id) = trait_ref.trait_def_id();
if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id); if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id);
let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id); let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id);
if !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]); if !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, []);
// If all of our fields implement `Eq`, we can implement `Eq` too // If all of our fields implement `Eq`, we can implement `Eq` too
if adt if adt
.all_fields() .all_fields()
.map(|f| f.ty(cx.tcx, substs)) .map(|f| f.ty(cx.tcx, substs))
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[])); .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, []));
then { then {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,

View file

@ -119,11 +119,13 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs(); let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs();
if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc);
if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc);
if let ty::Closure(_, substs) = *closure_ty.kind();
then { then {
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
if let Some(mut snippet) = snippet_opt(cx, callee.span) { if let Some(mut snippet) = snippet_opt(cx, callee.span) {
if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait() if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait()
&& implements_trait(cx, callee_ty.peel_refs(), fn_mut_id, &[]) && let args = cx.tcx.erase_late_bound_regions(ty::ClosureSubsts { substs }.sig()).inputs()
&& implements_trait(cx, callee_ty.peel_refs(), fn_mut_id, &args.iter().copied().map(Into::into).collect::<Vec<_>>())
&& path_to_local(callee).map_or(false, |l| local_used_after_expr(cx, l, expr)) && path_to_local(callee).map_or(false, |l| local_used_after_expr(cx, l, expr))
{ {
// Mutable closure is used after current expr; we cannot consume it. // Mutable closure is used after current expr; we cannot consume it.

View file

@ -474,7 +474,7 @@ fn is_cow_into_owned(cx: &LateContext<'_>, method_name: Symbol, method_def_id: D
} }
/// Returns true if the named method is `ToString::to_string` and it's called on a type that /// Returns true if the named method is `ToString::to_string` and it's called on a type that
/// is string-like i.e. implements `AsRef<str>` or `Deref<str>`. /// is string-like i.e. implements `AsRef<str>` or `Deref<Target = str>`.
fn is_to_string_on_string_like<'a>( fn is_to_string_on_string_like<'a>(
cx: &LateContext<'_>, cx: &LateContext<'_>,
call_expr: &'a Expr<'a>, call_expr: &'a Expr<'a>,
@ -490,7 +490,7 @@ fn is_to_string_on_string_like<'a>(
&& let GenericArgKind::Type(ty) = generic_arg.unpack() && let GenericArgKind::Type(ty) = generic_arg.unpack()
&& let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
&& let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)
&& (implements_trait(cx, ty, deref_trait_id, &[cx.tcx.types.str_.into()]) || && (get_associated_type(cx, ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) ||
implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) { implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) {
true true
} else { } else {

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::ptr::get_spans; use clippy_utils::ptr::get_spans;
use clippy_utils::source::{snippet, snippet_opt}; use clippy_utils::source::{snippet, snippet_opt};
use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy, is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::{get_trait_def_id, is_self, paths}; use clippy_utils::{get_trait_def_id, is_self, paths};
use if_chain::if_chain; use if_chain::if_chain;
use rustc_ast::ast::Attribute; use rustc_ast::ast::Attribute;
@ -185,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
if !ty.is_mutable_ptr(); if !ty.is_mutable_ptr();
if !is_copy(cx, ty); if !is_copy(cx, ty);
if ty.is_sized(cx.tcx, cx.param_env); if ty.is_sized(cx.tcx, cx.param_env);
if !allowed_traits.iter().any(|&t| implements_trait(cx, ty, t, &[])); if !allowed_traits.iter().any(|&t| implements_trait_with_env(cx.tcx, cx.param_env, ty, t, [None]));
if !implements_borrow_trait; if !implements_borrow_trait;
if !all_borrowable_trait; if !all_borrowable_trait;

View file

@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd {
let implements_partial_ord = { let implements_partial_ord = {
if let Some(id) = cx.tcx.lang_items().partial_ord_trait() { if let Some(id) = cx.tcx.lang_items().partial_ord_trait() {
implements_trait(cx, ty, id, &[]) implements_trait(cx, ty, id, &[ty.into()])
} else { } else {
return; return;
} }

View file

@ -9,7 +9,7 @@ use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety}; use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::{TyCtxtInferExt, type_variable::{TypeVariableOrigin, TypeVariableOriginKind}};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::mir::interpret::{ConstValue, Scalar};
use rustc_middle::ty::{ use rustc_middle::ty::{
@ -18,7 +18,7 @@ use rustc_middle::ty::{
}; };
use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_middle::ty::{GenericArg, GenericArgKind};
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::{sym, Span, Symbol}; use rustc_span::{sym, Span, Symbol, DUMMY_SP};
use rustc_target::abi::{Size, VariantIdx}; use rustc_target::abi::{Size, VariantIdx};
use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::query::normalize::AtExt; use rustc_trait_selection::traits::query::normalize::AtExt;
@ -153,7 +153,7 @@ pub fn implements_trait<'tcx>(
trait_id: DefId, trait_id: DefId,
ty_params: &[GenericArg<'tcx>], ty_params: &[GenericArg<'tcx>],
) -> bool { ) -> bool {
implements_trait_with_env(cx.tcx, cx.param_env, ty, trait_id, ty_params) implements_trait_with_env(cx.tcx, cx.param_env, ty, trait_id, ty_params.iter().map(|&arg| Some(arg)))
} }
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context. /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
@ -162,7 +162,7 @@ pub fn implements_trait_with_env<'tcx>(
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_id: DefId, trait_id: DefId,
ty_params: &[GenericArg<'tcx>], ty_params: impl IntoIterator<Item = Option<GenericArg<'tcx>>>,
) -> bool { ) -> bool {
// Clippy shouldn't have infer types // Clippy shouldn't have infer types
assert!(!ty.needs_infer()); assert!(!ty.needs_infer());
@ -171,8 +171,12 @@ pub fn implements_trait_with_env<'tcx>(
if ty.has_escaping_bound_vars() { if ty.has_escaping_bound_vars() {
return false; return false;
} }
let ty_params = tcx.mk_substs(ty_params.iter());
let infcx = tcx.infer_ctxt().build(); let infcx = tcx.infer_ctxt().build();
let orig = TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span: DUMMY_SP,
};
let ty_params = tcx.mk_substs(ty_params.into_iter().map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())));
infcx infcx
.type_implements_trait(trait_id, ty, ty_params, param_env) .type_implements_trait(trait_id, ty, ty_params, param_env)
.must_apply_modulo_regions() .must_apply_modulo_regions()