about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/traits
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-11-19 05:46:22 +0000
committerMichael Goulet <michael@errs.io>2022-11-19 06:09:29 +0000
commit5384af01e3aa5c840cffb0e4f2cb4b1ce6a9ac4e (patch)
tree13706000ac0b3124f1ea44cf891d91ebb32392af /compiler/rustc_trait_selection/src/traits
parentff0ffda6b3c3ea392c6cf88c676133666f491e5c (diff)
downloadrust-5384af01e3aa5c840cffb0e4f2cb4b1ce6a9ac4e.tar.gz
rust-5384af01e3aa5c840cffb0e4f2cb4b1ce6a9ac4e.zip
Probe + better error messsage for need_migrate_deref_output_trait_object
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits')
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs59
1 files changed, 27 insertions, 32 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 8183f34bb3c..57680669b26 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -8,7 +8,6 @@
 use hir::LangItem;
 use rustc_errors::DelayDm;
 use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
 use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
 use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
@@ -707,7 +706,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         ty: Ty<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         cause: &ObligationCause<'tcx>,
-    ) -> Option<(Ty<'tcx>, DefId)> {
+    ) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
         let tcx = self.tcx();
         if tcx.features().trait_upcasting {
             return None;
@@ -729,27 +728,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return None;
         }
 
-        let ty = traits::normalize_projection_type(
-            self,
-            param_env,
-            ty::ProjectionTy {
-                item_def_id: tcx.lang_items().deref_target()?,
-                substs: trait_ref.substs,
-            },
-            cause.clone(),
-            0,
-            // We're *intentionally* throwing these away,
-            // since we don't actually use them.
-            &mut vec![],
-        )
-        .ty()
-        .unwrap();
-
-        if let ty::Dynamic(data, ..) = ty.kind() {
-            Some((ty, data.principal_def_id()?))
-        } else {
-            None
-        }
+        self.infcx.probe(|_| {
+            let ty = traits::normalize_projection_type(
+                self,
+                param_env,
+                ty::ProjectionTy {
+                    item_def_id: tcx.lang_items().deref_target()?,
+                    substs: trait_ref.substs,
+                },
+                cause.clone(),
+                0,
+                // We're *intentionally* throwing these away,
+                // since we don't actually use them.
+                &mut vec![],
+            )
+            .ty()
+            .unwrap();
+
+            if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None }
+        })
     }
 
     /// Searches for unsizing that might apply to `obligation`.
@@ -811,21 +808,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         let principal_a = data_a.principal().unwrap();
                         let target_trait_did = principal_def_id_b.unwrap();
                         let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
-                        if let Some((deref_output_ty, deref_output_trait_did)) = self
-                            .need_migrate_deref_output_trait_object(
-                                source,
-                                obligation.param_env,
-                                &obligation.cause,
-                            )
-                        {
-                            if deref_output_trait_did == target_trait_did {
+                        if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object(
+                            source,
+                            obligation.param_env,
+                            &obligation.cause,
+                        ) {
+                            if deref_trait_ref.def_id() == target_trait_did {
                                 self.tcx().struct_span_lint_hir(
                                     DEREF_INTO_DYN_SUPERTRAIT,
                                     obligation.cause.body_id,
                                     obligation.cause.span,
                                     DelayDm(|| format!(
                                         "`{}` implements `Deref` with supertrait `{}` as output",
-                                        source, deref_output_ty
+                                        source, deref_trait_ref
                                     )),
                                     |lint| lint,
                                 );