From 00faed9f0cb0129dc39d3f6ea769df35c68a4d05 Mon Sep 17 00:00:00 2001 From: kadmin <julianknodt@gmail.com> Date: Sat, 24 Apr 2021 21:41:57 +0000 Subject: [PATCH 1/3] Add generic arg infer --- clippy_utils/src/hir_utils.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index a21ad42c061..63737955f09 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -885,7 +885,15 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { pub fn hash_ty(&mut self, ty: &Ty<'_>) { std::mem::discriminant(&ty.kind).hash(&mut self.s); - match ty.kind { + self.hash_tykind(&ty.kind); + } + + pub fn hash_infer(&mut self) { + "_".hash(&mut self.s); + } + + pub fn hash_tykind(&mut self, ty: &TyKind<'_>) { + match ty { TyKind::Slice(ty) => { self.hash_ty(ty); }, @@ -949,6 +957,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { GenericArg::Lifetime(l) => self.hash_lifetime(l), GenericArg::Type(ref ty) => self.hash_ty(ty), GenericArg::Const(ref ca) => self.hash_body(ca.value.body), + GenericArg::Infer(ref _inf) => self.hash_infer(), } } } From 8286824ab2f776eeaebd21b1f78bacda34dcbcba Mon Sep 17 00:00:00 2001 From: kadmin <julianknodt@gmail.com> Date: Mon, 26 Apr 2021 18:19:23 +0000 Subject: [PATCH 2/3] Add inferred args to typeck --- clippy_lints/src/implicit_hasher.rs | 10 +++- clippy_lints/src/types/type_complexity.rs | 7 ++- clippy_lints/src/use_self.rs | 56 ++++++++++++++++++++++- clippy_utils/src/hir_utils.rs | 8 ++-- clippy_utils/src/ty.rs | 2 +- tests/ui/transmute_ptr_to_ref.stderr | 4 +- 6 files changed, 75 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index 9a040ca572a..ad4898d1ccb 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -5,7 +5,7 @@ use std::collections::BTreeMap; use rustc_errors::DiagnosticBuilder; use rustc_hir as hir; -use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, NestedVisitorMap, Visitor}; +use rustc_hir::intravisit::{walk_body, walk_expr, walk_ty, walk_inf, NestedVisitorMap, Visitor}; use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -295,6 +295,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'a, 'tcx> { walk_ty(self, t); } + fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { + if let Some(target) = ImplicitHasherType::new(self.cx, &inf.to_ty()) { + self.found.push(target); + } + + walk_inf(self, inf); + } + fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> { NestedVisitorMap::None } diff --git a/clippy_lints/src/types/type_complexity.rs b/clippy_lints/src/types/type_complexity.rs index d8c4b67520d..b438d680d2c 100644 --- a/clippy_lints/src/types/type_complexity.rs +++ b/clippy_lints/src/types/type_complexity.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint; use rustc_hir as hir; -use rustc_hir::intravisit::{walk_ty, NestedVisitorMap, Visitor}; +use rustc_hir::intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor}; use rustc_hir::{GenericParamKind, TyKind}; use rustc_lint::LateContext; use rustc_middle::hir::map::Map; @@ -39,6 +39,11 @@ struct TypeComplexityVisitor { impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { type Map = Map<'tcx>; + fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { + self.score += 1; + walk_inf(self, inf); + } + fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_>) { let (add_score, sub_nest) = match ty.kind { // _, &x and *x have only small overhead; don't mess with nesting level diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 71117e967e3..c8cdf1a5d2c 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -8,8 +8,9 @@ use rustc_hir::{ self as hir, def::{CtorOf, DefKind, Res}, def_id::LocalDefId, - intravisit::{walk_ty, NestedVisitorMap, Visitor}, - Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind, + intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor}, + Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Node, Path, PathSegment, + QPath, TyKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::hir::map::Map; @@ -263,6 +264,11 @@ struct SkipTyCollector { impl<'tcx> Visitor<'tcx> for SkipTyCollector { type Map = Map<'tcx>; + fn visit_infer(&mut self, inf: &hir::InferArg) { + self.types_to_skip.push(inf.hir_id); + + walk_inf(self, inf) + } fn visit_ty(&mut self, hir_ty: &hir::Ty<'_>) { self.types_to_skip.push(hir_ty.hir_id); @@ -274,6 +280,52 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector { } } +<<<<<<< HEAD +======= +struct LintTyCollector<'a, 'tcx> { + cx: &'a LateContext<'tcx>, + self_ty: Ty<'tcx>, + types_to_lint: Vec<HirId>, + types_to_skip: Vec<HirId>, +} + +impl<'a, 'tcx> Visitor<'tcx> for LintTyCollector<'a, 'tcx> { + type Map = Map<'tcx>; + + fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'_>) { + if_chain! { + if let Some(ty) = self.cx.typeck_results().node_type_opt(hir_ty.hir_id); + if should_lint_ty(hir_ty, ty, self.self_ty); + then { + self.types_to_lint.push(hir_ty.hir_id); + } else { + self.types_to_skip.push(hir_ty.hir_id); + } + } + + walk_ty(self, hir_ty); + } + + fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { + if_chain! { + if let Some(ty) = self.cx.typeck_results().node_type_opt(inf.hir_id); + if should_lint_ty(&inf.to_ty(), ty, self.self_ty); + then { + self.types_to_lint.push(inf.hir_id); + } else { + self.types_to_skip.push(inf.hir_id); + } + } + + walk_inf(self, inf) + } + + fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> { + NestedVisitorMap::None + } +} + +>>>>>>> Add inferred args to typeck fn span_lint(cx: &LateContext<'_>, span: Span) { span_lint_and_sugg( cx, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 63737955f09..e636038b6e1 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -288,6 +288,8 @@ impl HirEqInterExpr<'_, '_, '_> { (GenericArg::Const(l), GenericArg::Const(r)) => self.eq_body(l.value.body, r.value.body), (GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => Self::eq_lifetime(l_lt, r_lt), (GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty), + (GenericArg::Infer(l_inf), GenericArg::Infer(r_inf)) => + self.eq_ty(&l_inf.to_ty(), &r_inf.to_ty()), _ => false, } } @@ -888,10 +890,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_tykind(&ty.kind); } - pub fn hash_infer(&mut self) { - "_".hash(&mut self.s); - } - pub fn hash_tykind(&mut self, ty: &TyKind<'_>) { match ty { TyKind::Slice(ty) => { @@ -957,7 +955,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { GenericArg::Lifetime(l) => self.hash_lifetime(l), GenericArg::Type(ref ty) => self.hash_ty(ty), GenericArg::Const(ref ca) => self.hash_body(ca.value.body), - GenericArg::Infer(ref _inf) => self.hash_infer(), + GenericArg::Infer(ref inf) => self.hash_ty(&inf.to_ty()), } } } diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 523d55219ab..e914dc1c222 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -180,7 +180,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { } // FIXME: Per https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/infer/at/struct.At.html#method.normalize -// this function can be removed once the `normalizie` method does not panic when normalization does +// this function can be removed once the `normalize` method does not panic when normalization does // not succeed /// Checks if `Ty` is normalizable. This function is useful /// to avoid crashes on `layout_of`. diff --git a/tests/ui/transmute_ptr_to_ref.stderr b/tests/ui/transmute_ptr_to_ref.stderr index df0598a58cd..54ab04f8c5d 100644 --- a/tests/ui/transmute_ptr_to_ref.stderr +++ b/tests/ui/transmute_ptr_to_ref.stderr @@ -46,13 +46,13 @@ error: transmute from a pointer type (`*const i32`) to a reference type (`&issue --> $DIR/transmute_ptr_to_ref.rs:32:32 | LL | let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<_>)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<u8>)` error: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<&u8>`) --> $DIR/transmute_ptr_to_ref.rs:34:33 | LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<&_>)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<&u8>)` error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`) --> $DIR/transmute_ptr_to_ref.rs:38:14 From 74379d4d85ad522f68ce2cb37a6a4c061b37ef82 Mon Sep 17 00:00:00 2001 From: kadmin <julianknodt@gmail.com> Date: Thu, 6 May 2021 15:33:44 +0000 Subject: [PATCH 3/3] Actually infer args in visitors --- clippy_lints/src/use_self.rs | 48 +--------------------------- clippy_utils/src/hir_utils.rs | 6 ++-- tests/ui/transmute_ptr_to_ref.stderr | 4 +-- 3 files changed, 6 insertions(+), 52 deletions(-) diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index c8cdf1a5d2c..d5ee717accd 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -9,7 +9,7 @@ use rustc_hir::{ def::{CtorOf, DefKind, Res}, def_id::LocalDefId, intravisit::{walk_ty, walk_inf, NestedVisitorMap, Visitor}, - Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Node, Path, PathSegment, + Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -280,52 +280,6 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector { } } -<<<<<<< HEAD -======= -struct LintTyCollector<'a, 'tcx> { - cx: &'a LateContext<'tcx>, - self_ty: Ty<'tcx>, - types_to_lint: Vec<HirId>, - types_to_skip: Vec<HirId>, -} - -impl<'a, 'tcx> Visitor<'tcx> for LintTyCollector<'a, 'tcx> { - type Map = Map<'tcx>; - - fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'_>) { - if_chain! { - if let Some(ty) = self.cx.typeck_results().node_type_opt(hir_ty.hir_id); - if should_lint_ty(hir_ty, ty, self.self_ty); - then { - self.types_to_lint.push(hir_ty.hir_id); - } else { - self.types_to_skip.push(hir_ty.hir_id); - } - } - - walk_ty(self, hir_ty); - } - - fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { - if_chain! { - if let Some(ty) = self.cx.typeck_results().node_type_opt(inf.hir_id); - if should_lint_ty(&inf.to_ty(), ty, self.self_ty); - then { - self.types_to_lint.push(inf.hir_id); - } else { - self.types_to_skip.push(inf.hir_id); - } - } - - walk_inf(self, inf) - } - - fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> { - NestedVisitorMap::None - } -} - ->>>>>>> Add inferred args to typeck fn span_lint(cx: &LateContext<'_>, span: Span) { span_lint_and_sugg( cx, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index e636038b6e1..6ea360a88a6 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -904,7 +904,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { mut_ty.mutbl.hash(&mut self.s); }, TyKind::Rptr(lifetime, ref mut_ty) => { - self.hash_lifetime(lifetime); + self.hash_lifetime(*lifetime); self.hash_ty(mut_ty.ty); mut_ty.mutbl.hash(&mut self.s); }, @@ -924,7 +924,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { bfn.decl.c_variadic.hash(&mut self.s); }, TyKind::Tup(ty_list) => { - for ty in ty_list { + for ty in *ty_list { self.hash_ty(ty); } }, @@ -933,7 +933,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_generic_args(arg_list); }, TyKind::TraitObject(_, lifetime, _) => { - self.hash_lifetime(lifetime); + self.hash_lifetime(*lifetime); }, TyKind::Typeof(anon_const) => { self.hash_body(anon_const.body); diff --git a/tests/ui/transmute_ptr_to_ref.stderr b/tests/ui/transmute_ptr_to_ref.stderr index 54ab04f8c5d..df0598a58cd 100644 --- a/tests/ui/transmute_ptr_to_ref.stderr +++ b/tests/ui/transmute_ptr_to_ref.stderr @@ -46,13 +46,13 @@ error: transmute from a pointer type (`*const i32`) to a reference type (`&issue --> $DIR/transmute_ptr_to_ref.rs:32:32 | LL | let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<u8>)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<_>)` error: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<&u8>`) --> $DIR/transmute_ptr_to_ref.rs:34:33 | LL | let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const issue1231::Foo<&u8>)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const Foo<&_>)` error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`) --> $DIR/transmute_ptr_to_ref.rs:38:14