diff options
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.rs | 1 | ||||
-rw-r--r-- | compiler/rustc_typeck/src/outlives/utils.rs | 6 |
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); |