hir_ty/next_solver/infer/outlives/
obligations.rs

1use ena::undo_log::UndoLogs;
2use rustc_type_ir::{OutlivesPredicate, TypeVisitableExt};
3use tracing::{debug, instrument};
4
5use crate::next_solver::{
6    ArgOutlivesPredicate, GenericArg, Region, RegionOutlivesPredicate, Ty,
7    infer::{InferCtxt, TypeOutlivesConstraint, snapshot::undo_log::UndoLog},
8};
9
10impl<'db> InferCtxt<'db> {
11    pub fn register_outlives_constraint(
12        &self,
13        OutlivesPredicate(arg, r2): ArgOutlivesPredicate<'db>,
14    ) {
15        match arg {
16            GenericArg::Lifetime(r1) => {
17                self.register_region_outlives_constraint(OutlivesPredicate(r1, r2));
18            }
19            GenericArg::Ty(ty1) => {
20                self.register_type_outlives_constraint(ty1, r2);
21            }
22            GenericArg::Const(_) => unreachable!(),
23        }
24    }
25
26    pub fn register_region_outlives_constraint(
27        &self,
28        OutlivesPredicate(r_a, r_b): RegionOutlivesPredicate<'db>,
29    ) {
30        // `'a: 'b` ==> `'b <= 'a`
31        self.sub_regions(r_b, r_a);
32    }
33
34    /// Registers that the given region obligation must be resolved
35    /// from within the scope of `body_id`. These regions are enqueued
36    /// and later processed by regionck, when full type information is
37    /// available (see `region_obligations` field for more
38    /// information).
39    #[instrument(level = "debug", skip(self))]
40    pub fn register_type_outlives_constraint_inner(&self, obligation: TypeOutlivesConstraint<'db>) {
41        let mut inner = self.inner.borrow_mut();
42        inner.undo_log.push(UndoLog::PushTypeOutlivesConstraint);
43        inner.region_obligations.push(obligation);
44    }
45
46    pub fn register_type_outlives_constraint(&self, sup_type: Ty<'db>, sub_region: Region<'db>) {
47        // `is_global` means the type has no params, infer, placeholder, or non-`'static`
48        // free regions. If the type has none of these things, then we can skip registering
49        // this outlives obligation since it has no components which affect lifetime
50        // checking in an interesting way.
51        if sup_type.is_global() {
52            return;
53        }
54
55        debug!(?sup_type, ?sub_region);
56
57        self.register_type_outlives_constraint_inner(TypeOutlivesConstraint {
58            sup_type,
59            sub_region,
60        });
61    }
62
63    pub fn register_region_assumption(&self, assumption: ArgOutlivesPredicate<'db>) {
64        let mut inner = self.inner.borrow_mut();
65        inner.undo_log.push(UndoLog::PushRegionAssumption);
66        inner.region_assumptions.push(assumption);
67    }
68}