|
9 | 9 | use hir::def_id::DefId;
|
10 | 10 | use hir::LangItem;
|
11 | 11 | use rustc_hir as hir;
|
| 12 | +use rustc_infer::traits::ObligationCause; |
12 | 13 | use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
|
13 | 14 | use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
14 | 15 | use rustc_middle::ty::{self, Ty, TypeVisitableExt};
|
15 | 16 |
|
| 17 | +use crate::traits; |
| 18 | +use crate::traits::query::evaluate_obligation::InferCtxtExt; |
16 | 19 | use crate::traits::util;
|
17 | 20 |
|
18 | 21 | use super::BuiltinImplConditions;
|
@@ -723,6 +726,45 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
723 | 726 | })
|
724 | 727 | }
|
725 | 728 |
|
| 729 | + /// Temporary migration for #89190 |
| 730 | + fn need_migrate_deref_output_trait_object( |
| 731 | + &mut self, |
| 732 | + ty: Ty<'tcx>, |
| 733 | + param_env: ty::ParamEnv<'tcx>, |
| 734 | + cause: &ObligationCause<'tcx>, |
| 735 | + ) -> Option<ty::PolyExistentialTraitRef<'tcx>> { |
| 736 | + let tcx = self.tcx(); |
| 737 | + if tcx.features().trait_upcasting { |
| 738 | + return None; |
| 739 | + } |
| 740 | + |
| 741 | + // <ty as Deref> |
| 742 | + let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]); |
| 743 | + |
| 744 | + let obligation = |
| 745 | + traits::Obligation::new(tcx, cause.clone(), param_env, ty::Binder::dummy(trait_ref)); |
| 746 | + if !self.infcx.predicate_may_hold(&obligation) { |
| 747 | + return None; |
| 748 | + } |
| 749 | + |
| 750 | + self.infcx.probe(|_| { |
| 751 | + let ty = traits::normalize_projection_type( |
| 752 | + self, |
| 753 | + param_env, |
| 754 | + ty::AliasTy::new(tcx, tcx.lang_items().deref_target()?, trait_ref.args), |
| 755 | + cause.clone(), |
| 756 | + 0, |
| 757 | + // We're *intentionally* throwing these away, |
| 758 | + // since we don't actually use them. |
| 759 | + &mut vec![], |
| 760 | + ) |
| 761 | + .ty() |
| 762 | + .unwrap(); |
| 763 | + |
| 764 | + if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None } |
| 765 | + }) |
| 766 | + } |
| 767 | + |
726 | 768 | /// Searches for unsizing that might apply to `obligation`.
|
727 | 769 | fn assemble_candidates_for_unsizing(
|
728 | 770 | &mut self,
|
@@ -780,6 +822,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
780 | 822 | let principal_a = a_data.principal().unwrap();
|
781 | 823 | let target_trait_did = principal_def_id_b.unwrap();
|
782 | 824 | let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
|
| 825 | + if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object( |
| 826 | + source, |
| 827 | + obligation.param_env, |
| 828 | + &obligation.cause, |
| 829 | + ) { |
| 830 | + if deref_trait_ref.def_id() == target_trait_did { |
| 831 | + return; |
| 832 | + } |
| 833 | + } |
783 | 834 |
|
784 | 835 | for (idx, upcast_trait_ref) in
|
785 | 836 | util::supertraits(self.tcx(), source_trait_ref).enumerate()
|
|
0 commit comments