Skip to content

Commit

Permalink
Normalize caller bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jan 30, 2024
1 parent 028d293 commit fef38a6
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
tcx,
region_bound_pairs,
Some(implicit_region_bound),
param_env,
// FIXME(-Znext-solver): These bounds are not normalized!
param_env.caller_bounds(),
)
.type_must_outlive(origin, t1, r2, constraint_category);
}
Expand Down
28 changes: 24 additions & 4 deletions compiler/rustc_infer/src/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -205,7 +225,7 @@ where
tcx,
region_bound_pairs,
implicit_region_bound,
param_env,
caller_bounds,
),
}
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_infer/src/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ 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> {
pub fn new(
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))]
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit fef38a6

Please sign in to comment.