about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs84
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs17
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs7
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs13
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs38
-rw-r--r--compiler/rustc_trait_selection/src/regions.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs2
8 files changed, 90 insertions, 79 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 4c224248945..c97e3170166 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -5,13 +5,11 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
 use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
 use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
 use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
+use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::ObligationCause;
-use rustc_middle::ty::GenericArgKind;
-use rustc_middle::ty::{self, TyCtxt};
-use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
+use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_trait_selection::solve::deeply_normalize;
-use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
 use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
 
@@ -146,7 +144,6 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
         let ConstraintConversion {
             tcx,
             infcx,
-            param_env,
             region_bound_pairs,
             implicit_region_bound,
             known_type_outlives_obligations,
@@ -178,43 +175,10 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
                         // Normalize the type we receive from a `TypeOutlives` obligation
                         // in the new trait solver.
                         if infcx.next_trait_solver() {
-                            let result = CustomTypeOp::new(
-                                |ocx| {
-                                    match deeply_normalize(
-                                        ocx.infcx.at(
-                                            &ObligationCause::dummy_with_span(self.span),
-                                            param_env,
-                                        ),
-                                        t1,
-                                    ) {
-                                        Ok(normalized_ty) => {
-                                            t1 = normalized_ty;
-                                        }
-                                        Err(e) => {
-                                            infcx.err_ctxt().report_fulfillment_errors(e);
-                                        }
-                                    }
-
-                                    Ok(())
-                                },
-                                "normalize type outlives obligation",
-                            )
-                            .fully_perform(infcx, self.span);
-
-                            match result {
-                                Ok(TypeOpOutput { output: (), constraints, .. }) => {
-                                    if let Some(constraints) = constraints {
-                                        assert!(
-                                            constraints.member_constraints.is_empty(),
-                                            "no member constraints expected from normalizing: {:#?}",
-                                            constraints.member_constraints
-                                        );
-                                        next_outlives_predicates
-                                            .extend(constraints.outlives.iter().copied());
-                                    }
-                                }
-                                Err(_) => {}
-                            }
+                            t1 = self.normalize_and_add_type_outlives_constraints(
+                                t1,
+                                &mut next_outlives_predicates,
+                            );
                         }
 
                         // we don't actually use this for anything, but
@@ -306,6 +270,42 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
         debug!("add_type_test(type_test={:?})", type_test);
         self.constraints.type_tests.push(type_test);
     }
+
+    fn normalize_and_add_type_outlives_constraints(
+        &self,
+        ty: Ty<'tcx>,
+        next_outlives_predicates: &mut Vec<(
+            ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>,
+            ConstraintCategory<'tcx>,
+        )>,
+    ) -> Ty<'tcx> {
+        let result = CustomTypeOp::new(
+            |ocx| {
+                deeply_normalize(
+                    ocx.infcx.at(&ObligationCause::dummy_with_span(self.span), self.param_env),
+                    ty,
+                )
+                .map_err(|_| NoSolution)
+            },
+            "normalize type outlives obligation",
+        )
+        .fully_perform(self.infcx, self.span);
+
+        match result {
+            Ok(TypeOpOutput { output: ty, constraints, .. }) => {
+                if let Some(constraints) = constraints {
+                    assert!(
+                        constraints.member_constraints.is_empty(),
+                        "no member constraints expected from normalizing: {:#?}",
+                        constraints.member_constraints
+                    );
+                    next_outlives_predicates.extend(constraints.outlives.iter().copied());
+                }
+                ty
+            }
+            Err(_) => ty,
+        }
+    }
 }
 
 impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'b, 'tcx> {
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index 4d53a53ee19..2e0caf44819 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -11,7 +11,7 @@ use rustc_middle::traits::query::OutlivesBound;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
 use rustc_span::{ErrorGuaranteed, DUMMY_SP};
-use rustc_trait_selection::solve::deeply_normalize_with_skipped_universes;
+use rustc_trait_selection::solve::deeply_normalize;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
 use std::rc::Rc;
@@ -226,18 +226,16 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
         let mut constraints = vec![];
         let mut known_type_outlives_obligations = vec![];
         for bound in param_env.caller_bounds() {
-            let Some(outlives) = bound.as_type_outlives_clause() else { continue };
-            let ty::OutlivesPredicate(mut ty, region) = outlives.skip_binder();
+            let Some(mut outlives) = bound.as_type_outlives_clause() else { continue };
 
             // In the new solver, normalize the type-outlives obligation assumptions.
             if self.infcx.next_trait_solver() {
-                match deeply_normalize_with_skipped_universes(
+                match deeply_normalize(
                     self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), self.param_env),
-                    ty,
-                    vec![None; ty.outer_exclusive_binder().as_usize()],
+                    outlives,
                 ) {
-                    Ok(normalized_ty) => {
-                        ty = normalized_ty;
+                    Ok(normalized_outlives) => {
+                        outlives = normalized_outlives;
                     }
                     Err(e) => {
                         self.infcx.err_ctxt().report_fulfillment_errors(e);
@@ -245,8 +243,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                 }
             }
 
-            known_type_outlives_obligations
-                .push(outlives.rebind(ty::OutlivesPredicate(ty, region)));
+            known_type_outlives_obligations.push(outlives);
         }
         let known_type_outlives_obligations =
             self.infcx.tcx.arena.alloc_slice(&known_type_outlives_obligations);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index b8344310d5d..f74e13db447 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -71,6 +71,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_middle::dep_graph::DepContext;
 use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
 use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
+use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::{
     self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable,
     TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@@ -519,10 +520,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
                     }
 
-                    RegionResolutionError::CannotNormalize(ty, origin) => {
+                    RegionResolutionError::CannotNormalize(clause, origin) => {
+                        let clause: ty::Clause<'tcx> =
+                            clause.map_bound(ty::ClauseKind::TypeOutlives).to_predicate(self.tcx);
                         self.tcx
                             .dcx()
-                            .struct_span_err(origin.span(), format!("cannot normalize `{ty}`"))
+                            .struct_span_err(origin.span(), format!("cannot normalize `{clause}`"))
                             .emit();
                     }
                 }
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 4a1169e68e0..6137506d4a9 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -99,7 +99,7 @@ pub enum RegionResolutionError<'tcx> {
         Region<'tcx>,          // the placeholder `'b`
     ),
 
-    CannotNormalize(Ty<'tcx>, SubregionOrigin<'tcx>),
+    CannotNormalize(ty::PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>),
 }
 
 impl<'tcx> RegionResolutionError<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index 926e198b219..a4f9316b502 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -4,8 +4,8 @@ use super::region_constraints::RegionConstraintData;
 use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
 use crate::infer::free_regions::RegionRelations;
 use crate::infer::lexical_region_resolve;
-use rustc_middle::traits::query::OutlivesBound;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::traits::query::{NoSolution, OutlivesBound};
+use rustc_middle::ty;
 
 pub mod components;
 pub mod env;
@@ -49,12 +49,15 @@ impl<'tcx> InferCtxt<'tcx> {
     pub fn resolve_regions_with_normalize(
         &self,
         outlives_env: &OutlivesEnvironment<'tcx>,
-        deeply_normalize_ty: impl Fn(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
+        deeply_normalize_ty: impl Fn(
+            ty::PolyTypeOutlivesPredicate<'tcx>,
+            SubregionOrigin<'tcx>,
+        ) -> Result<ty::PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
     ) -> Vec<RegionResolutionError<'tcx>> {
         match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
             Ok(()) => {}
-            Err((ty, origin)) => {
-                return vec![RegionResolutionError::CannotNormalize(ty, origin)];
+            Err((clause, origin)) => {
+                return vec![RegionResolutionError::CannotNormalize(clause, origin)];
             }
         };
 
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index c36d8556d17..7208f17fb34 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -68,8 +68,9 @@ use crate::infer::{
 use crate::traits::{ObligationCause, ObligationCauseCode};
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::mir::ConstraintCategory;
-use rustc_middle::ty::GenericArgKind;
+use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{GenericArgKind, PolyTypeOutlivesPredicate};
 use rustc_span::DUMMY_SP;
 use smallvec::smallvec;
 
@@ -125,11 +126,15 @@ impl<'tcx> InferCtxt<'tcx> {
     /// invoked after all type-inference variables have been bound --
     /// right before lexical region resolution.
     #[instrument(level = "debug", skip(self, outlives_env, deeply_normalize_ty))]
-    pub fn process_registered_region_obligations<E>(
+    pub fn process_registered_region_obligations(
         &self,
         outlives_env: &OutlivesEnvironment<'tcx>,
-        mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, E>,
-    ) -> Result<(), (E, SubregionOrigin<'tcx>)> {
+        mut deeply_normalize_ty: impl FnMut(
+            PolyTypeOutlivesPredicate<'tcx>,
+            SubregionOrigin<'tcx>,
+        )
+            -> Result<PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
+    ) -> Result<(), (PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>)> {
         assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
 
         let normalized_caller_bounds: Vec<_> = outlives_env
@@ -137,21 +142,19 @@ impl<'tcx> InferCtxt<'tcx> {
             .caller_bounds()
             .iter()
             .filter_map(|clause| {
-                let bound_clause = clause.kind();
-                let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else {
-                    return None;
-                };
+                let outlives = clause.as_type_outlives_clause()?;
                 Some(
                     deeply_normalize_ty(
-                        outlives.0,
+                        outlives,
                         SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
                     )
-                    .map(|ty| bound_clause.rebind(ty::OutlivesPredicate(ty, outlives.1))),
+                    // FIXME(-Znext-solver): How do we accurately report an error span here :(
+                    .map_err(|NoSolution| {
+                        (outlives, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP))
+                    }),
                 )
             })
-            // FIXME(-Znext-solver): How do we accurately report an error here :(
-            .try_collect()
-            .map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
+            .try_collect()?;
 
         // Must loop since the process of normalizing may itself register region obligations.
         for iteration in 0.. {
@@ -167,8 +170,13 @@ impl<'tcx> InferCtxt<'tcx> {
             }
 
             for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
-                let sup_type = deeply_normalize_ty(sup_type, origin.clone())
-                    .map_err(|e| (e, origin.clone()))?;
+                let outlives = ty::Binder::dummy(ty::OutlivesPredicate(sup_type, sub_region));
+                let ty::OutlivesPredicate(sup_type, sub_region) =
+                    deeply_normalize_ty(outlives, origin.clone())
+                        .map_err(|NoSolution| (outlives, origin.clone()))?
+                        .no_bound_vars()
+                        .expect("started with no bound vars, should end with no bound vars");
+
                 debug!(?sup_type, ?sub_region, ?origin);
 
                 let outlives = &mut TypeOutlives::new(
diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs
index e5a7b27446b..756db7cc206 100644
--- a/compiler/rustc_trait_selection/src/regions.rs
+++ b/compiler/rustc_trait_selection/src/regions.rs
@@ -1,5 +1,6 @@
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{InferCtxt, RegionResolutionError};
+use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::ObligationCause;
 
 pub trait InferCtxtRegionExt<'tcx> {
@@ -24,15 +25,14 @@ impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
             let ty = self.resolve_vars_if_possible(ty);
 
             if self.next_trait_solver() {
-                crate::solve::deeply_normalize_with_skipped_universes(
+                crate::solve::deeply_normalize(
                     self.at(
                         &ObligationCause::dummy_with_span(origin.span()),
                         outlives_env.param_env,
                     ),
                     ty,
-                    vec![None; ty.outer_exclusive_binder().as_usize()],
                 )
-                .map_err(|_| ty)
+                .map_err(|_| NoSolution)
             } else {
                 Ok(ty)
             }
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 7933654a915..81c72fc4b7b 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -179,7 +179,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         }
 
         let outlives_env = OutlivesEnvironment::new(full_env);
-        let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty, _| Ok(ty));
+        let _ = infcx.process_registered_region_obligations(&outlives_env, |ty, _| Ok(ty));
 
         let region_data =
             infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();