about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-11-17 11:55:27 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-11-21 20:32:41 +0000
commit19a1192d426656fcb8d71cdb510f6920d9ba70ee (patch)
treed2e9d33af7c1148b1769110c8d1ac2c66fb0a864
parent6f77c97b386f05083f039f0130146addf99eefd9 (diff)
downloadrust-19a1192d426656fcb8d71cdb510f6920d9ba70ee.tar.gz
rust-19a1192d426656fcb8d71cdb510f6920d9ba70ee.zip
Add a helper for replacing the self type in trait refs
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs6
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs19
-rw-r--r--compiler/rustc_trait_selection/src/traits/relationships.rs11
5 files changed, 15 insertions, 29 deletions
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 139f2e84136..7d081bac3bd 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -539,11 +539,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .subst_iter_copied(self.tcx, substs)
                     {
                         let pred = pred.kind().rebind(match pred.kind().skip_binder() {
-                            ty::PredicateKind::Trait(mut trait_pred) => {
+                            ty::PredicateKind::Trait(trait_pred) => {
                                 assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
-                                trait_pred.trait_ref.substs =
-                                    self.tcx.mk_substs_trait(ty, &trait_pred.trait_ref.substs[1..]);
-                                ty::PredicateKind::Trait(trait_pred)
+                                ty::PredicateKind::Trait(trait_pred.with_self_type(self.tcx, ty))
                             }
                             ty::PredicateKind::Projection(mut proj_pred) => {
                                 assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty);
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index b4779655252..8bac76d559f 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -852,6 +852,10 @@ impl<'tcx> TraitPredicate<'tcx> {
         }
     }
 
+    pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
+        Self { trait_ref: self.trait_ref.with_self_type(tcx, self_ty), ..self }
+    }
+
     pub fn def_id(self) -> DefId {
         self.trait_ref.def_id
     }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index b9717f2b37e..47cdabb5f81 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -811,6 +811,10 @@ impl<'tcx> TraitRef<'tcx> {
         TraitRef { def_id, substs }
     }
 
+    pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
+        tcx.mk_trait_ref(self.def_id, self_ty, &self.substs[1..])
+    }
+
     /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
     /// are the parameters defined on trait.
     pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> {
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 cf9ba1d8421..cb9902bed54 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -998,13 +998,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         if trait_predicate.skip_binder().self_ty().is_never()
                             && self.fallback_has_occurred
                         {
-                            let predicate = trait_predicate.map_bound(|mut trait_pred| {
-                                trait_pred.trait_ref = self.tcx.mk_trait_ref(
-                                    trait_pred.trait_ref.def_id,
-                                    self.tcx.mk_unit(),
-                                    &trait_pred.trait_ref.substs[1..],
-                                );
-                                trait_pred
+                            let predicate = trait_predicate.map_bound(|trait_pred| {
+                                trait_pred.with_self_type(self.tcx, self.tcx.mk_unit())
                             });
                             let unit_obligation = obligation.with(tcx, predicate);
                             if self.predicate_may_hold(&unit_obligation) {
@@ -2026,14 +2021,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
     ) -> PredicateObligation<'tcx> {
-        let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate {
-            trait_ref: self.tcx.mk_trait_ref(
-                tr.trait_ref.def_id,
-                *new_self_ty,
-                &tr.trait_ref.substs[1..],
-            ),
-            ..*tr
-        });
+        let trait_pred = trait_ref_and_ty
+            .map_bound(|(tr, new_self_ty)| tr.with_self_type(self.tcx, new_self_ty));
 
         Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred)
     }
diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs
index 78f0807bd95..f844da50032 100644
--- a/compiler/rustc_trait_selection/src/traits/relationships.rs
+++ b/compiler/rustc_trait_selection/src/traits/relationships.rs
@@ -18,11 +18,6 @@ pub(crate) fn update<'tcx, T>(
     {
         let new_self_ty = infcx.tcx.types.unit;
 
-        let trait_ref = infcx.tcx.mk_trait_ref(
-            tpred.trait_ref.def_id,
-            new_self_ty, &tpred.trait_ref.substs[1..],
-        );
-
         // Then construct a new obligation with Self = () added
         // to the ParamEnv, and see if it holds.
         let o = obligation.with(infcx.tcx,
@@ -31,11 +26,7 @@ pub(crate) fn update<'tcx, T>(
                 .kind()
                 .rebind(
                     // (*) binder moved here
-                    ty::PredicateKind::Trait(ty::TraitPredicate {
-                        trait_ref,
-                        constness: tpred.constness,
-                        polarity: tpred.polarity,
-                    })
+                    ty::PredicateKind::Trait(tpred.with_self_type(infcx.tcx, new_self_ty))
                 ),
         );
         // Don't report overflow errors. Otherwise equivalent to may_hold.