]> git.lizzy.rs Git - rust.git/commitdiff
Use Term in ProjectionPredicate
authorkadmin <julianknodt@gmail.com>
Sat, 8 Jan 2022 09:28:12 +0000 (09:28 +0000)
committerkadmin <julianknodt@gmail.com>
Mon, 17 Jan 2022 17:44:56 +0000 (17:44 +0000)
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.

51 files changed:
Cargo.lock
compiler/rustc_ast_lowering/src/lib.rs
compiler/rustc_ast_lowering/src/path.rs
compiler/rustc_ast_pretty/src/pprust/state.rs
compiler/rustc_borrowck/src/diagnostics/region_name.rs
compiler/rustc_hir/src/hir.rs
compiler/rustc_hir/src/intravisit.rs
compiler/rustc_hir_pretty/src/lib.rs
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
compiler/rustc_infer/src/infer/opaque_types.rs
compiler/rustc_infer/src/infer/projection.rs
compiler/rustc_middle/src/ty/flags.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_middle/src/ty/relate.rs
compiler/rustc_middle/src/ty/structural_impls.rs
compiler/rustc_middle/src/ty/sty.rs
compiler/rustc_parse/src/parser/path.rs
compiler/rustc_privacy/src/lib.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/project.rs
compiler/rustc_trait_selection/src/traits/relationships.rs
compiler/rustc_trait_selection/src/traits/wf.rs
compiler/rustc_traits/src/chalk/lowering.rs
compiler/rustc_typeck/src/astconv/errors.rs
compiler/rustc_typeck/src/astconv/mod.rs
compiler/rustc_typeck/src/bounds.rs
compiler/rustc_typeck/src/check/closure.rs
compiler/rustc_typeck/src/check/compare_method.rs
compiler/rustc_typeck/src/check/method/suggest.rs
compiler/rustc_typeck/src/check/mod.rs
compiler/rustc_typeck/src/collect.rs
compiler/rustc_typeck/src/collect/item_bounds.rs
compiler/rustc_typeck/src/constrained_generic_params.rs
compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
src/librustdoc/clean/mod.rs
src/llvm-project
src/test/ui/associated-consts/assoc-const.rs
src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
src/test/ui/const-generics/parser-error-recovery/issue-89013.rs
src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr
src/test/ui/parser/recover-assoc-const-constraint.rs
src/test/ui/parser/recover-assoc-const-constraint.stderr [deleted file]
src/tools/cargo
src/tools/clippy/clippy_lints/src/manual_async_fn.rs
src/tools/clippy/clippy_lints/src/methods/mod.rs
src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
src/tools/rust-analyzer

index 18b85103202e32744279d3c48c3173a523a70219..529e17b158fc83b8e8bc867a212320be6470b6b2 100644 (file)
@@ -335,7 +335,7 @@ dependencies = [
  "cargo-test-macro",
  "cargo-test-support",
  "cargo-util",
- "clap 3.0.6",
+ "clap",
  "crates-io",
  "crossbeam-utils",
  "curl",
@@ -615,28 +615,13 @@ 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"
@@ -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",
@@ -2521,15 +2506,6 @@ dependencies = [
  "winapi",
 ]
 
-[[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"
@@ -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",
 ]
@@ -4898,19 +4874,13 @@ version = "0.8.0"
 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",
 ]
@@ -5081,12 +5051,6 @@ dependencies = [
  "unicode-width",
 ]
 
-[[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"
index 9a8a097ee249c834b87e43e59adad3c03988e0e4..b2965774e2a6e85a4253f5cdd7ea47c926469afe 100644 (file)
@@ -997,10 +997,13 @@ fn lower_assoc_ty_constraint(
         };
 
         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 @@ fn lower_assoc_ty_constraint(
                             itctx,
                         );
 
-                        hir::TypeBindingKind::Equality { ty }
+                        hir::TypeBindingKind::Equality { term: ty.into() }
                     })
                 } else {
                     // Desugar `AssocTy: Bounds` into a type binding where the
index 46928a1846540f13859f74c2f6df5ce4023dd67b..79262235cd9f250584e1556c7145a415eb2cf982 100644 (file)
@@ -420,7 +420,7 @@ fn lower_parenthesized_parameter_data(
         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 {
index 3c45b5790fb47d8f2dabb3ff4cec6918f91e6ed7..17941058ed6f0ce7e21e58da0ec86c322446c361 100644 (file)
@@ -964,9 +964,7 @@ pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocConstraint) {
                     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),
         }
     }
 
index 9aa58f05a8e65e5e55ce8ed0d643c7a123d5f23c..01cc72121c7d4d5cfc9ad03787ee2f363578c12b 100644 (file)
@@ -779,7 +779,10 @@ fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::
                                     [
                                         hir::TypeBinding {
                                             ident: Ident { name: sym::Output, .. },
-                                            kind: hir::TypeBindingKind::Equality { ty },
+                                            kind:
+                                                hir::TypeBindingKind::Equality {
+                                                    term: hir::Term::Ty(ty),
+                                                },
                                             ..
                                         },
                                     ],
index 039bb0db0aa792ab3d72cb2c0163281e7456c602..43aa0ae265a095eacc0a7ed3a67175f3b580d950 100644 (file)
@@ -377,7 +377,7 @@ pub fn has_err(&self) -> bool {
             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"),
         }
     }
index 56b32cde9d54fd8fb9d8bf7e73bf44215dcedd3c..a219dad7b3d226399ad644a1595a92e750cfa5a1 100644 (file)
@@ -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),
     }
 }
 
index a76af35a8e62648829f18c0a98185e115f2e2862..a301c5e34565cabd107e279828293ab846d2c690 100644 (file)
@@ -6,7 +6,7 @@
 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 @@ fn print_generic_args(
                 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);
index 6e6012fdc1a60a44dfdaaaa25115fdd086f11d49..f1e99faba01bd1fa99d32efb0364f2cdaa99dff9 100644 (file)
@@ -69,7 +69,7 @@
 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 @@ pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'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!(),
+                        }
                     }
                 }
             }
index 04eceecc5f072a6e4faf48fdde71178f03a78a52..3fa71d1a3d8171204636aade006a54da3fd1bd14 100644 (file)
@@ -122,8 +122,9 @@ pub(super) fn future_return_type(
                             {
                                 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);
                                         }
index 8894093c66c985c0990a9b86387126eff76191c0..39339da9a0bfcca1146fe26e564c667afdac38f5 100644 (file)
@@ -7,7 +7,7 @@
 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 @@ fn fold_opaque_ty(
             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!();
                 }
             }
 
index 9b53ab72b00dea078ce8b58767994a7622f77ff2..b45a6514d79347e05f8e1e47320901227486c2c1 100644 (file)
@@ -26,7 +26,8 @@ pub fn infer_projection(
             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,
index b6e673983fd4ed32d6bb7896c38d8f8ce7e78114..74c8d7b7777227701aa4d106ed69bd58e526b55a 100644 (file)
@@ -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 @@ fn add_predicate_atom(&mut self, atom: ty::PredicateKind<'_>) {
                 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));
index 72e4e26dd3ee72937aa7bb529b0eab409a483dcd..f1851150e38e82ad66c384e7c07444e9ca1ac596 100644 (file)
@@ -484,7 +484,7 @@ pub fn has_name(&self) -> bool {
 }
 
 #[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 struct 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 @@ pub fn required_poly_trait_ref(&self, tcx: TyCtxt<'tcx>) -> PolyTraitRef<'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.
index 94cd650e39e6f2a75466dffd9374321b2018a20e..8c07f154637e398148af165e52412eb0389f51cf 100644 (file)
@@ -2499,7 +2499,14 @@ pub fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPat
     }
 
     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> {
index 9e381cabdfe8482995ecdf1ed05dc4238b02f85f..851c4592f4fad8594e6fa4f85064bfb1ea9dba7f 100644 (file)
@@ -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 @@ fn relate<R: TypeRelation<'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!(),
+        }
     }
 }
 
index a27169d59e13f654b1ab09a0871423a879aa7990..3cbea92ae67149dbe95eaee5d44972920c53107c 100644 (file)
@@ -6,7 +6,7 @@
 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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 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 @@ fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
     }
 }
 
+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 @@ fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionTy<'tcx>> {
 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 })
     }
 }
 
index 92fb7612688c08c2f265d21dfa428bd2f7653f9c..50d0862905bbf38a05a45bcb414cbbbf05ffc527 100644 (file)
@@ -8,7 +8,7 @@
 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 @@ pub fn with_self_ty(
                 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 @@ pub fn erase_self_ty(
     ) -> 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,
         }
     }
 }
index 8f272820015b2a7e84d6cfddafda271462eb08b9..531cac1f57e5649826c6e035ea76652fbff3b47e 100644 (file)
@@ -503,17 +503,15 @@ fn parse_assoc_equality_term(
     ) -> 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 @@ fn parse_assoc_equality_term(
                 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:
index 7577b77181a061e308bd8c2e96ed3b8052556c30..dc432905b1c7c448dd1c59830922b7604cbab0ab 100644 (file)
@@ -127,7 +127,8 @@ fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<V::
                 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 @@ fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef<'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()
index b4d297a03ef21f3b552d8a15b9164fe0d77395b3..85135383b8062a3ba9c43b15019c30d1af683d9b 100644 (file)
@@ -1304,7 +1304,8 @@ fn report_projection_error(
 
                 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 @@ fn report_projection_error(
                 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 @@ fn maybe_report_ambiguity(
             }
             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;
                 }
index 577b96f3a400ba5e331f7803f4c9290de27a80db..4995590baec231f8856b9b00a54a1193be646f54 100644 (file)
@@ -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!(
index e0098cc92d51569ac0509b08e34024fca73648b1..acac76cdfaaf026487f4f6367057f8fadbcda14d 100644 (file)
@@ -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;
         }
index f6e98f427108f7f380dd0579040acaa986fb2677..e3b366c65bf5c779e2bb83d3e8ee31e6966eb9de 100644 (file)
@@ -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)
                 {
index 36c536c0ba3b2af0273852b537d7e45f31fd1134..e651ff63c5249d9d223f284deda8e8fff97a383b 100644 (file)
@@ -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 @@ fn lower_into(
             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),
         }
     }
 }
index 1f99a9b0536d0e967a54d17ddcef6d170d387162..b532c41642c6e88b814b41cc79e804ed0afad937 100644 (file)
@@ -151,8 +151,12 @@ pub(crate) fn complain_about_internal_fn_trait(
                     .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,
                     })
index 2d847f6145d6f096780d2454752986a9063dcc34..2866a7884a77a0916af881a11ec8c5218ca6891a 100644 (file)
@@ -602,14 +602,16 @@ fn create_assoc_bindings_for_generic_args<'a>(
             .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 @@ fn add_predicates_for_ast_type_binding(
                 //
                 // `<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 @@ trait here instead: `trait NewTrait: {} {{}}`",
                         // 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.
index 47c3ea5457578117c9242b1b4d25bd208cba2dd6..6a28bb16a20acf2945f940d3f376d957529c3adf 100644 (file)
@@ -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 @@ pub fn predicates<'out, 's>(
             .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)
     }
 }
index c87ab0d410cd9c61dd108dc6ad3012e360becd79..c8e1d8b190c9d6ca10585203beacd44ca28e347d 100644 (file)
@@ -279,7 +279,7 @@ fn deduce_sig_from_projection(
             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 @@ fn deduce_future_output_from_projection(
         // 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)
     }
index 74327affede481e5d7e7b7913d835d42291385c0..c3fae46909f1c2e99eed636d202243ac618bbd3e 100644 (file)
@@ -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,
                 )
index f2fe4403d558ccab3d6284e93b65e97bd3f12465..590d65b7cba3f3cffb06a58e9c7a4129989626e4 100644 (file)
@@ -789,7 +789,7 @@ fn report_function<T: std::fmt::Display>(
                                     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);
index 719266ad5a4355b9ff70add27239001e09b93fea..8d06b8a7a170b2b69d133bf5c959f92bf642ec3f 100644 (file)
@@ -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()
index 7cb100a0a83f09f6f8d5e15ae62e6b24b922c0bc..2843f19d09e0e0c76fd911f7d1f0f8ea80b3de33 100644 (file)
@@ -664,7 +664,11 @@ fn type_parameter_bounds_in_generics(
             .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())
index 6d992629a00ffecda0271ae81cd97c857aa94a7e..87a67c4a4e060ed147802f1cacd9c298bdbfc667 100644 (file)
@@ -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))
     })
 }
 
index 1095290132347c85c570b1c0fa04898d896257f9..a0c8fc822dffd88769c78094b71dda48211d0125 100644 (file)
@@ -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;
             }
index 6296f2ab32a5236d26e77d967de9f52cf7a1f40b..5e6704c9864fcae3039474b79559eae419769d66 100644 (file)
@@ -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 {
index 169cb618a7d93888a402870df366590e06c3dabf..f6af81769b7a1be6fbe0cfe9ccdbaaa412f1296b 100644 (file)
@@ -354,7 +354,8 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> {
 
 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 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
                                                 .ident
                                                 .name,
                                             kind: TypeBindingKind::Equality {
-                                                ty: proj.ty.clean(cx),
+                                                ty: proj.term.ty().clean(cx),
                                             },
                                         })
                                     } else {
@@ -2114,10 +2116,10 @@ fn clean(&self, cx: &mut DocContext<'_>) -> 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(),
             },
index 2abffbf977a9e8c6ca4174a08fe5c4d7781f0aac..6b3dbcc81a470e5da84576d63fcfc19e3b1154cd 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2abffbf977a9e8c6ca4174a08fe5c4d7781f0aac
+Subproject commit 6b3dbcc81a470e5da84576d63fcfc19e3b1154cd
index 9332d16afe54fe38bec45efaff4715a74d63218e..582d0a69229854bcf32d059e8248d080216a6cbe 100644 (file)
@@ -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() {}
index 19e0f38d320c4e915bdd9c1c76e10881fb866aeb..32b08fb97f2711a147062b472b2b698af1cad679 100644 (file)
@@ -7,7 +7,7 @@ trait Foo<const N: usize> {
 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]
index bbca92ad63a91ab7a0d0ae15859c8211ff534053..455f6f61aada35853de04543d4d3a995839b1cba 100644 (file)
@@ -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`.
index ca1158a2f6d16140cccb9e3578ffa4862be26a90..97c22fa7862d5750082b630f1d9dbd8838699563 100644 (file)
@@ -8,7 +8,7 @@ trait Foo<const N: usize> {
 
 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]
index 85379d3f06e4b46722a0a2d5ed9aac717fb74580..57108d718cfdea808cd6416420a11457a57afe5b 100644 (file)
@@ -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`.
index 06be3cdcc1a9528dd58d472dcedb5a477f5e7dc7..3f7423dcb8e0cd14e79932a9268ce76a5f3cb366 100644 (file)
@@ -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 (file)
index c6733b3..0000000
+++ /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
-
index 06b9d31743210b788b130c8a484c2838afa6fc27..358e79fe56fe374649275ca7aebaafd57ade0e8d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 06b9d31743210b788b130c8a484c2838afa6fc27
+Subproject commit 358e79fe56fe374649275ca7aebaafd57ade0e8d
index 86819752f90ffe1753eaa2baa4d681f569bf9046..2af3555e370a4b8ec15f0c4204e24276abe324c1 100644 (file)
@@ -6,7 +6,7 @@
 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)
         }
index ed5136e7d00ff1cbe7c0643f06062916840ed42c..c0e65e520f23a59c85fab26c1ee237cda12c212e 100644 (file)
@@ -2143,10 +2143,10 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::Impl
                     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;
                         }
                     }
index e5b6d296b2d2519a320636db919465f54a7bf21f..865a36a5cd1d668efcd9cf48b296de774303ea3f 100644 (file)
@@ -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 {
index fe35ff33d35a4736f49f8a3b656e75b3f82b787d..09f9e1ee09990ed1964f0c541f8528634de8ecbc 100644 (file)
@@ -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()));
                             }
                         }
index 0f8c96c92689af8378dbe9f466c6bf15a3a27458..8e9ccbf97a70259b6c6576e8fd7d77d28238737e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 0f8c96c92689af8378dbe9f466c6bf15a3a27458
+Subproject commit 8e9ccbf97a70259b6c6576e8fd7d77d28238737e