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