summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_typeck/src/outlives
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs (renamed from compiler/rustc_typeck/src/outlives/outlives_bounds.rs)41
-rw-r--r--compiler/rustc_typeck/src/outlives/mod.rs1
-rw-r--r--compiler/rustc_typeck/src/outlives/utils.rs6
3 files changed, 33 insertions, 15 deletions
diff --git a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 229a64650..3008dfcad 100644
--- a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -1,22 +1,32 @@
+use crate::infer::InferCtxt;
+use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput};
+use crate::traits::query::NoSolution;
+use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt};
+use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
-use rustc_middle::ty::{self, Ty};
-use rustc_trait_selection::infer::InferCtxt;
-use rustc_trait_selection::traits::query::type_op::{self, TypeOp, TypeOpOutput};
-use rustc_trait_selection::traits::query::NoSolution;
-use rustc_trait_selection::traits::{ObligationCause, TraitEngine, TraitEngineExt};
+use rustc_hir::HirId;
+use rustc_middle::ty::{self, ParamEnv, Ty};
pub use rustc_middle::traits::query::OutlivesBound;
-pub trait InferCtxtExt<'tcx> {
+type Bounds<'a, 'tcx: 'a> = impl Iterator<Item = OutlivesBound<'tcx>> + 'a;
+pub trait InferCtxtExt<'a, 'tcx> {
fn implied_outlives_bounds(
&self,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
ty: Ty<'tcx>,
) -> Vec<OutlivesBound<'tcx>>;
+
+ fn implied_bounds_tys(
+ &'a self,
+ param_env: ty::ParamEnv<'tcx>,
+ body_id: hir::HirId,
+ tys: FxHashSet<Ty<'tcx>>,
+ ) -> Bounds<'a, 'tcx>;
}
-impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
+impl<'a, 'cx, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'cx, 'tcx> {
/// Implied bounds are region relationships that we deduce
/// automatically. The idea is that (e.g.) a caller must check that a
/// function's argument types are well-formed immediately before
@@ -36,7 +46,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
/// Note that this may cause outlives obligations to be injected
/// into the inference context with this body-id.
/// - `ty`, the type that we are supposed to assume is WF.
- #[instrument(level = "debug", skip(self, param_env, body_id))]
+ #[instrument(level = "debug", skip(self, param_env, body_id), ret)]
fn implied_outlives_bounds(
&self,
param_env: ty::ParamEnv<'tcx>,
@@ -61,6 +71,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
let TypeOpOutput { output, constraints, .. } = result;
if let Some(constraints) = constraints {
+ debug!(?constraints);
// Instantiation may have produced new inference variables and constraints on those
// variables. Process these constraints.
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self.tcx);
@@ -87,4 +98,18 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
output
}
+
+ fn implied_bounds_tys(
+ &'a self,
+ param_env: ParamEnv<'tcx>,
+ body_id: HirId,
+ tys: FxHashSet<Ty<'tcx>>,
+ ) -> Bounds<'a, 'tcx> {
+ tys.into_iter()
+ .map(move |ty| {
+ let ty = self.resolve_vars_if_possible(ty);
+ self.implied_outlives_bounds(param_env, body_id, ty)
+ })
+ .flatten()
+ }
}
diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs
index 8fa65d51e..e50c26765 100644
--- a/compiler/rustc_typeck/src/outlives/mod.rs
+++ b/compiler/rustc_typeck/src/outlives/mod.rs
@@ -9,7 +9,6 @@ use rustc_span::Span;
mod explicit;
mod implicit_infer;
-pub(crate) mod outlives_bounds;
/// Code to write unit test for outlives.
pub mod test;
mod utils;
diff --git a/compiler/rustc_typeck/src/outlives/utils.rs b/compiler/rustc_typeck/src/outlives/utils.rs
index b718ca942..3e8d023fb 100644
--- a/compiler/rustc_typeck/src/outlives/utils.rs
+++ b/compiler/rustc_typeck/src/outlives/utils.rs
@@ -161,12 +161,6 @@ fn is_free_region(region: Region<'_>) -> bool {
// ignore it. We can't put it on the struct header anyway.
ty::ReLateBound(..) => false,
- // This can appear in `where Self: ` bounds (#64855):
- //
- // struct Bar<T>(<Self as Foo>::Type) where Self: ;
- // struct Baz<'a>(&'a Self) where Self: ;
- ty::ReEmpty(_) => false,
-
// These regions don't appear in types from type declarations:
ty::ReErased | ty::ReVar(..) | ty::RePlaceholder(..) | ty::ReFree(..) => {
bug!("unexpected region in outlives inference: {:?}", region);