mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 21:23:56 +00:00
Fix clippy's missing substs
This commit is contained in:
parent
c7828221e3
commit
f60e43ee05
6 changed files with 19 additions and 13 deletions
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue