]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_trait_selection/src/traits/auto_trait.rs
Combine projection and opaque into alias
[rust.git] / compiler / rustc_trait_selection / src / traits / auto_trait.rs
index 5869bc76b596cf34a33459e4a080526a16158275..aef2f8ff9911cc90b565bf27c02d946d0ffcd766 100644 (file)
@@ -10,7 +10,7 @@
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{PolyTraitRef, Region, RegionVid};
+use rustc_middle::ty::{ImplPolarity, Region, RegionVid};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 
@@ -86,21 +86,24 @@ pub fn find_auto_trait_generics<A>(
     ) -> AutoTraitResult<A> {
         let tcx = self.tcx;
 
-        let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) };
-
-        let trait_pred = ty::Binder::dummy(trait_ref);
+        let trait_ref = tcx.mk_trait_ref(trait_did, [ty]);
 
         let infcx = tcx.infer_ctxt().build();
         let mut selcx = SelectionContext::new(&infcx);
-        for f in [
-            PolyTraitRef::to_poly_trait_predicate,
-            PolyTraitRef::to_poly_trait_predicate_negative_polarity,
-        ] {
+        for polarity in [true, false] {
             let result = selcx.select(&Obligation::new(
                 tcx,
                 ObligationCause::dummy(),
                 orig_env,
-                f(&trait_pred),
+                ty::Binder::dummy(ty::TraitPredicate {
+                    trait_ref,
+                    constness: ty::BoundConstness::NotConst,
+                    polarity: if polarity {
+                        ImplPolarity::Positive
+                    } else {
+                        ImplPolarity::Negative
+                    },
+                }),
             ));
             if let Ok(Some(ImplSource::UserDefined(_))) = result {
                 debug!(
@@ -260,10 +263,8 @@ fn evaluate_predicates(
         let mut already_visited = FxHashSet::default();
         let mut predicates = VecDeque::new();
         predicates.push_back(ty::Binder::dummy(ty::TraitPredicate {
-            trait_ref: ty::TraitRef {
-                def_id: trait_did,
-                substs: infcx.tcx.mk_substs_trait(ty, &[]),
-            },
+            trait_ref: infcx.tcx.mk_trait_ref(trait_did, [ty]),
+
             constness: ty::BoundConstness::NotConst,
             // Auto traits are positive
             polarity: ty::ImplPolarity::Positive,
@@ -402,8 +403,10 @@ fn add_user_pred(
     ) {
         let mut should_add_new = true;
         user_computed_preds.retain(|&old_pred| {
-            if let (ty::PredicateKind::Trait(new_trait), ty::PredicateKind::Trait(old_trait)) =
-                (new_pred.kind().skip_binder(), old_pred.kind().skip_binder())
+            if let (
+                ty::PredicateKind::Clause(ty::Clause::Trait(new_trait)),
+                ty::PredicateKind::Clause(ty::Clause::Trait(old_trait)),
+            ) = (new_pred.kind().skip_binder(), old_pred.kind().skip_binder())
             {
                 if new_trait.def_id() == old_trait.def_id() {
                     let new_substs = new_trait.trait_ref.substs;
@@ -576,14 +579,14 @@ fn is_param_no_infer(&self, substs: SubstsRef<'_>) -> bool {
     pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
         match ty.kind() {
             ty::Param(_) => true,
-            ty::Projection(p) => self.is_of_param(p.self_ty()),
+            ty::Alias(ty::Projection, p) => self.is_of_param(p.self_ty()),
             _ => false,
         }
     }
 
     fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
         if let Some(ty) = p.term().skip_binder().ty() {
-            matches!(ty.kind(), ty::Projection(proj) if proj == &p.skip_binder().projection_ty)
+            matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_ty)
         } else {
             false
         }
@@ -596,17 +599,17 @@ fn evaluate_nested_obligations(
         computed_preds: &mut FxIndexSet<ty::Predicate<'tcx>>,
         fresh_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
         predicates: &mut VecDeque<ty::PolyTraitPredicate<'tcx>>,
-        select: &mut SelectionContext<'_, 'tcx>,
+        selcx: &mut SelectionContext<'_, 'tcx>,
         only_projections: bool,
     ) -> bool {
         let dummy_cause = ObligationCause::dummy();
 
         for obligation in nested {
             let is_new_pred =
-                fresh_preds.insert(self.clean_pred(select.infcx(), obligation.predicate));
+                fresh_preds.insert(self.clean_pred(selcx.infcx, obligation.predicate));
 
             // Resolve any inference variables that we can, to help selection succeed
-            let predicate = select.infcx().resolve_vars_if_possible(obligation.predicate);
+            let predicate = selcx.infcx.resolve_vars_if_possible(obligation.predicate);
 
             // We only add a predicate as a user-displayable bound if
             // it involves a generic parameter, and doesn't contain
@@ -623,14 +626,14 @@ fn evaluate_nested_obligations(
 
             let bound_predicate = predicate.kind();
             match bound_predicate.skip_binder() {
-                ty::PredicateKind::Trait(p) => {
+                ty::PredicateKind::Clause(ty::Clause::Trait(p)) => {
                     // Add this to `predicates` so that we end up calling `select`
                     // with it. If this predicate ends up being unimplemented,
                     // then `evaluate_predicates` will handle adding it the `ParamEnv`
                     // if possible.
                     predicates.push_back(bound_predicate.rebind(p));
                 }
-                ty::PredicateKind::Projection(p) => {
+                ty::PredicateKind::Clause(ty::Clause::Projection(p)) => {
                     let p = bound_predicate.rebind(p);
                     debug!(
                         "evaluate_nested_obligations: examining projection predicate {:?}",
@@ -714,10 +717,8 @@ fn evaluate_nested_obligations(
                     // and turn them into an explicit negative impl for our type.
                     debug!("Projecting and unifying projection predicate {:?}", predicate);
 
-                    match project::poly_project_and_unify_type(
-                        select,
-                        &obligation.with(self.tcx, p),
-                    ) {
+                    match project::poly_project_and_unify_type(selcx, &obligation.with(self.tcx, p))
+                    {
                         ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
                             debug!(
                                 "evaluate_nested_obligations: Unable to unify predicate \
@@ -742,7 +743,7 @@ fn evaluate_nested_obligations(
                                     computed_preds,
                                     fresh_preds,
                                     predicates,
-                                    select,
+                                    selcx,
                                     only_projections,
                                 ) {
                                     return false;
@@ -763,25 +764,25 @@ fn evaluate_nested_obligations(
                         }
                     }
                 }
-                ty::PredicateKind::RegionOutlives(binder) => {
+                ty::PredicateKind::Clause(ty::Clause::RegionOutlives(binder)) => {
                     let binder = bound_predicate.rebind(binder);
-                    select.infcx().region_outlives_predicate(&dummy_cause, binder)
+                    selcx.infcx.region_outlives_predicate(&dummy_cause, binder)
                 }
-                ty::PredicateKind::TypeOutlives(binder) => {
+                ty::PredicateKind::Clause(ty::Clause::TypeOutlives(binder)) => {
                     let binder = bound_predicate.rebind(binder);
                     match (
                         binder.no_bound_vars(),
                         binder.map_bound_ref(|pred| pred.0).no_bound_vars(),
                     ) {
                         (None, Some(t_a)) => {
-                            select.infcx().register_region_obligation_with_cause(
+                            selcx.infcx.register_region_obligation_with_cause(
                                 t_a,
-                                select.infcx().tcx.lifetimes.re_static,
+                                selcx.infcx.tcx.lifetimes.re_static,
                                 &dummy_cause,
                             );
                         }
                         (Some(ty::OutlivesPredicate(t_a, r_b)), _) => {
-                            select.infcx().register_region_obligation_with_cause(
+                            selcx.infcx.register_region_obligation_with_cause(
                                 t_a,
                                 r_b,
                                 &dummy_cause,
@@ -793,14 +794,12 @@ fn evaluate_nested_obligations(
                 ty::PredicateKind::ConstEquate(c1, c2) => {
                     let evaluate = |c: ty::Const<'tcx>| {
                         if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
-                            match select.infcx().const_eval_resolve(
+                            match selcx.infcx.const_eval_resolve(
                                 obligation.param_env,
                                 unevaluated,
                                 Some(obligation.cause.span),
                             ) {
-                                Ok(Some(valtree)) => {
-                                    Ok(ty::Const::from_value(select.tcx(), valtree, c.ty()))
-                                }
+                                Ok(Some(valtree)) => Ok(selcx.tcx().mk_const(valtree, c.ty())),
                                 Ok(None) => {
                                     let tcx = self.tcx;
                                     let def_id = unevaluated.def.did;
@@ -820,10 +819,7 @@ fn evaluate_nested_obligations(
 
                     match (evaluate(c1), evaluate(c2)) {
                         (Ok(c1), Ok(c2)) => {
-                            match select
-                                .infcx()
-                                .at(&obligation.cause, obligation.param_env)
-                                .eq(c1, c2)
+                            match selcx.infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
                             {
                                 Ok(_) => (),
                                 Err(_) => return false,
@@ -843,6 +839,7 @@ fn evaluate_nested_obligations(
                 | ty::PredicateKind::ConstEvaluatable(..)
                 | ty::PredicateKind::Coerce(..)
                 | ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
+                ty::PredicateKind::Ambiguous => return false,
             };
         }
         true
@@ -857,7 +854,7 @@ pub fn clean_pred(
     }
 }
 
-// Replaces all ReVars in a type with ty::Region's, using the provided map
+/// Replaces all ReVars in a type with ty::Region's, using the provided map
 pub struct RegionReplacer<'a, 'tcx> {
     vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
     tcx: TyCtxt<'tcx>,