1 use rustc_infer
::infer
::nll_relate
::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}
;
2 use rustc_infer
::infer
::{InferCtxt, NllRegionVariableOrigin}
;
3 use rustc_middle
::mir
::ConstraintCategory
;
4 use rustc_middle
::ty
::relate
::TypeRelation
;
5 use rustc_middle
::ty
::{self, Const, Ty}
;
6 use rustc_trait_selection
::traits
::query
::Fallible
;
8 use crate::borrow_check
::constraints
::OutlivesConstraint
;
9 use crate::borrow_check
::type_check
::{BorrowCheckContext, Locations}
;
11 /// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`:
13 /// - "Covariant" `a <: b`
14 /// - "Invariant" `a == b`
15 /// - "Contravariant" `a :> b`
17 /// N.B., the type `a` is permitted to have unresolved inference
18 /// variables, but not the type `b`.
19 pub(super) fn relate_types
<'tcx
>(
20 infcx
: &InferCtxt
<'_
, 'tcx
>,
21 param_env
: ty
::ParamEnv
<'tcx
>,
26 category
: ConstraintCategory
,
27 borrowck_context
: Option
<&mut BorrowCheckContext
<'_
, 'tcx
>>,
29 debug
!("relate_types(a={:?}, v={:?}, b={:?}, locations={:?})", a
, v
, b
, locations
);
32 NllTypeRelatingDelegate
::new(infcx
, borrowck_context
, param_env
, locations
, category
),
39 struct NllTypeRelatingDelegate
<'me
, 'bccx
, 'tcx
> {
40 infcx
: &'me InferCtxt
<'me
, 'tcx
>,
41 borrowck_context
: Option
<&'me
mut BorrowCheckContext
<'bccx
, 'tcx
>>,
43 param_env
: ty
::ParamEnv
<'tcx
>,
45 /// Where (and why) is this relation taking place?
48 /// What category do we assign the resulting `'a: 'b` relationships?
49 category
: ConstraintCategory
,
52 impl NllTypeRelatingDelegate
<'me
, 'bccx
, 'tcx
> {
54 infcx
: &'me InferCtxt
<'me
, 'tcx
>,
55 borrowck_context
: Option
<&'me
mut BorrowCheckContext
<'bccx
, 'tcx
>>,
56 param_env
: ty
::ParamEnv
<'tcx
>,
58 category
: ConstraintCategory
,
60 Self { infcx, borrowck_context, param_env, locations, category }
64 impl TypeRelatingDelegate
<'tcx
> for NllTypeRelatingDelegate
<'_
, '_
, 'tcx
> {
65 fn param_env(&self) -> ty
::ParamEnv
<'tcx
> {
69 fn create_next_universe(&mut self) -> ty
::UniverseIndex
{
70 self.infcx
.create_next_universe()
73 fn next_existential_region_var(&mut self, from_forall
: bool
) -> ty
::Region
<'tcx
> {
74 if self.borrowck_context
.is_some() {
75 let origin
= NllRegionVariableOrigin
::Existential { from_forall }
;
76 self.infcx
.next_nll_region_var(origin
)
78 self.infcx
.tcx
.lifetimes
.re_erased
82 fn next_placeholder_region(&mut self, placeholder
: ty
::PlaceholderRegion
) -> ty
::Region
<'tcx
> {
83 if let Some(borrowck_context
) = &mut self.borrowck_context
{
84 borrowck_context
.constraints
.placeholder_region(self.infcx
, placeholder
)
86 self.infcx
.tcx
.lifetimes
.re_erased
90 fn generalize_existential(&mut self, universe
: ty
::UniverseIndex
) -> ty
::Region
<'tcx
> {
91 self.infcx
.next_nll_region_var_in_universe(
92 NllRegionVariableOrigin
::Existential { from_forall: false }
,
97 fn push_outlives(&mut self, sup
: ty
::Region
<'tcx
>, sub
: ty
::Region
<'tcx
>) {
98 if let Some(borrowck_context
) = &mut self.borrowck_context
{
99 let sub
= borrowck_context
.universal_regions
.to_region_vid(sub
);
100 let sup
= borrowck_context
.universal_regions
.to_region_vid(sup
);
101 borrowck_context
.constraints
.outlives_constraints
.push(OutlivesConstraint
{
104 locations
: self.locations
,
105 category
: self.category
,
110 // We don't have to worry about the equality of consts during borrow checking
111 // as consts always have a static lifetime.
112 fn const_equate(&mut self, _a
: &'tcx Const
<'tcx
>, _b
: &'tcx Const
<'tcx
>) {}
114 fn normalization() -> NormalizationStrategy
{
115 NormalizationStrategy
::Eager
118 fn forbid_inference_vars() -> bool
{