about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkadmin <julianknodt@gmail.com>2022-01-08 09:28:12 +0000
committerkadmin <julianknodt@gmail.com>2022-01-17 17:44:56 +0000
commit67f56671d0384bdb2d92dddebfbf42510b16e0f7 (patch)
tree40e044743da8fab20f86e317f65f1276e78343c5
parentfb57b7518d207caa99bdd99f4dab2a7d3902a83a (diff)
downloadrust-67f56671d0384bdb2d92dddebfbf42510b16e0f7.tar.gz
rust-67f56671d0384bdb2d92dddebfbf42510b16e0f7.zip
Use Term in ProjectionPredicate
ProjectionPredicate should be able to handle both associated types and consts so this adds the
first step of that. It mainly just pipes types all the way down, not entirely sure how to handle
consts, but hopefully that'll come with time.
-rw-r--r--Cargo.lock54
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs13
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs5
-rw-r--r--compiler/rustc_hir/src/hir.rs28
-rw-r--r--compiler/rustc_hir/src/intravisit.rs10
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs13
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs5
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs12
-rw-r--r--compiler/rustc_infer/src/infer/projection.rs3
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs9
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs51
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs9
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs13
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs18
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs11
-rw-r--r--compiler/rustc_parse/src/parser/path.rs12
-rw-r--r--compiler/rustc_privacy/src/lib.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/relationships.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs4
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs4
-rw-r--r--compiler/rustc_typeck/src/astconv/errors.rs8
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs37
-rw-r--r--compiler/rustc_typeck/src/bounds.rs25
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs4
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs2
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs6
-rw-r--r--compiler/rustc_typeck/src/collect.rs6
-rw-r--r--compiler/rustc_typeck/src/collect/item_bounds.rs6
-rw-r--r--compiler/rustc_typeck/src/constrained_generic_params.rs2
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs2
-rw-r--r--src/librustdoc/clean/mod.rs18
m---------src/llvm-project0
-rw-r--r--src/test/ui/associated-consts/assoc-const.rs5
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs2
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr22
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013.rs2
-rw-r--r--src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr22
-rw-r--r--src/test/ui/parser/recover-assoc-const-constraint.rs6
-rw-r--r--src/test/ui/parser/recover-assoc-const-constraint.stderr20
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs4
m---------src/tools/rust-analyzer36
51 files changed, 287 insertions, 276 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 18b85103202..529e17b158f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -335,7 +335,7 @@ dependencies = [
  "cargo-test-macro",
  "cargo-test-support",
  "cargo-util",
- "clap 3.0.6",
+ "clap",
  "crates-io",
  "crossbeam-utils",
  "curl",
@@ -615,29 +615,14 @@ dependencies = [
  "ansi_term 0.12.1",
  "atty",
  "bitflags",
- "strsim 0.8.0",
- "textwrap 0.11.0",
+ "strsim",
+ "textwrap",
  "unicode-width",
  "vec_map",
  "yaml-rust 0.3.5",
 ]
 
 [[package]]
-name = "clap"
-version = "3.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1957aa4a5fb388f0a0a73ce7556c5b42025b874e5cdc2c670775e346e97adec0"
-dependencies = [
- "atty",
- "bitflags",
- "indexmap",
- "os_str_bytes",
- "strsim 0.10.0",
- "termcolor",
- "textwrap 0.14.2",
-]
-
-[[package]]
 name = "clippy"
 version = "0.1.60"
 dependencies = [
@@ -669,7 +654,7 @@ version = "0.0.1"
 dependencies = [
  "bytecount",
  "cargo_metadata 0.14.0",
- "clap 2.34.0",
+ "clap",
  "indoc",
  "itertools 0.10.1",
  "opener",
@@ -1751,7 +1736,7 @@ name = "installer"
 version = "0.0.0"
 dependencies = [
  "anyhow",
- "clap 2.34.0",
+ "clap",
  "flate2",
  "lazy_static",
  "num_cpus",
@@ -2190,7 +2175,7 @@ dependencies = [
  "ammonia",
  "anyhow",
  "chrono",
- "clap 2.34.0",
+ "clap",
  "elasticlunr-rs",
  "env_logger 0.7.1",
  "handlebars",
@@ -2522,15 +2507,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "os_str_bytes"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
-dependencies = [
- "memchr",
-]
-
-[[package]]
 name = "output_vt100"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2934,7 +2910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b0b4b5faaf07040474e8af74a9e19ff167d5d204df5db5c5c765edecfb900358"
 dependencies = [
  "bitflags",
- "clap 2.34.0",
+ "clap",
  "derive_more",
  "env_logger 0.7.1",
  "humantime 2.0.1",
@@ -3282,7 +3258,7 @@ dependencies = [
 name = "rustbook"
 version = "0.1.0"
 dependencies = [
- "clap 2.34.0",
+ "clap",
  "env_logger 0.7.1",
  "mdbook",
 ]
@@ -4899,18 +4875,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
 
 [[package]]
-name = "strsim"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-
-[[package]]
 name = "structopt"
 version = "0.3.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
 dependencies = [
- "clap 2.34.0",
+ "clap",
  "lazy_static",
  "structopt-derive",
 ]
@@ -5082,12 +5052,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "textwrap"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
-
-[[package]]
 name = "thiserror"
 version = "1.0.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 9a8a097ee24..b2965774e2a 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -997,10 +997,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         };
 
         let kind = match constraint.kind {
-            AssocConstraintKind::Equality { ref term } => match term {
-                Term::Ty(ref ty) => hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) },
-                Term::Const(ref c) => hir::TypeBindingKind::Const { c: self.lower_anon_const(c) },
-            },
+            AssocConstraintKind::Equality { ref term } => {
+                let term = match term {
+                    Term::Ty(ref ty) => self.lower_ty(ty, itctx).into(),
+                    Term::Const(ref c) => self.lower_anon_const(c).into(),
+                };
+                hir::TypeBindingKind::Equality { term }
+            }
             AssocConstraintKind::Bound { ref bounds } => {
                 let mut capturable_lifetimes;
                 let mut parent_def_id = self.current_hir_id_owner;
@@ -1079,7 +1082,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             itctx,
                         );
 
-                        hir::TypeBindingKind::Equality { ty }
+                        hir::TypeBindingKind::Equality { term: ty.into() }
                     })
                 } else {
                     // Desugar `AssocTy: Bounds` into a type binding where the
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 46928a18465..79262235cd9 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -420,7 +420,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         ty: &'hir hir::Ty<'hir>,
     ) -> hir::TypeBinding<'hir> {
         let ident = Ident::with_dummy_span(hir::FN_OUTPUT_NAME);
-        let kind = hir::TypeBindingKind::Equality { ty };
+        let kind = hir::TypeBindingKind::Equality { term: ty.into() };
         let args = arena_vec![self;];
         let bindings = arena_vec![self;];
         let gen_args = self.arena.alloc(hir::GenericArgs {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 3c45b5790fb..17941058ed6 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -964,9 +964,7 @@ impl<'a> State<'a> {
                     Term::Const(c) => self.print_expr_anon_const(c),
                 }
             }
-            ast::AssocConstraintKind::Bound { bounds } => {
-                self.print_type_bounds(":", &*bounds);
-            }
+            ast::AssocConstraintKind::Bound { bounds } => self.print_type_bounds(":", &*bounds),
         }
     }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 9aa58f05a8e..01cc72121c7 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -779,7 +779,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                                     [
                                         hir::TypeBinding {
                                             ident: Ident { name: sym::Output, .. },
-                                            kind: hir::TypeBindingKind::Equality { ty },
+                                            kind:
+                                                hir::TypeBindingKind::Equality {
+                                                    term: hir::Term::Ty(ty),
+                                                },
                                             ..
                                         },
                                     ],
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 039bb0db0aa..43aa0ae265a 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -377,7 +377,7 @@ impl GenericArgs<'_> {
             GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err),
             _ => false,
         }) || self.bindings.iter().any(|arg| match arg.kind {
-            TypeBindingKind::Equality { ty } => matches!(ty.kind, TyKind::Err),
+            TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err),
             _ => false,
         })
     }
@@ -2129,21 +2129,37 @@ pub struct TypeBinding<'hir> {
     pub span: Span,
 }
 
+#[derive(Debug, HashStable_Generic)]
+pub enum Term<'hir> {
+    Ty(&'hir Ty<'hir>),
+    Const(AnonConst),
+}
+
+impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
+    fn from(ty: &'hir Ty<'hir>) -> Self {
+        Term::Ty(ty)
+    }
+}
+
+impl<'hir> From<AnonConst> for Term<'hir> {
+    fn from(c: AnonConst) -> Self {
+        Term::Const(c)
+    }
+}
+
 // Represents the two kinds of type bindings.
 #[derive(Debug, HashStable_Generic)]
 pub enum TypeBindingKind<'hir> {
     /// E.g., `Foo<Bar: Send>`.
     Constraint { bounds: &'hir [GenericBound<'hir>] },
-    /// E.g., `Foo<Bar = ()>`.
-    Equality { ty: &'hir Ty<'hir> },
-    /// E.g., `Foo<N = 3>`.
-    Const { c: AnonConst },
+    /// E.g., `Foo<Bar = ()>`, `Foo<Bar = ()>`
+    Equality { term: Term<'hir> },
 }
 
 impl TypeBinding<'_> {
     pub fn ty(&self) -> &Ty<'_> {
         match self.kind {
-            TypeBindingKind::Equality { ref ty } => ty,
+            TypeBindingKind::Equality { term: Term::Ty(ref ty) } => ty,
             _ => panic!("expected equality type binding for parenthesized generic args"),
         }
     }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 56b32cde9d5..a219dad7b3d 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -827,11 +827,11 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
     visitor.visit_ident(type_binding.ident);
     visitor.visit_generic_args(type_binding.span, type_binding.gen_args);
     match type_binding.kind {
-        TypeBindingKind::Equality { ref ty } => visitor.visit_ty(ty),
-        TypeBindingKind::Const { ref c } => visitor.visit_anon_const(c),
-        TypeBindingKind::Constraint { bounds } => {
-            walk_list!(visitor, visit_param_bound, bounds);
-        }
+        TypeBindingKind::Equality { ref term } => match term {
+            Term::Ty(ref ty) => visitor.visit_ty(ty),
+            Term::Const(ref c) => visitor.visit_anon_const(c),
+        },
+        TypeBindingKind::Constraint { bounds } => walk_list!(visitor, visit_param_bound, bounds),
     }
 }
 
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index a76af35a8e6..a301c5e3456 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -6,7 +6,7 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
 use rustc_ast_pretty::pp::{self, Breaks};
 use rustc_ast_pretty::pprust::{Comments, PrintState};
 use rustc_hir as hir;
-use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node};
+use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node, Term};
 use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
 use rustc_span::source_map::{SourceMap, Spanned};
 use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
@@ -1752,13 +1752,12 @@ impl<'a> State<'a> {
                 self.print_generic_args(binding.gen_args, false, false);
                 self.space();
                 match generic_args.bindings[0].kind {
-                    hir::TypeBindingKind::Equality { ref ty } => {
+                    hir::TypeBindingKind::Equality { ref term } => {
                         self.word_space("=");
-                        self.print_type(ty);
-                    }
-                    hir::TypeBindingKind::Const { ref c } => {
-                        self.word_space("=");
-                        self.print_anon_const(c);
+                        match term {
+                            Term::Ty(ref ty) => self.print_type(ty),
+                            Term::Const(ref c) => self.print_anon_const(c),
+                        }
                     }
                     hir::TypeBindingKind::Constraint { bounds } => {
                         self.print_bounds(":", bounds);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 6e6012fdc1a..f1e99faba01 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -69,7 +69,7 @@ use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{
     self,
     subst::{GenericArgKind, Subst, SubstsRef},
-    Region, Ty, TyCtxt, TypeFoldable,
+    Region, Term, Ty, TyCtxt, TypeFoldable,
 };
 use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
 use rustc_target::spec::abi;
@@ -1780,7 +1780,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 {
                     if projection_predicate.projection_ty.item_def_id == item_def_id {
                         // We don't account for multiple `Future::Output = Ty` contraints.
-                        return Some(projection_predicate.ty);
+                        match projection_predicate.term {
+                            Term::Ty(ty) => return Some(ty),
+                            // Can return None, but not sure if that makes sense?
+                            Term::Const(_c) => todo!(),
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
index 04eceecc5f0..3fa71d1a3d8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
@@ -122,8 +122,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                             {
                                 for type_binding in generic_args.bindings.iter() {
                                     if type_binding.ident.name == rustc_span::sym::Output {
-                                        if let hir::TypeBindingKind::Equality { ty } =
-                                            type_binding.kind
+                                        if let hir::TypeBindingKind::Equality {
+                                            term: hir::Term::Ty(ty),
+                                        } = type_binding.kind
                                         {
                                             return Some(ty);
                                         }
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 8894093c66c..39339da9a0b 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -7,7 +7,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::subst::{GenericArgKind, Subst};
-use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor};
+use rustc_middle::ty::{self, OpaqueTypeKey, Term, Ty, TyCtxt, TypeFoldable, TypeVisitor};
 use rustc_span::Span;
 
 use std::ops::ControlFlow;
@@ -584,9 +584,13 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
             debug!(?predicate);
 
             if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
-                if projection.ty.references_error() {
-                    // No point on adding these obligations since there's a type error involved.
-                    return tcx.ty_error();
+                if let Term::Ty(ty) = projection.term {
+                    if ty.references_error() {
+                        // No point on adding these obligations since there's a type error involved.
+                        return tcx.ty_error();
+                    }
+                } else {
+                    todo!();
                 }
             }
 
diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs
index 9b53ab72b00..b45a6514d79 100644
--- a/compiler/rustc_infer/src/infer/projection.rs
+++ b/compiler/rustc_infer/src/infer/projection.rs
@@ -26,7 +26,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             kind: TypeVariableOriginKind::NormalizeProjectionType,
             span: self.tcx.def_span(def_id),
         });
-        let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var });
+        let projection =
+            ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, term: ty_var.into() });
         let obligation = Obligation::with_depth(
             cause,
             recursion_depth,
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index b6e673983fd..74c8d7b7777 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -1,5 +1,5 @@
 use crate::ty::subst::{GenericArg, GenericArgKind};
-use crate::ty::{self, InferConst, Ty, TypeFlags};
+use crate::ty::{self, InferConst, Term, Ty, TypeFlags};
 use std::slice;
 
 #[derive(Debug)]
@@ -241,9 +241,12 @@ impl FlagComputation {
                 self.add_ty(a);
                 self.add_ty(b);
             }
-            ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
+            ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
                 self.add_projection_ty(projection_ty);
-                self.add_ty(ty);
+                match term {
+                    Term::Ty(ty) => self.add_ty(ty),
+                    Term::Const(_c) => todo!(),
+                }
             }
             ty::PredicateKind::WellFormed(arg) => {
                 self.add_substs(slice::from_ref(&arg));
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 72e4e26dd3e..f1851150e38 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -484,7 +484,7 @@ crate struct PredicateInner<'tcx> {
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(PredicateInner<'_>, 48);
+static_assert_size!(PredicateInner<'_>, 56);
 
 #[derive(Clone, Copy, Lift)]
 pub struct Predicate<'tcx> {
@@ -795,11 +795,35 @@ pub struct CoercePredicate<'tcx> {
 }
 pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
 
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
+#[derive(HashStable, TypeFoldable)]
+pub enum Term<'tcx> {
+    Ty(Ty<'tcx>),
+    Const(&'tcx Const<'tcx>),
+}
+
+impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
+    fn from(ty: Ty<'tcx>) -> Self {
+        Term::Ty(ty)
+    }
+}
+
+impl<'tcx> From<&'tcx Const<'tcx>> for Term<'tcx> {
+    fn from(c: &'tcx Const<'tcx>) -> Self {
+        Term::Const(c)
+    }
+}
+
+impl<'tcx> Term<'tcx> {
+    pub fn ty(&self) -> Ty<'tcx> {
+        if let Term::Ty(ty) = self { ty } else { panic!("Expected type") }
+    }
+}
+
 /// This kind of predicate has no *direct* correspondent in the
 /// syntax, but it roughly corresponds to the syntactic forms:
 ///
 /// 1. `T: TraitRef<..., Item = Type>`
-/// - Or `T: TraitRef<..., Item = Const>`
 /// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
 ///
 /// In particular, form #1 is "desugared" to the combination of a
@@ -812,26 +836,7 @@ pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
 #[derive(HashStable, TypeFoldable)]
 pub struct ProjectionPredicate<'tcx> {
     pub projection_ty: ProjectionTy<'tcx>,
-    pub ty: Ty<'tcx>,
-}
-
-/// This kind of predicate has no *direct* correspondent in the
-/// syntax, but it roughly corresponds to the syntactic forms:
-///
-/// 1. `T: TraitRef<..., Item = Const>`
-/// 2. `<T as TraitRef<...>>::Item == Const` (NYI)
-///
-/// In particular, form #1 is "desugared" to the combination of a
-/// normal trait predicate (`T: TraitRef<...>`) and one of these
-/// predicates. Form #2 is a broader form in that it also permits
-/// equality between arbitrary types. Processing an instance of
-/// Form #2 eventually yields one of these `ProjectionPredicate`
-/// instances to normalize the LHS.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug)]
-#[derive(HashStable, TypeFoldable)]
-pub struct ConstPredicate<'tcx> {
-    pub projection: ProjectionTy<'tcx>,
-    pub c: &'tcx Const<'tcx>,
+    pub term: Term<'tcx>,
 }
 
 pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;
@@ -857,7 +862,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
     }
 
     pub fn ty(&self) -> Binder<'tcx, Ty<'tcx>> {
-        self.map_bound(|predicate| predicate.ty)
+        self.map_bound(|predicate| if let Term::Ty(ty) = predicate.term { ty } else { todo!() })
     }
 
     /// The `DefId` of the `TraitItem` for the associated type.
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 94cd650e39e..8c07f154637 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2499,7 +2499,14 @@ define_print_and_forward_display! {
     }
 
     ty::ProjectionPredicate<'tcx> {
-        p!(print(self.projection_ty), " == ", print(self.ty))
+        p!(print(self.projection_ty), " == ", print(self.term))
+    }
+
+    ty::Term<'tcx> {
+      match self {
+        ty::Term::Ty(ty) => p!(print(ty)),
+        ty::Term::Const(c) => p!(print(c)),
+      }
     }
 
     ty::ProjectionTy<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 9e381cabdfe..851c4592f4f 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -7,7 +7,7 @@
 use crate::mir::interpret::{get_slice_bytes, ConstValue, GlobalAlloc, Scalar};
 use crate::ty::error::{ExpectedFound, TypeError};
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
-use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, Term, Ty, TyCtxt, TypeFoldable};
 use rustc_hir as ast;
 use rustc_hir::def_id::DefId;
 use rustc_span::DUMMY_SP;
@@ -839,10 +839,13 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
         a: ty::ProjectionPredicate<'tcx>,
         b: ty::ProjectionPredicate<'tcx>,
     ) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
-        Ok(ty::ProjectionPredicate {
-            projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
-            ty: relation.relate(a.ty, b.ty)?,
-        })
+        match (a.term, b.term) {
+            (Term::Ty(a_ty), Term::Ty(b_ty)) => Ok(ty::ProjectionPredicate {
+                projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
+                term: relation.relate(a_ty, b_ty)?.into(),
+            }),
+            _ => todo!(),
+        }
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index a27169d59e1..3cbea92ae67 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -6,7 +6,7 @@ use crate::mir::interpret;
 use crate::mir::ProjectionKind;
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor};
 use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
-use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
+use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt};
 use rustc_data_structures::functor::IdFunctor;
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::CRATE_DEF_INDEX;
@@ -158,7 +158,7 @@ impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
 
 impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty)
+        write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term)
     }
 }
 
@@ -356,6 +356,16 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
     }
 }
 
+impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
+    type Lifted = ty::Term<'tcx>;
+    fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
+        Some(match self {
+            Term::Ty(ty) => Term::Ty(tcx.lift(ty)?),
+            Term::Const(c) => Term::Const(tcx.lift(c)?),
+        })
+    }
+}
+
 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
     type Lifted = ty::TraitPredicate<'tcx>;
     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
@@ -403,8 +413,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
     type Lifted = ty::ProjectionPredicate<'tcx>;
     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
-        tcx.lift((self.projection_ty, self.ty))
-            .map(|(projection_ty, ty)| ty::ProjectionPredicate { projection_ty, ty })
+        tcx.lift((self.projection_ty, self.term))
+            .map(|(projection_ty, term)| ty::ProjectionPredicate { projection_ty, term })
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 92fb7612688..50d0862905b 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -8,7 +8,7 @@ use crate::infer::canonical::Canonical;
 use crate::ty::fold::ValidateBoundVars;
 use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
 use crate::ty::InferTy::{self, *};
-use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable};
+use crate::ty::{self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable};
 use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
 use polonius_engine::Atom;
 use rustc_data_structures::captures::Captures;
@@ -1570,7 +1570,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
                 item_def_id: self.item_def_id,
                 substs: tcx.mk_substs_trait(self_ty, self.substs),
             },
-            ty: self.ty,
+            term: self.ty.into(),
         }
     }
 
@@ -1580,11 +1580,16 @@ impl<'tcx> ExistentialProjection<'tcx> {
     ) -> Self {
         // Assert there is a Self.
         projection_predicate.projection_ty.substs.type_at(0);
+        let ty = if let Term::Ty(ty) = projection_predicate.term {
+            ty
+        } else {
+            todo!();
+        };
 
         Self {
             item_def_id: projection_predicate.projection_ty.item_def_id,
             substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
-            ty: projection_predicate.ty,
+            ty,
         }
     }
 }
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 8f272820015..531cac1f57e 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -503,17 +503,15 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, AssocConstraintKind> {
         let arg = self.parse_generic_arg(None)?;
         let span = ident.span.to(self.prev_token.span);
-        let ty = match arg {
-            Some(GenericArg::Type(ty)) => ty,
-            Some(GenericArg::Const(c)) => {
-                return Ok(AssocConstraintKind::Equality { term: c.into() });
-            }
+        let term = match arg {
+            Some(GenericArg::Type(ty)) => ty.into(),
+            Some(GenericArg::Const(c)) => c.into(),
             Some(GenericArg::Lifetime(lt)) => {
                 self.struct_span_err(span, "associated lifetimes are not supported")
                     .span_label(lt.ident.span, "the lifetime is given here")
                     .help("if you meant to specify a trait object, write `dyn Trait + 'lifetime`")
                     .emit();
-                self.mk_ty(span, ast::TyKind::Err)
+                self.mk_ty(span, ast::TyKind::Err).into()
             }
             None => {
                 let after_eq = eq.shrink_to_hi();
@@ -542,7 +540,7 @@ impl<'a> Parser<'a> {
                 return Err(err);
             }
         };
-        Ok(AssocConstraintKind::Equality { term: ty.into() })
+        Ok(AssocConstraintKind::Equality { term })
     }
 
     /// We do not permit arbitrary expressions as const arguments. They must be one of:
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 7577b77181a..dc432905b1c 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -127,7 +127,8 @@ where
                 constness: _,
                 polarity: _,
             }) => self.visit_trait(trait_ref),
-            ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
+            ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
+                let ty = term.ty();
                 ty.visit_with(self)?;
                 self.visit_projection_ty(projection_ty)
             }
@@ -1185,7 +1186,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
             }
 
             for (poly_predicate, _) in bounds.projection_bounds {
-                if self.visit(poly_predicate.skip_binder().ty).is_break()
+                if self.visit(poly_predicate.skip_binder().term.ty()).is_break()
                     || self
                         .visit_projection_ty(poly_predicate.skip_binder().projection_ty)
                         .is_break()
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index b4d297a03ef..85135383b80 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1304,7 +1304,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
 
                 debug!(
                     "report_projection_error normalized_ty={:?} data.ty={:?}",
-                    normalized_ty, data.ty
+                    normalized_ty,
+                    data.term.ty()
                 );
 
                 let is_normalized_ty_expected = !matches!(
@@ -1318,12 +1319,12 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                 if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
                     is_normalized_ty_expected,
                     normalized_ty,
-                    data.ty,
+                    data.term.ty(),
                 ) {
                     values = Some(infer::ValuePairs::Types(ExpectedFound::new(
                         is_normalized_ty_expected,
                         normalized_ty,
-                        data.ty,
+                        data.term.ty(),
                     )));
 
                     err_buf = error;
@@ -1803,7 +1804,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
             }
             ty::PredicateKind::Projection(data) => {
                 let self_ty = data.projection_ty.self_ty();
-                let ty = data.ty;
+                let ty = data.term.ty();
                 if predicate.references_error() || self.is_tainted_by_errors() {
                     return;
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 577b96f3a40..4995590baec 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -214,7 +214,7 @@ fn project_and_unify_type<'cx, 'tcx>(
     let infcx = selcx.infcx();
     match infcx
         .at(&obligation.cause, obligation.param_env)
-        .eq(normalized_ty, obligation.predicate.ty)
+        .eq(normalized_ty, obligation.predicate.term.ty())
     {
         Ok(InferOk { obligations: inferred_obligations, value: () }) => {
             obligations.extend(inferred_obligations);
@@ -1615,7 +1615,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
                 substs: trait_ref.substs,
                 item_def_id: obligation.predicate.item_def_id,
             },
-            ty,
+            term: ty.into(),
         }
     });
 
@@ -1641,7 +1641,7 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
 
     let predicate = ty::ProjectionPredicate {
         projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
-        ty: self_ty.discriminant_ty(tcx),
+        term: self_ty.discriminant_ty(tcx).into(),
     };
 
     // We get here from `poly_project_and_unify_type` which replaces bound vars
@@ -1674,7 +1674,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
 
     let predicate = ty::ProjectionPredicate {
         projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
-        ty: metadata_ty,
+        term: metadata_ty.into(),
     };
 
     confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
@@ -1747,7 +1747,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
             substs: trait_ref.substs,
             item_def_id: fn_once_output_def_id,
         },
-        ty: ret_type,
+        term: ret_type.into(),
     });
 
     confirm_param_env_candidate(selcx, obligation, predicate, true)
@@ -1803,7 +1803,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
         Ok(InferOk { value: _, obligations }) => {
             nested_obligations.extend(obligations);
             assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
-            Progress { ty: cache_entry.ty, obligations: nested_obligations }
+            Progress { ty: cache_entry.term.ty(), obligations: nested_obligations }
         }
         Err(e) => {
             let msg = format!(
diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs
index e0098cc92d5..acac76cdfaa 100644
--- a/compiler/rustc_trait_selection/src/traits/relationships.rs
+++ b/compiler/rustc_trait_selection/src/traits/relationships.rs
@@ -62,7 +62,7 @@ pub(crate) fn update<'tcx, T>(
     if let ty::PredicateKind::Projection(predicate) = obligation.predicate.kind().skip_binder() {
         // If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
         // we need to make it into one.
-        if let Some(vid) = predicate.ty.ty_vid() {
+        if let Some(vid) = predicate.term.ty().ty_vid() {
             debug!("relationship: {:?}.output = true", vid);
             engine.relationships().entry(vid).or_default().output = true;
         }
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index f6e98f42710..e3b366c65bf 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -116,7 +116,7 @@ pub fn predicate_obligations<'a, 'tcx>(
         }
         ty::PredicateKind::Projection(t) => {
             wf.compute_projection(t.projection_ty);
-            wf.compute(t.ty.into());
+            wf.compute(t.term.ty().into());
         }
         ty::PredicateKind::WellFormed(arg) => {
             wf.compute(arg);
@@ -219,7 +219,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
             // projection coming from another associated type. See
             // `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
             // `traits-assoc-type-in-supertrait-bad.rs`.
-            if let ty::Projection(projection_ty) = proj.ty.kind() {
+            if let ty::Projection(projection_ty) = proj.term.ty().kind() {
                 if let Some(&impl_item_id) =
                     tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_id)
                 {
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 36c536c0ba3..e651ff63c52 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -227,7 +227,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq<RustInterner<'tcx>>>
 {
     fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::AliasEq<RustInterner<'tcx>> {
         chalk_ir::AliasEq {
-            ty: self.ty.lower_into(interner),
+            ty: self.term.ty().lower_into(interner),
             alias: self.projection_ty.lower_into(interner),
         }
     }
@@ -787,7 +787,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>
             trait_bound: trait_ref.lower_into(interner),
             associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.item_def_id),
             parameters: own_substs.iter().map(|arg| arg.lower_into(interner)).collect(),
-            value: self.ty.lower_into(interner),
+            value: self.term.ty().lower_into(interner),
         }
     }
 }
diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs
index 1f99a9b0536..b532c41642c 100644
--- a/compiler/rustc_typeck/src/astconv/errors.rs
+++ b/compiler/rustc_typeck/src/astconv/errors.rs
@@ -151,8 +151,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     .bindings
                     .iter()
                     .find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
-                        (true, hir::TypeBindingKind::Equality { ty }) => {
-                            sess.source_map().span_to_snippet(ty.span).ok()
+                        (true, hir::TypeBindingKind::Equality { term }) => {
+                            let span = match term {
+                                hir::Term::Ty(ty) => ty.span,
+                                hir::Term::Const(c) => self.tcx().hir().span(c.hir_id),
+                            };
+                            sess.source_map().span_to_snippet(span).ok()
                         }
                         _ => None,
                     })
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 2d847f6145d..2866a7884a7 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -602,14 +602,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             .iter()
             .map(|binding| {
                 let kind = match binding.kind {
-                    hir::TypeBindingKind::Equality { ty } => {
-                        ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty))
-                    }
-                    hir::TypeBindingKind::Const { ref c } => {
-                        let local_did = self.tcx().hir().local_def_id(c.hir_id);
-                        let c = Const::from_anon_const(self.tcx(), local_did);
-                        ConvertedBindingKind::Const(&c)
-                    }
+                    hir::TypeBindingKind::Equality { ref term } => match term {
+                        hir::Term::Ty(ref ty) => {
+                            ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty))
+                        }
+                        hir::Term::Const(ref c) => {
+                            let local_did = self.tcx().hir().local_def_id(c.hir_id);
+                            let c = Const::from_anon_const(self.tcx(), local_did);
+                            ConvertedBindingKind::Const(&c)
+                        }
+                    },
                     hir::TypeBindingKind::Constraint { ref bounds } => {
                         ConvertedBindingKind::Constraint(bounds)
                     }
@@ -1227,21 +1229,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 //
                 // `<T as Iterator>::Item = u32`
                 bounds.projection_bounds.push((
-                    projection_ty.map_bound(|projection_ty| {
-                        debug!(
-                            "add_predicates_for_ast_type_binding: projection_ty {:?}, substs: {:?}",
-                            projection_ty, projection_ty.substs
-                        );
-                        ty::ProjectionPredicate { projection_ty, ty }
+                    projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
+                        projection_ty,
+                        term: ty.into(),
                     }),
                     binding.span,
                 ));
             }
             ConvertedBindingKind::Const(c) => {
-                bounds.const_bounds.push((
-                    projection_ty.map_bound(|projection_ty| ty::ConstPredicate {
-                        projection: projection_ty,
-                        c,
+                bounds.projection_bounds.push((
+                    projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
+                        projection_ty,
+                        term: c.into(),
                     }),
                     binding.span,
                 ));
@@ -1393,7 +1392,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         // A `Self` within the original bound will be substituted with a
                         // `trait_object_dummy_self`, so check for that.
                         let references_self =
-                            pred.skip_binder().ty.walk().any(|arg| arg == dummy_self.into());
+                            pred.skip_binder().term.ty().walk().any(|arg| arg == dummy_self.into());
 
                         // If the projection output contains `Self`, force the user to
                         // elaborate it explicitly to avoid a lot of complexity.
diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs
index 47c3ea54575..6a28bb16a20 100644
--- a/compiler/rustc_typeck/src/bounds.rs
+++ b/compiler/rustc_typeck/src/bounds.rs
@@ -37,12 +37,6 @@ pub struct Bounds<'tcx> {
     /// here.
     pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>,
 
-    /// A list of const equality bounds. So if you had `T:
-    /// Iterator<N = 4>` this would include `<T as
-    /// Iterator>::N => 4`. Note that the self-type is explicit
-    /// here.
-    pub const_bounds: Vec<(ty::Binder<'tcx, ty::ConstPredicate<'tcx>>, Span)>,
-
     /// `Some` if there is *no* `?Sized` predicate. The `span`
     /// is the location in the source of the `T` declaration which can
     /// be cited as the source of the `T: Sized` requirement.
@@ -90,24 +84,7 @@ impl<'tcx> Bounds<'tcx> {
             .projection_bounds
             .iter()
             .map(move |&(projection, span)| (projection.to_predicate(tcx), span));
-        let const_bounds = self.const_bounds.iter().map(move |&(bound, span)| {
-            // FIXME(...): what about the projection's generics?
-            // Is this the right local defid? Or should I get the self ty then
-            let pred = bound
-                .map_bound(|cp| {
-                    let got =
-                        ty::Const::from_anon_const(tcx, cp.projection.item_def_id.expect_local());
-                    ty::PredicateKind::ConstEquate(cp.c, got)
-                })
-                .to_predicate(tcx);
-            (pred, span)
-        });
 
-        sized_predicate
-            .into_iter()
-            .chain(region_preds)
-            .chain(trait_bounds)
-            .chain(projection_bounds)
-            .chain(const_bounds)
+        sized_predicate.into_iter().chain(region_preds).chain(trait_bounds).chain(projection_bounds)
     }
 }
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index c87ab0d410c..c8e1d8b190c 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -279,7 +279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return None;
         };
 
-        let ret_param_ty = projection.skip_binder().ty;
+        let ret_param_ty = projection.skip_binder().term.ty();
         let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty);
         debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty);
 
@@ -706,7 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Extract the type from the projection. Note that there can
         // be no bound variables in this type because the "self type"
         // does not have any regions in it.
-        let output_ty = self.resolve_vars_if_possible(predicate.ty);
+        let output_ty = self.resolve_vars_if_possible(predicate.term.ty());
         debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty);
         Some(output_ty)
     }
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 74327affede..c3fae46909f 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -1360,7 +1360,7 @@ pub fn check_type_bounds<'tcx>(
                             item_def_id: trait_ty.def_id,
                             substs: rebased_substs,
                         },
-                        ty: impl_ty_value,
+                        term: impl_ty_value.into(),
                     },
                     bound_vars,
                 )
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index f2fe4403d55..590d65b7cba 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -789,7 +789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     item_def_id: projection_ty.item_def_id,
                                 };
 
-                                let ty = pred.skip_binder().ty;
+                                let ty: Ty<'_> = pred.skip_binder().term.ty();
 
                                 let obligation = format!("{} = {}", projection_ty, ty);
                                 let quiet = format!("{} = {}", quiet_projection_ty, ty);
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 719266ad5a4..8d06b8a7a17 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -691,7 +691,11 @@ fn bounds_from_generic_predicates<'tcx>(
         // insert the associated types where they correspond, but for now let's be "lazy" and
         // propose this instead of the following valid resugaring:
         // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
-        where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
+        where_clauses.push(format!(
+            "{} = {}",
+            tcx.def_path_str(p.projection_ty.item_def_id),
+            p.term.ty()
+        ));
     }
     let where_clauses = if where_clauses.is_empty() {
         String::new()
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 7cb100a0a83..2843f19d09e 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -664,7 +664,11 @@ impl<'tcx> ItemCtxt<'tcx> {
             .params
             .iter()
             .filter_map(|param| match param.kind {
-                GenericParamKind::Type { .. } if param.hir_id == param_id => Some(&param.bounds),
+                GenericParamKind::Type { .. } | GenericParamKind::Const { .. }
+                    if param.hir_id == param_id =>
+                {
+                    Some(&param.bounds)
+                }
                 _ => None,
             })
             .flat_map(|bounds| bounds.iter())
diff --git a/compiler/rustc_typeck/src/collect/item_bounds.rs b/compiler/rustc_typeck/src/collect/item_bounds.rs
index 6d992629a00..87a67c4a4e0 100644
--- a/compiler/rustc_typeck/src/collect/item_bounds.rs
+++ b/compiler/rustc_typeck/src/collect/item_bounds.rs
@@ -67,11 +67,7 @@ fn opaque_type_bounds<'tcx>(
         let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
         // Opaque types are implicitly sized unless a `?Sized` bound is found
         <dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
-        let preds = bounds.predicates(tcx, item_ty);
-
-        let bounds = tcx.arena.alloc_from_iter(preds);
-        debug!("opaque_type_bounds({}) = {:?}", tcx.def_path_str(opaque_def_id), bounds);
-        bounds
+        tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty))
     })
 }
 
diff --git a/compiler/rustc_typeck/src/constrained_generic_params.rs b/compiler/rustc_typeck/src/constrained_generic_params.rs
index 10952901323..a0c8fc822df 100644
--- a/compiler/rustc_typeck/src/constrained_generic_params.rs
+++ b/compiler/rustc_typeck/src/constrained_generic_params.rs
@@ -203,7 +203,7 @@ pub fn setup_constraining_predicates<'tcx>(
                 if !relies_only_on_inputs {
                     continue;
                 }
-                input_parameters.extend(parameters_for(&projection.ty, false));
+                input_parameters.extend(parameters_for(&projection.term, false));
             } else {
                 continue;
             }
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index 6296f2ab32a..5e6704c9864 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
@@ -199,7 +199,7 @@ fn unconstrained_parent_impl_substs<'tcx>(
     for (predicate, _) in impl_generic_predicates.predicates.iter() {
         if let ty::PredicateKind::Projection(proj) = predicate.kind().skip_binder() {
             let projection_ty = proj.projection_ty;
-            let projected_ty = proj.ty;
+            let projected_ty = proj.term.ty();
 
             let unbound_trait_ref = projection_ty.trait_ref(tcx);
             if Some(unbound_trait_ref) == impl_trait_ref {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 169cb618a7d..f6af81769b7 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -354,7 +354,8 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
 
 impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
     fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate {
-        let ty::ProjectionPredicate { projection_ty, ty } = self;
+        let ty::ProjectionPredicate { projection_ty, term } = self;
+        let ty = term.ty();
         WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) }
     }
 }
@@ -623,8 +624,9 @@ fn clean_ty_generics(
                             .filter(|b| !b.is_sized_bound(cx)),
                     );
 
-                    let proj = projection
-                        .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty));
+                    let proj = projection.map(|p| {
+                        (p.skip_binder().projection_ty.clean(cx), p.skip_binder().term.ty())
+                    });
                     if let Some(((_, trait_did, name), rhs)) =
                         proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
                     {
@@ -1566,7 +1568,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                                                 .ident
                                                 .name,
                                             kind: TypeBindingKind::Equality {
-                                                ty: proj.ty.clean(cx),
+                                                ty: proj.term.ty().clean(cx),
                                             },
                                         })
                                     } else {
@@ -2114,10 +2116,10 @@ impl Clean<TypeBinding> for hir::TypeBinding<'_> {
 impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind {
         match *self {
-            hir::TypeBindingKind::Equality { ref ty } => {
-                TypeBindingKind::Equality { ty: ty.clean(cx) }
-            }
-            hir::TypeBindingKind::Const { c: _ } => todo!(),
+            hir::TypeBindingKind::Equality { ref term } => match term {
+                hir::Term::Ty(ref ty) => TypeBindingKind::Equality { ty: ty.clean(cx) },
+                hir::Term::Const(ref _c) => todo!(),
+            },
             hir::TypeBindingKind::Constraint { ref bounds } => TypeBindingKind::Constraint {
                 bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(),
             },
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 2abffbf977a9e8c6ca4174a08fe5c4d7781f0aa
+Subproject 6b3dbcc81a470e5da84576d63fcfc19e3b1154c
diff --git a/src/test/ui/associated-consts/assoc-const.rs b/src/test/ui/associated-consts/assoc-const.rs
index 9332d16afe5..582d0a69229 100644
--- a/src/test/ui/associated-consts/assoc-const.rs
+++ b/src/test/ui/associated-consts/assoc-const.rs
@@ -10,5 +10,10 @@ impl Foo for Bar {
   const N: usize = 3;
 }
 
+const TEST:usize = 3;
+
+
 fn foo<F: Foo<N=3>>() {}
+fn bar<F: Foo<N={TEST}>>() {}
+
 fn main() {}
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
index 19e0f38d320..32b08fb97f2 100644
--- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
@@ -7,7 +7,7 @@ struct Bar;
 const T: usize = 42;
 
 impl Foo<N = 3> for Bar {
-//~^ ERROR cannot constrain an associated constant to a value
+//~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied
 //~| ERROR associated type bindings are not allowed here
     fn do_x(&self) -> [u8; 3] {
         [0u8; 3]
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
index bbca92ad63a..455f6f61aad 100644
--- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
@@ -1,11 +1,18 @@
-error: cannot constrain an associated constant to a value
-  --> $DIR/issue-89013-no-kw.rs:9:10
+error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+  --> $DIR/issue-89013-no-kw.rs:9:6
    |
 LL | impl Foo<N = 3> for Bar {
-   |          -^^^-
-   |          |   |
-   |          |   ...cannot be constrained to this value
-   |          this associated constant...
+   |      ^^^ expected 1 generic argument
+   |
+note: trait defined here, with 1 generic parameter: `N`
+  --> $DIR/issue-89013-no-kw.rs:1:7
+   |
+LL | trait Foo<const N: usize> {
+   |       ^^^       -
+help: add missing generic argument
+   |
+LL | impl Foo<N, N = 3> for Bar {
+   |          ++
 
 error[E0229]: associated type bindings are not allowed here
   --> $DIR/issue-89013-no-kw.rs:9:10
@@ -15,4 +22,5 @@ LL | impl Foo<N = 3> for Bar {
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0229`.
+Some errors have detailed explanations: E0107, E0229.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs
index ca1158a2f6d..97c22fa7862 100644
--- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs
@@ -8,7 +8,7 @@ const T: usize = 42;
 
 impl Foo<N = const 3> for Bar {
 //~^ ERROR expected lifetime, type, or constant, found keyword `const`
-//~| ERROR cannot constrain an associated constant to a value
+//~| ERROR this trait takes 1 generic
 //~| ERROR associated type bindings are not allowed here
     fn do_x(&self) -> [u8; 3] {
         [0u8; 3]
diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr
index 85379d3f06e..57108d718cf 100644
--- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr
+++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr
@@ -10,14 +10,21 @@ LL - impl Foo<N = const 3> for Bar {
 LL + impl Foo<N = 3> for Bar {
    | 
 
-error: cannot constrain an associated constant to a value
-  --> $DIR/issue-89013.rs:9:10
+error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+  --> $DIR/issue-89013.rs:9:6
    |
 LL | impl Foo<N = const 3> for Bar {
-   |          -^^^^^^^^^-
-   |          |         |
-   |          |         ...cannot be constrained to this value
-   |          this associated constant...
+   |      ^^^ expected 1 generic argument
+   |
+note: trait defined here, with 1 generic parameter: `N`
+  --> $DIR/issue-89013.rs:1:7
+   |
+LL | trait Foo<const N: usize> {
+   |       ^^^       -
+help: add missing generic argument
+   |
+LL | impl Foo<N, N = const 3> for Bar {
+   |          ++
 
 error[E0229]: associated type bindings are not allowed here
   --> $DIR/issue-89013.rs:9:10
@@ -27,4 +34,5 @@ LL | impl Foo<N = const 3> for Bar {
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0229`.
+Some errors have detailed explanations: E0107, E0229.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/parser/recover-assoc-const-constraint.rs b/src/test/ui/parser/recover-assoc-const-constraint.rs
index 06be3cdcc1a..3f7423dcb8e 100644
--- a/src/test/ui/parser/recover-assoc-const-constraint.rs
+++ b/src/test/ui/parser/recover-assoc-const-constraint.rs
@@ -1,7 +1,9 @@
+// run-pass
+
 #[cfg(FALSE)]
 fn syntax() {
-    bar::<Item = 42>(); //~ ERROR cannot constrain an associated constant to a value
-    bar::<Item = { 42 }>(); //~ ERROR cannot constrain an associated constant to a value
+    bar::<Item = 42>();
+    bar::<Item = { 42 }>();
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/recover-assoc-const-constraint.stderr b/src/test/ui/parser/recover-assoc-const-constraint.stderr
deleted file mode 100644
index c6733b33faa..00000000000
--- a/src/test/ui/parser/recover-assoc-const-constraint.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: cannot constrain an associated constant to a value
-  --> $DIR/recover-assoc-const-constraint.rs:3:11
-   |
-LL |     bar::<Item = 42>();
-   |           ----^^^--
-   |           |      |
-   |           |      ...cannot be constrained to this value
-   |           this associated constant...
-
-error: cannot constrain an associated constant to a value
-  --> $DIR/recover-assoc-const-constraint.rs:4:11
-   |
-LL |     bar::<Item = { 42 }>();
-   |           ----^^^------
-   |           |      |
-   |           |      ...cannot be constrained to this value
-   |           this associated constant...
-
-error: aborting due to 2 previous errors
-
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 06b9d31743210b788b130c8a484c2838afa6fc2
+Subproject 358e79fe56fe374649275ca7aebaafd57ade0e8
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 86819752f90..2af3555e370 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -6,7 +6,7 @@ use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId,
+    Term, AsyncGeneratorKind, Block, Body, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, HirId,
     IsAsync, ItemKind, LifetimeName, TraitRef, Ty, TyKind, TypeBindingKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
@@ -140,7 +140,7 @@ fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'t
         if args.bindings.len() == 1;
         let binding = &args.bindings[0];
         if binding.ident.name == sym::Output;
-        if let TypeBindingKind::Equality{ty: output} = binding.kind;
+        if let TypeBindingKind::Equality{term: Term::Ty(output)} = binding.kind;
         then {
             return Some(output)
         }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index ed5136e7d00..c0e65e520f2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -2143,10 +2143,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                     if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
                         // walk the associated type and check for Self
                         if let Some(self_adt) = self_ty.ty_adt_def() {
-                            if contains_adt_constructor(projection_predicate.ty, self_adt) {
+                            if contains_adt_constructor(projection_predicate.term.ty(), self_adt) {
                                 return;
                             }
-                        } else if contains_ty(projection_predicate.ty, self_ty) {
+                        } else if contains_ty(projection_predicate.term.ty(), self_ty) {
                             return;
                         }
                     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index e5b6d296b2d..865a36a5cd1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -243,7 +243,7 @@ fn check_other_call_arg<'tcx>(
         if if trait_predicate.def_id() == deref_trait_id {
             if let [projection_predicate] = projection_predicates[..] {
                 let normalized_ty =
-                    cx.tcx.subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.ty);
+                    cx.tcx.subst_and_normalize_erasing_regions(call_substs, cx.param_env, projection_predicate.term.ty());
                 implements_trait(cx, receiver_ty, deref_trait_id, &[])
                     && get_associated_type(cx, receiver_ty, deref_trait_id, "Target") == Some(normalized_ty)
             } else {
diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
index fe35ff33d35..09f9e1ee099 100644
--- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
@@ -98,9 +98,9 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve
                         if trait_pred.self_ty() == inp;
                         if let Some(return_ty_pred) = get_projection_pred(cx, generics, *trait_pred);
                         then {
-                            if ord_preds.iter().any(|ord| ord.self_ty() == return_ty_pred.ty) {
+                            if ord_preds.iter().any(|ord| ord.self_ty() == return_ty_pred.term.ty()) {
                                 args_to_check.push((i, "Ord".to_string()));
-                            } else if partial_ord_preds.iter().any(|pord| pord.self_ty() == return_ty_pred.ty) {
+                            } else if partial_ord_preds.iter().any(|pord| pord.self_ty() == return_ty_pred.term.ty()) {
                                 args_to_check.push((i, "PartialOrd".to_string()));
                             }
                         }
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
-Subproject 0f8c96c92689af8378dbe9f466c6bf15a3a2745
+Subproject 8e9ccbf97a70259b6c6576e8fd7d77d28238737