about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkadmin <julianknodt@gmail.com>2021-05-06 15:33:44 +0000
committerkadmin <julianknodt@gmail.com>2021-07-26 21:15:18 +0000
commit8759f00c73641d44b3ab7a2290e3c58168d3e30f (patch)
treeb2d4cdbbaa0b84be96c03e068d0f1fa6539d4ec7
parent3605675bb1b4f1fb65f80585ded2b62aea15bf2c (diff)
Actually infer args in visitors
-rw-r--r--compiler/rustc_ast/src/ast.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs10
-rw-r--r--compiler/rustc_feature/src/active.rs3
-rw-r--r--compiler/rustc_hir/src/hir.rs49
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs7
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs27
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs6
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs5
-rw-r--r--compiler/rustc_typeck/src/check/method/confirm.rs5
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs3
-rw-r--r--src/test/ui/const-generics/issues/issue-62878.rs2
-rw-r--r--src/test/ui/const-generics/min_const_generics/inferred_const.rs1
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs13
-rw-r--r--src/test/ui/inference/infer-arg-test.rs24
-rw-r--r--src/test/ui/inference/infer-arg-test.stderr36
-rw-r--r--src/test/ui/object-lifetime-default-inferred.rs35
-rw-r--r--src/test/ui/parser/issue-14303-fncall.full.stderr9
-rw-r--r--src/test/ui/parser/issue-14303-fncall.generic_arg.stderr (renamed from src/test/ui/parser/issue-14303-fncall.stderr)2
-rw-r--r--src/test/ui/parser/issue-14303-fncall.rs8
-rw-r--r--src/test/ui/privacy/associated-item-privacy-trait.stderr2
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr (renamed from src/test/ui/span/issue-42234-unknown-receiver-type.stderr)4
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr21
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs48
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs6
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr4
30 files changed, 257 insertions, 97 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 5bffc94364d..8cab83707dc 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -336,6 +336,8 @@ pub enum ParamKindOrd {
     // is active. Specifically, if it's only `min_const_generics`, it will still require
     // ordering consts after types.
     Const { unordered: bool },
+    // `Infer` is not actually constructed directly from the AST, but is implicitly constructed
+    // during HIR lowering, and `ParamKindOrd` will implicitly order inferred variables last.
     Infer,
 }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index c7a477fedc6..a19a2fbbe74 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -51,7 +51,7 @@ use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
 use rustc_hir::def_id::{DefId, DefIdMap, DefPathHash, LocalDefId, CRATE_DEF_ID};
 use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
 use rustc_hir::intravisit;
-use rustc_hir::{ConstArg, GenericArg, ParamName};
+use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_session::lint::builtin::{BARE_TRAIT_OBJECTS, MISSING_ABI};
 use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
@@ -1219,9 +1219,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
             ast::GenericArg::Type(ty) => {
                 match ty.kind {
-                    TyKind::Infer => {
+                    TyKind::Infer if self.sess.features_untracked().generic_arg_infer => {
                         let hir_id = self.lower_node_id(ty.id);
-                        return GenericArg::Infer(hir::InferArg { hir_id, span: ty.span });
+                        return GenericArg::Infer(hir::InferArg {
+                            hir_id,
+                            span: ty.span,
+                            kind: InferKind::Type,
+                        });
                     }
                     // We parse const arguments as path types as we cannot distinguish them during
                     // parsing. We try to resolve that ambiguity by attempting resolution in both the
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index a3e40daf6bf..46bf49d640f 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -684,6 +684,9 @@ declare_features! (
     /// Allows `cfg(target_abi = "...")`.
     (active, cfg_target_abi, "1.55.0", Some(80970), None),
 
+    /// Infer generic args for both consts and types.
+    (active, generic_arg_infer, "1.55.0", Some(85077), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 140219287b1..4914280f5c8 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -253,9 +253,23 @@ pub struct ConstArg {
     pub span: Span,
 }
 
+#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
+pub enum InferKind {
+    Const,
+    Type,
+}
+
+impl InferKind {
+    #[inline]
+    pub fn is_type(self) -> bool {
+        matches!(self, InferKind::Type)
+    }
+}
+
 #[derive(Encodable, Debug, HashStable_Generic)]
 pub struct InferArg {
     pub hir_id: HirId,
+    pub kind: InferKind,
     pub span: Span,
 }
 
@@ -365,22 +379,29 @@ impl GenericArgs<'_> {
         panic!("GenericArgs::inputs: not a `Fn(T) -> U`");
     }
 
-    pub fn own_counts(&self) -> GenericParamCount {
-        // We could cache this as a property of `GenericParamCount`, but
-        // the aim is to refactor this away entirely eventually and the
-        // presence of this method will be a constant reminder.
-        let mut own_counts: GenericParamCount = Default::default();
+    #[inline]
+    pub fn has_type_params(&self) -> bool {
+        self.args.iter().any(|arg| matches!(arg, GenericArg::Type(_)))
+    }
 
-        for arg in self.args {
-            match arg {
-                GenericArg::Lifetime(_) => own_counts.lifetimes += 1,
-                GenericArg::Type(_) => own_counts.types += 1,
-                GenericArg::Const(_) => own_counts.consts += 1,
-                GenericArg::Infer(_) => own_counts.infer += 1,
-            };
-        }
+    #[inline]
+    pub fn num_type_params(&self) -> usize {
+        self.args.iter().filter(|arg| matches!(arg, GenericArg::Type(_))).count()
+    }
+
+    #[inline]
+    pub fn num_lifetime_params(&self) -> usize {
+        self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count()
+    }
 
-        own_counts
+    #[inline]
+    pub fn has_lifetime_params(&self) -> bool {
+        self.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
+    }
+
+    #[inline]
+    pub fn num_generic_params(&self) -> usize {
+        self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
     }
 
     /// The span encompassing the text inside the surrounding brackets.
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index d47bef4379c..94dd2116e16 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -103,7 +103,7 @@ impl<'a> State<'a> {
             Node::TraitRef(a) => self.print_trait_ref(&a),
             Node::Binding(a) | Node::Pat(a) => self.print_pat(&a),
             Node::Arm(a) => self.print_arm(&a),
-            Node::Infer(_) => self.print_string("_", ast::StrStyle::Cooked),
+            Node::Infer(_) => self.s.word("_"),
             Node::Block(a) => {
                 // Containing cbox, will be closed by print-block at `}`.
                 self.cbox(INDENT_UNIT);
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index e77bda7d4ab..cd91ecdf2ba 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1224,6 +1224,13 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
                 }
             }
         } else {
+            let local_id = self.tcx.hir().local_def_id(inf.hir_id);
+            if let Some(did) = self.tcx.opt_const_param_of(local_id) {
+                if self.visit_def_id(did, "inferred", &"").is_break() {
+                    return;
+                }
+            }
+
             // FIXME see above note for same issue.
             if self.visit(rustc_typeck::hir_ty_to_ty(self.tcx, &inf.to_ty())).is_break() {
                 return;
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 26e2efc2552..bf6d5542f62 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -2559,7 +2559,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 }
                 GenericArg::Infer(inf) => {
                     self.visit_id(inf.hir_id);
-                    i += 1;
+                    if inf.kind.is_type() {
+                        i += 1;
+                    }
                 }
             }
         }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index c0f63f40853..536ebdef426 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -622,6 +622,7 @@ symbols! {
         generator,
         generator_state,
         generators,
+        generic_arg_infer,
         generic_associated_types,
         generic_param_attrs,
         get_context,
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index dd15d2d65b9..eb6265dec89 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -39,11 +39,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         );
 
         if let GenericParamDefKind::Const { .. } = param.kind {
-            if matches!(
-                arg,
-                GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. }) | GenericArg::Infer(_)
-            ) {
+            if matches!(arg, GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. })) {
                 err.help("const arguments cannot yet be inferred with `_`");
+                if sess.is_nightly_build() {
+                    err.help(
+                        "add `#![feature(generic_arg_infer)]` to the crate attributes to enable",
+                    );
+                }
             }
         }
 
@@ -458,8 +460,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let default_counts = gen_params.own_defaults();
         let param_counts = gen_params.own_counts();
         let named_type_param_count = param_counts.types - has_self as usize;
-        let arg_counts = gen_args.own_counts();
-        let infer_lifetimes = gen_pos != GenericArgPosition::Type && arg_counts.lifetimes == 0;
+        let infer_lifetimes =
+            gen_pos != GenericArgPosition::Type && !gen_args.has_lifetime_params();
 
         if gen_pos != GenericArgPosition::Type && !gen_args.bindings.is_empty() {
             Self::prohibit_assoc_ty_binding(tcx, gen_args.bindings[0].span);
@@ -517,7 +519,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         let min_expected_lifetime_args = if infer_lifetimes { 0 } else { param_counts.lifetimes };
         let max_expected_lifetime_args = param_counts.lifetimes;
-        let num_provided_lifetime_args = arg_counts.lifetimes;
+        let num_provided_lifetime_args = gen_args.num_lifetime_params();
 
         let lifetimes_correct = check_lifetime_args(
             min_expected_lifetime_args,
@@ -588,14 +590,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     - default_counts.consts
             };
             debug!("expected_min: {:?}", expected_min);
-            debug!("arg_counts.lifetimes: {:?}", arg_counts.lifetimes);
+            debug!("arg_counts.lifetimes: {:?}", gen_args.num_lifetime_params());
 
             check_types_and_consts(
                 expected_min,
                 param_counts.consts + named_type_param_count,
-                arg_counts.consts + arg_counts.types + arg_counts.infer,
+                gen_args.num_generic_params(),
                 param_counts.lifetimes + has_self as usize,
-                arg_counts.lifetimes,
+                gen_args.num_lifetime_params(),
             )
         };
 
@@ -673,8 +675,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         position: GenericArgPosition,
     ) -> ExplicitLateBound {
         let param_counts = def.own_counts();
-        let arg_counts = args.own_counts();
-        let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
+        let infer_lifetimes = position != GenericArgPosition::Type && !args.has_lifetime_params();
 
         if infer_lifetimes {
             return ExplicitLateBound::No;
@@ -687,7 +688,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             let span = args.args[0].span();
 
             if position == GenericArgPosition::Value
-                && arg_counts.lifetimes != param_counts.lifetimes
+                && args.num_lifetime_params() != param_counts.lifetimes
             {
                 let mut err = tcx.sess.struct_span_err(span, msg);
                 err.span_note(span_late, note);
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 58ad086f225..03c4c5dfa0c 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -463,8 +463,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     }
                     (&GenericParamDefKind::Const { has_default }, hir::GenericArg::Infer(inf)) => {
                         if has_default {
-                            // FIXME(const_generics): Actually infer parameter here?
                             tcx.const_param_default(param.def_id).into()
+                        } else if self.astconv.allow_ty_infer() {
+                            // FIXME(const_generics): Actually infer parameter here?
+                            todo!()
                         } else {
                             self.inferred_params.push(inf.span);
                             tcx.ty_error().into()
@@ -1963,7 +1965,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         }
                         has_err = true;
                         err_for_ty = true;
-                        (inf.span, "inferred")
+                        (inf.span, "generic")
                     }
                 };
                 let mut err = struct_span_err!(
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 310517339cd..f5776ae7cf6 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -1480,10 +1480,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         self.fcx.const_arg_to_const(&ct.value, param.def_id).into()
                     }
                     (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
-                        self.fcx.to_ty(&inf.to_ty()).into()
+                        self.fcx.ty_infer(Some(param), inf.span).into()
                     }
                     (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
-                        self.fcx.var_for_def(inf.span, param)
+                        let tcx = self.fcx.tcx();
+                        self.fcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into()
                     }
                     _ => unreachable!(),
                 }
diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs
index 3224fe362cb..3aceaba882d 100644
--- a/compiler/rustc_typeck/src/check/method/confirm.rs
+++ b/compiler/rustc_typeck/src/check/method/confirm.rs
@@ -367,10 +367,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                         self.cfcx.const_arg_to_const(&ct.value, param.def_id).into()
                     }
                     (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => {
-                        self.cfcx.to_ty(&inf.to_ty()).into()
+                        self.cfcx.ty_infer(Some(param), inf.span).into()
                     }
                     (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
-                        self.cfcx.var_for_def(inf.span, param)
+                        let tcx = self.cfcx.tcx();
+                        self.cfcx.ct_infer(tcx.type_of(param.def_id), Some(param), inf.span).into()
                     }
                     _ => unreachable!(),
                 }
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 50e4ba4fe6c..96b3fa9aa01 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -20,6 +20,9 @@ use super::{bad_placeholder_type, is_suggestable_infer_ty};
 ///
 /// This should be called using the query `tcx.opt_const_param_of`.
 pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
+    // FIXME(generic_arg_infer): allow for returning DefIds of inference of
+    // GenericArg::Infer below. This may require a change where GenericArg::Infer has some flag
+    // for const or type.
     use hir::*;
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
 
diff --git a/src/test/ui/const-generics/issues/issue-62878.rs b/src/test/ui/const-generics/issues/issue-62878.rs
index fae57b37773..fb6257696b9 100644
--- a/src/test/ui/const-generics/issues/issue-62878.rs
+++ b/src/test/ui/const-generics/issues/issue-62878.rs
@@ -1,5 +1,5 @@
 // revisions: full min
-#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, feature(const_generics, generic_arg_infer))]
 #![cfg_attr(full, allow(incomplete_features))]
 
 fn foo<const N: usize, const A: [u8; N]>() {}
diff --git a/src/test/ui/const-generics/min_const_generics/inferred_const.rs b/src/test/ui/const-generics/min_const_generics/inferred_const.rs
index f5800d10971..57d6941587a 100644
--- a/src/test/ui/const-generics/min_const_generics/inferred_const.rs
+++ b/src/test/ui/const-generics/min_const_generics/inferred_const.rs
@@ -1,3 +1,4 @@
+#![feature(generic_arg_infer)]
 // run-pass
 
 fn foo<const N: usize, const K: usize>(_data: [u32; N]) -> [u32; K] {
diff --git a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
new file mode 100644
index 00000000000..c17f02d58f3
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
@@ -0,0 +1,12 @@
+error[E0747]: type provided when a constant was expected
+  --> $DIR/feature-gate-generic_arg_infer.rs:11:20
+   |
+LL |     let _x = foo::<_>([1,2]);
+   |                    ^
+   |
+   = help: const arguments cannot yet be inferred with `_`
+   = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs
new file mode 100644
index 00000000000..4729773b12e
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs
@@ -0,0 +1,13 @@
+// [feature] run-pass
+// revisions: normal feature
+
+#![cfg_attr(feature, feature(generic_arg_infer))]
+
+fn foo<const N: usize>(_: [u8; N]) -> [u8; N] {
+  [0; N]
+}
+
+fn main() {
+    let _x = foo::<_>([1,2]);
+    //[normal]~^ ERROR: type provided when a constant was expected
+}
diff --git a/src/test/ui/inference/infer-arg-test.rs b/src/test/ui/inference/infer-arg-test.rs
new file mode 100644
index 00000000000..1b67ccd6c43
--- /dev/null
+++ b/src/test/ui/inference/infer-arg-test.rs
@@ -0,0 +1,24 @@
+#![feature(generic_arg_infer)]
+
+struct All<'a, T, const N: usize> {
+  v: &'a T,
+}
+
+struct BadInfer<_>;
+//~^ ERROR expected identifier
+//~| ERROR parameter `_` is never used
+
+fn all_fn<'a, T, const N: usize>() {}
+
+fn bad_infer_fn<_>() {}
+//~^ ERROR expected identifier
+
+
+fn main() {
+  let a: All<_, _, _>;
+  all_fn();
+  let v: [u8; _];
+  //~^ ERROR in expressions
+  let v: [u8; 10] = [0; _];
+  //~^ ERROR in expressions
+}
diff --git a/src/test/ui/inference/infer-arg-test.stderr b/src/test/ui/inference/infer-arg-test.stderr
new file mode 100644
index 00000000000..30e171eac21
--- /dev/null
+++ b/src/test/ui/inference/infer-arg-test.stderr
@@ -0,0 +1,36 @@
+error: expected identifier, found reserved identifier `_`
+  --> $DIR/infer-arg-test.rs:7:17
+   |
+LL | struct BadInfer<_>;
+   |                 ^ expected identifier, found reserved identifier
+
+error: expected identifier, found reserved identifier `_`
+  --> $DIR/infer-arg-test.rs:13:17
+   |
+LL | fn bad_infer_fn<_>() {}
+   |                 ^ expected identifier, found reserved identifier
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+  --> $DIR/infer-arg-test.rs:20:15
+   |
+LL |   let v: [u8; _];
+   |               ^ `_` not allowed here
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+  --> $DIR/infer-arg-test.rs:22:25
+   |
+LL |   let v: [u8; 10] = [0; _];
+   |                         ^ `_` not allowed here
+
+error[E0392]: parameter `_` is never used
+  --> $DIR/infer-arg-test.rs:7:17
+   |
+LL | struct BadInfer<_>;
+   |                 ^ unused parameter
+   |
+   = help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `_` to be a const parameter, use `const _: usize` instead
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/object-lifetime-default-inferred.rs b/src/test/ui/object-lifetime-default-inferred.rs
new file mode 100644
index 00000000000..8a1156b8fc8
--- /dev/null
+++ b/src/test/ui/object-lifetime-default-inferred.rs
@@ -0,0 +1,35 @@
+// run-pass
+// Test that even with prior inferred parameters, object lifetimes of objects after are still
+// valid.
+
+// pretty-expanded FIXME #23616
+
+#![allow(dead_code)]
+#![feature(generic_arg_infer)]
+
+trait Test {
+    fn foo(&self) { }
+}
+
+struct Foo;
+impl Test for Foo {}
+
+struct SomeStruct<'a> {
+    t: &'a dyn Test,
+    u: &'a (dyn Test+'a),
+}
+
+fn a<'a, const N: usize>(_: [u8; N], t: &'a (dyn Test+'a), mut ss: SomeStruct<'a>) {
+    ss.t = t;
+}
+
+fn b<'a, T>(_: T, t: &'a (dyn Test+'a), mut ss: SomeStruct<'a>) {
+    ss.u = t;
+}
+
+fn main() {
+    // Inside a function body, we can just infer both
+    // lifetimes, to allow &'tmp (Display+'static).
+    a::<_>([], &Foo as &dyn Test, SomeStruct{t:&Foo,u:&Foo});
+    b::<_>(0u8, &Foo as &dyn Test, SomeStruct{t:&Foo,u:&Foo});
+}
diff --git a/src/test/ui/parser/issue-14303-fncall.full.stderr b/src/test/ui/parser/issue-14303-fncall.full.stderr
new file mode 100644
index 00000000000..02af61e8539
--- /dev/null
+++ b/src/test/ui/parser/issue-14303-fncall.full.stderr
@@ -0,0 +1,9 @@
+error[E0747]: type provided when a lifetime was expected
+  --> $DIR/issue-14303-fncall.rs:16:26
+   |
+LL |         .collect::<Vec<S<_, 'a>>>();
+   |                          ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/parser/issue-14303-fncall.stderr b/src/test/ui/parser/issue-14303-fncall.generic_arg.stderr
index a039eca0bfd..9f3359b3f68 100644
--- a/src/test/ui/parser/issue-14303-fncall.stderr
+++ b/src/test/ui/parser/issue-14303-fncall.generic_arg.stderr
@@ -1,5 +1,5 @@
 error[E0747]: inferred provided when a lifetime was expected
-  --> $DIR/issue-14303-fncall.rs:13:26
+  --> $DIR/issue-14303-fncall.rs:16:26
    |
 LL |         .collect::<Vec<S<_, 'a>>>();
    |                          ^
diff --git a/src/test/ui/parser/issue-14303-fncall.rs b/src/test/ui/parser/issue-14303-fncall.rs
index 1757baec70f..976a79a59b1 100644
--- a/src/test/ui/parser/issue-14303-fncall.rs
+++ b/src/test/ui/parser/issue-14303-fncall.rs
@@ -1,6 +1,9 @@
-// can't run rustfix because it doesn't handle multipart suggestions correctly
+// revisions: full generic_arg
 // compile-flags: -Zborrowck=mir
+// can't run rustfix because it doesn't handle multipart suggestions correctly
 // we need the above to avoid ast borrowck failure in recovered code
+#![cfg_attr(generic_arg, feature(generic_arg_infer))]
+
 
 struct S<'a, T> {
     a: &'a T,
@@ -11,7 +14,8 @@ fn foo<'a, 'b>(start: &'a usize, end: &'a usize) {
     let _x = (*start..*end)
         .map(|x| S { a: start, b: end })
         .collect::<Vec<S<_, 'a>>>();
-        //~^ ERROR inferred provided when a lifetime was expected
+        //[generic_arg]~^ ERROR inferred provided when a lifetime was expected
+        //[full]~^^ ERROR type provided when a lifetime was expected
 }
 
 fn main() {}
diff --git a/src/test/ui/privacy/associated-item-privacy-trait.stderr b/src/test/ui/privacy/associated-item-privacy-trait.stderr
index 85db42e9c13..3a42415e474 100644
--- a/src/test/ui/privacy/associated-item-privacy-trait.stderr
+++ b/src/test/ui/privacy/associated-item-privacy-trait.stderr
@@ -282,7 +282,7 @@ LL |         let _: <Pub as PubTr<_>>::AssocTy;
 LL |     priv_parent_substs::mac!();
    |     --------------------------- in this macro invocation
    |
-   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: type `priv_parent_substs::Priv` is private
   --> $DIR/associated-item-privacy-trait.rs:119:17
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr
index c64c5b1c28f..278d0492244 100644
--- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.full.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed for `Option<_>`
-  --> $DIR/issue-42234-unknown-receiver-type.rs:7:7
+  --> $DIR/issue-42234-unknown-receiver-type.rs:10:7
    |
 LL |     let x: Option<_> = None;
    |         - consider giving `x` the explicit type `Option<_>`, where the type parameter `T` is specified
@@ -9,7 +9,7 @@ LL |     x.unwrap().method_that_could_exist_on_some_type();
    = note: type must be known at this point
 
 error[E0282]: type annotations needed
-  --> $DIR/issue-42234-unknown-receiver-type.rs:13:10
+  --> $DIR/issue-42234-unknown-receiver-type.rs:16:10
    |
 LL |         .sum::<_>()
    |          ^^^ cannot infer type
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr
new file mode 100644
index 00000000000..8d4ed4aea6a
--- /dev/null
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr
@@ -0,0 +1,21 @@
+error[E0282]: type annotations needed for `Option<_>`
+  --> $DIR/issue-42234-unknown-receiver-type.rs:10:7
+   |
+LL |     let x: Option<_> = None;
+   |         - consider giving `x` the explicit type `Option<_>`, where the type parameter `T` is specified
+LL |     x.unwrap().method_that_could_exist_on_some_type();
+   |       ^^^^^^ cannot infer type for type parameter `T`
+   |
+   = note: type must be known at this point
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-42234-unknown-receiver-type.rs:16:16
+   |
+LL |         .sum::<_>()
+   |                ^ cannot infer type for type parameter `S` declared on the associated function `sum`
+   |
+   = note: type must be known at this point
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.rs b/src/test/ui/span/issue-42234-unknown-receiver-type.rs
index d3292bbecba..15b00de44b9 100644
--- a/src/test/ui/span/issue-42234-unknown-receiver-type.rs
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.rs
@@ -1,3 +1,6 @@
+// revisions: full generic_arg
+#![cfg_attr(generic_arg, feature(generic_arg_infer))]
+
 // When the type of a method call's receiver is unknown, the span should point
 // to the receiver (and not the entire call, as was previously the case before
 // the fix of which this tests).
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index c8cdf1a5d2c..d5ee717accd 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/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/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index e636038b6e1..6ea360a88a6 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/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/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
index 54ab04f8c5d..df0598a58cd 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
+++ b/src/tools/clippy/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