1
Fork 0

Normalize caller bounds

This commit is contained in:
Michael Goulet 2023-12-25 21:37:29 +00:00
parent 028d29301f
commit fef38a6337
4 changed files with 32 additions and 10 deletions

View file

@ -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::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{GenericArgKind, ToPredicate};
use rustc_span::DUMMY_SP;
use smallvec::smallvec;
use super::env::OutlivesEnvironment;
@ -131,6 +132,25 @@ impl<'tcx> InferCtxt<'tcx> {
) -> Result<(), (E, SubregionOrigin<'tcx>)> {
assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
let normalized_caller_bounds: Vec<_> = outlives_env
.param_env
.caller_bounds()
.iter()
.filter_map(|clause| {
let bound_clause = clause.kind();
let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else {
return None;
};
Some(deeply_normalize_ty(outlives.0).map(|ty| {
bound_clause
.rebind(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, outlives.1)))
.to_predicate(self.tcx)
}))
})
// FIXME: How do we accurately report an error here :(
.try_collect()
.map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
let my_region_obligations = self.take_registered_region_obligations();
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
@ -142,7 +162,7 @@ impl<'tcx> InferCtxt<'tcx> {
self.tcx,
outlives_env.region_bound_pairs(),
None,
outlives_env.param_env,
&normalized_caller_bounds,
);
let category = origin.to_constraint_category();
outlives.type_must_outlive(origin, sup_type, sub_region, category);
@ -196,7 +216,7 @@ where
tcx: TyCtxt<'tcx>,
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>,
caller_bounds: &'cx [ty::Clause<'tcx>],
) -> Self {
Self {
delegate,
@ -205,7 +225,7 @@ where
tcx,
region_bound_pairs,
implicit_region_bound,
param_env,
caller_bounds,
),
}
}

View file

@ -23,7 +23,7 @@ pub struct VerifyBoundCx<'cx, 'tcx> {
/// Outside of borrowck the only way to prove `T: '?0` is by
/// setting `'?0` to `'empty`.
implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>,
caller_bounds: &'cx [ty::Clause<'tcx>],
}
impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
@ -31,9 +31,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
tcx: TyCtxt<'tcx>,
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>,
caller_bounds: &'cx [ty::Clause<'tcx>],
) -> Self {
Self { tcx, region_bound_pairs, implicit_region_bound, param_env }
Self { tcx, region_bound_pairs, implicit_region_bound, caller_bounds }
}
#[instrument(level = "debug", skip(self))]
@ -219,8 +219,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
// To start, collect bounds from user environment. Note that
// parameter environments are already elaborated, so we don't
// have to worry about that.
let c_b = self.param_env.caller_bounds();
let param_bounds = self.collect_outlives_from_clause_list(erased_ty, c_b.into_iter());
let param_bounds =
self.collect_outlives_from_clause_list(erased_ty, self.caller_bounds.iter().copied());
// Next, collect regions we scraped from the well-formedness
// constraints in the fn signature. To do that, we walk the list

View file

@ -21,6 +21,7 @@
#![feature(extend_one)]
#![feature(let_chains)]
#![feature(if_let_guard)]
#![feature(iterator_try_collect)]
#![feature(min_specialization)]
#![feature(try_blocks)]
#![recursion_limit = "512"] // For rustdoc