Move required_region_bounds to rustc::infer::opaque_types.
This commit is contained in:
parent
24d09c7c1b
commit
86ec4b5f85
3 changed files with 70 additions and 68 deletions
|
@ -350,7 +350,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
debug!("constrain_opaque_type: bounds={:#?}", bounds);
|
||||
let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs);
|
||||
|
||||
let required_region_bounds = tcx.required_region_bounds(opaque_type, bounds.predicates);
|
||||
let required_region_bounds =
|
||||
required_region_bounds(tcx, opaque_type, bounds.predicates);
|
||||
debug_assert!(!required_region_bounds.is_empty());
|
||||
|
||||
for required_region in required_region_bounds {
|
||||
|
@ -1133,7 +1134,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
|||
|
||||
debug!("instantiate_opaque_types: bounds={:?}", bounds);
|
||||
|
||||
let required_region_bounds = tcx.required_region_bounds(ty, bounds.predicates.clone());
|
||||
let required_region_bounds = required_region_bounds(tcx, ty, bounds.predicates.clone());
|
||||
debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds);
|
||||
|
||||
// Make sure that we are in fact defining the *entire* type
|
||||
|
@ -1228,3 +1229,67 @@ pub fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: DefId, opaque_hir_id: hir
|
|||
);
|
||||
res
|
||||
}
|
||||
|
||||
/// Given a set of predicates that apply to an object type, returns
|
||||
/// the region bounds that the (erased) `Self` type must
|
||||
/// outlive. Precisely *because* the `Self` type is erased, the
|
||||
/// parameter `erased_self_ty` must be supplied to indicate what type
|
||||
/// has been used to represent `Self` in the predicates
|
||||
/// themselves. This should really be a unique type; `FreshTy(0)` is a
|
||||
/// popular choice.
|
||||
///
|
||||
/// N.B., in some cases, particularly around higher-ranked bounds,
|
||||
/// this function returns a kind of conservative approximation.
|
||||
/// That is, all regions returned by this function are definitely
|
||||
/// required, but there may be other region bounds that are not
|
||||
/// returned, as well as requirements like `for<'a> T: 'a`.
|
||||
///
|
||||
/// Requires that trait definitions have been processed so that we can
|
||||
/// elaborate predicates and walk supertraits.
|
||||
//
|
||||
// FIXME: callers may only have a `&[Predicate]`, not a `Vec`, so that's
|
||||
// what this code should accept.
|
||||
crate fn required_region_bounds(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
erased_self_ty: Ty<'tcx>,
|
||||
predicates: Vec<ty::Predicate<'tcx>>,
|
||||
) -> Vec<ty::Region<'tcx>> {
|
||||
debug!(
|
||||
"required_region_bounds(erased_self_ty={:?}, predicates={:?})",
|
||||
erased_self_ty, predicates
|
||||
);
|
||||
|
||||
assert!(!erased_self_ty.has_escaping_bound_vars());
|
||||
|
||||
traits::elaborate_predicates(tcx, predicates)
|
||||
.filter_map(|predicate| {
|
||||
match predicate {
|
||||
ty::Predicate::Projection(..)
|
||||
| ty::Predicate::Trait(..)
|
||||
| ty::Predicate::Subtype(..)
|
||||
| ty::Predicate::WellFormed(..)
|
||||
| ty::Predicate::ObjectSafe(..)
|
||||
| ty::Predicate::ClosureKind(..)
|
||||
| ty::Predicate::RegionOutlives(..)
|
||||
| ty::Predicate::ConstEvaluatable(..) => None,
|
||||
ty::Predicate::TypeOutlives(predicate) => {
|
||||
// Search for a bound of the form `erased_self_ty
|
||||
// : 'a`, but be wary of something like `for<'a>
|
||||
// erased_self_ty : 'a` (we interpret a
|
||||
// higher-ranked bound like that as 'static,
|
||||
// though at present the code in `fulfill.rs`
|
||||
// considers such bounds to be unsatisfiable, so
|
||||
// it's kind of a moot point since you could never
|
||||
// construct such an object, but this seems
|
||||
// correct even if that code changes).
|
||||
let ty::OutlivesPredicate(ref t, ref r) = predicate.skip_binder();
|
||||
if t == &erased_self_ty && !r.has_escaping_bound_vars() {
|
||||
Some(*r)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::infer::opaque_types::required_region_bounds;
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::middle::lang_items;
|
||||
use crate::traits::{self, AssocTypeBoundData};
|
||||
|
@ -668,7 +669,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
/// from the declarations of `SomeTrait`, `Send`, and friends -- if
|
||||
/// they declare `trait SomeTrait : 'static`, for example, then
|
||||
/// `'static` would appear in the list. The hard work is done by
|
||||
/// `ty::required_region_bounds`, see that for more information.
|
||||
/// `infer::required_region_bounds`, see that for more information.
|
||||
pub fn object_region_bounds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
existential_predicates: ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
|
||||
|
@ -689,7 +690,7 @@ pub fn object_region_bounds<'tcx>(
|
|||
})
|
||||
.collect();
|
||||
|
||||
tcx.required_region_bounds(open_ty, predicates)
|
||||
required_region_bounds(tcx, open_ty, predicates)
|
||||
}
|
||||
|
||||
/// Find the span of a generic bound affecting an associated type.
|
||||
|
|
|
@ -393,70 +393,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
(a, b)
|
||||
}
|
||||
|
||||
/// Given a set of predicates that apply to an object type, returns
|
||||
/// the region bounds that the (erased) `Self` type must
|
||||
/// outlive. Precisely *because* the `Self` type is erased, the
|
||||
/// parameter `erased_self_ty` must be supplied to indicate what type
|
||||
/// has been used to represent `Self` in the predicates
|
||||
/// themselves. This should really be a unique type; `FreshTy(0)` is a
|
||||
/// popular choice.
|
||||
///
|
||||
/// N.B., in some cases, particularly around higher-ranked bounds,
|
||||
/// this function returns a kind of conservative approximation.
|
||||
/// That is, all regions returned by this function are definitely
|
||||
/// required, but there may be other region bounds that are not
|
||||
/// returned, as well as requirements like `for<'a> T: 'a`.
|
||||
///
|
||||
/// Requires that trait definitions have been processed so that we can
|
||||
/// elaborate predicates and walk supertraits.
|
||||
//
|
||||
// FIXME: callers may only have a `&[Predicate]`, not a `Vec`, so that's
|
||||
// what this code should accept.
|
||||
pub fn required_region_bounds(
|
||||
self,
|
||||
erased_self_ty: Ty<'tcx>,
|
||||
predicates: Vec<ty::Predicate<'tcx>>,
|
||||
) -> Vec<ty::Region<'tcx>> {
|
||||
debug!(
|
||||
"required_region_bounds(erased_self_ty={:?}, predicates={:?})",
|
||||
erased_self_ty, predicates
|
||||
);
|
||||
|
||||
assert!(!erased_self_ty.has_escaping_bound_vars());
|
||||
|
||||
traits::elaborate_predicates(self, predicates)
|
||||
.filter_map(|predicate| {
|
||||
match predicate {
|
||||
ty::Predicate::Projection(..)
|
||||
| ty::Predicate::Trait(..)
|
||||
| ty::Predicate::Subtype(..)
|
||||
| ty::Predicate::WellFormed(..)
|
||||
| ty::Predicate::ObjectSafe(..)
|
||||
| ty::Predicate::ClosureKind(..)
|
||||
| ty::Predicate::RegionOutlives(..)
|
||||
| ty::Predicate::ConstEvaluatable(..) => None,
|
||||
ty::Predicate::TypeOutlives(predicate) => {
|
||||
// Search for a bound of the form `erased_self_ty
|
||||
// : 'a`, but be wary of something like `for<'a>
|
||||
// erased_self_ty : 'a` (we interpret a
|
||||
// higher-ranked bound like that as 'static,
|
||||
// though at present the code in `fulfill.rs`
|
||||
// considers such bounds to be unsatisfiable, so
|
||||
// it's kind of a moot point since you could never
|
||||
// construct such an object, but this seems
|
||||
// correct even if that code changes).
|
||||
let ty::OutlivesPredicate(ref t, ref r) = predicate.skip_binder();
|
||||
if t == &erased_self_ty && !r.has_escaping_bound_vars() {
|
||||
Some(*r)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Calculate the destructor of a given type.
|
||||
pub fn calculate_dtor(
|
||||
self,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue