Struct rustc_infer::infer::nll_relate::TypeRelating
source · pub struct TypeRelating<'me, 'tcx, D>where
D: TypeRelatingDelegate<'tcx>,{
infcx: &'me InferCtxt<'me, 'tcx>,
delegate: D,
ambient_variance: Variance,
ambient_variance_info: VarianceDiagInfo<'tcx>,
a_scopes: Vec<BoundRegionScope<'tcx>>,
b_scopes: Vec<BoundRegionScope<'tcx>>,
}
Fields
infcx: &'me InferCtxt<'me, 'tcx>
delegate: D
Callback to use when we deduce an outlives relationship.
ambient_variance: Variance
How are we relating a
and b
?
- Covariant means
a <: b
. - Contravariant means
b <: a
. - Invariant means `a == b.
- Bivariant means that it doesn’t matter.
ambient_variance_info: VarianceDiagInfo<'tcx>
a_scopes: Vec<BoundRegionScope<'tcx>>
When we pass through a set of binders (e.g., when looking into
a fn
type), we push a new bound region scope onto here. This
will contain the instantiated region for each region in those
binders. When we then encounter a ReLateBound(d, br)
, we can
use the De Bruijn index d
to find the right scope, and then
bound region name br
to find the specific instantiation from
within that scope. See replace_bound_region
.
This field stores the instantiations for late-bound regions in
the a
type.
b_scopes: Vec<BoundRegionScope<'tcx>>
Same as a_scopes
, but for the b
type.
Implementations
sourceimpl<'me, 'tcx, D> TypeRelating<'me, 'tcx, D>where
D: TypeRelatingDelegate<'tcx>,
impl<'me, 'tcx, D> TypeRelating<'me, 'tcx, D>where
D: TypeRelatingDelegate<'tcx>,
pub fn new(
infcx: &'me InferCtxt<'me, 'tcx>,
delegate: D,
ambient_variance: Variance
) -> Self
fn ambient_covariance(&self) -> bool
fn ambient_contravariance(&self) -> bool
fn create_scope(
&mut self,
value: Binder<'tcx, impl Relate<'tcx>>,
universally_quantified: UniversallyQuantified
) -> BoundRegionScope<'tcx>
sourcefn lookup_bound_region(
debruijn: DebruijnIndex,
br: &BoundRegion,
first_free_index: DebruijnIndex,
scopes: &[BoundRegionScope<'tcx>]
) -> Region<'tcx>
fn lookup_bound_region(
debruijn: DebruijnIndex,
br: &BoundRegion,
first_free_index: DebruijnIndex,
scopes: &[BoundRegionScope<'tcx>]
) -> Region<'tcx>
When we encounter binders during the type traversal, we record
the value to substitute for each of the things contained in
that binder. (This will be either a universal placeholder or
an existential inference variable.) Given the De Bruijn index
debruijn
(and name br
) of some binder we have now
encountered, this routine finds the value that we instantiated
the region with; to do so, it indexes backwards into the list
of ambient scopes scopes
.
sourcefn replace_bound_region(
&self,
r: Region<'tcx>,
first_free_index: DebruijnIndex,
scopes: &[BoundRegionScope<'tcx>]
) -> Region<'tcx>
fn replace_bound_region(
&self,
r: Region<'tcx>,
first_free_index: DebruijnIndex,
scopes: &[BoundRegionScope<'tcx>]
) -> Region<'tcx>
If r
is a bound region, find the scope in which it is bound
(from scopes
) and return the value that we instantiated it
with. Otherwise just return r
.
sourcefn push_outlives(
&mut self,
sup: Region<'tcx>,
sub: Region<'tcx>,
info: VarianceDiagInfo<'tcx>
)
fn push_outlives(
&mut self,
sup: Region<'tcx>,
sub: Region<'tcx>,
info: VarianceDiagInfo<'tcx>
)
Push a new outlives requirement into our output set of constraints.
sourcefn relate_projection_ty(
&mut self,
projection_ty: ProjectionTy<'tcx>,
value_ty: Ty<'tcx>
) -> Ty<'tcx>
fn relate_projection_ty(
&mut self,
projection_ty: ProjectionTy<'tcx>,
value_ty: Ty<'tcx>
) -> Ty<'tcx>
Relate a projection type and some value type lazily. This will always
succeed, but we push an additional ProjectionEq
goal depending
on the value type:
- if the value type is any type
T
which is not a projection, we pushProjectionEq(projection = T)
. - if the value type is another projection
other_projection
, we create a new inference variable?U
and push the two goalsProjectionEq(projection = ?U)
,ProjectionEq(other_projection = ?U)
.
sourcefn relate_ty_var<PAIR: VidValuePair<'tcx>>(
&mut self,
pair: PAIR
) -> RelateResult<'tcx, Ty<'tcx>>
fn relate_ty_var<PAIR: VidValuePair<'tcx>>(
&mut self,
pair: PAIR
) -> RelateResult<'tcx, Ty<'tcx>>
Relate a type inference variable with a value type. This works
by creating a “generalization” G of the value where all the
lifetimes are replaced with fresh inference values. This
generalization G becomes the value of the inference variable,
and is then related in turn to the value. So e.g. if you had
vid = ?0
and value = &'a u32
, we might first instantiate
?0
to a type like &'0 u32
where '0
is a fresh variable,
and then relate &'0 u32
with &'a u32
(resulting in
relations between '0
and 'a
).
The variable pair
can be either a (vid, ty)
or (ty, vid)
– in other words, it is always an (unresolved) inference
variable vid
and a type ty
that are being related, but the
vid may appear either as the “a” type or the “b” type,
depending on where it appears in the tuple. The trait
VidValuePair
lets us work with the vid/type while preserving
the “sidedness” when necessary – the sidedness is relevant in
particular for the variance and set of in-scope things.
fn generalize_value<T: Relate<'tcx>>(
&mut self,
value: T,
for_vid: TyVid
) -> RelateResult<'tcx, T>
fn relate_opaques(
&mut self,
a: Ty<'tcx>,
b: Ty<'tcx>
) -> RelateResult<'tcx, Ty<'tcx>>
Trait Implementations
sourceimpl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D>where
D: TypeRelatingDelegate<'tcx>,
impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D>where
D: TypeRelatingDelegate<'tcx>,
sourcefn const_equate_obligation(&mut self, a: Const<'tcx>, b: Const<'tcx>)
fn const_equate_obligation(&mut self, a: Const<'tcx>, b: Const<'tcx>)
sourceimpl<'tcx, D> TypeRelation<'tcx> for TypeRelating<'_, 'tcx, D>where
D: TypeRelatingDelegate<'tcx>,
impl<'tcx, D> TypeRelation<'tcx> for TypeRelating<'_, 'tcx, D>where
D: TypeRelatingDelegate<'tcx>,
fn tcx(&self) -> TyCtxt<'tcx>
fn param_env(&self) -> ParamEnv<'tcx>
sourcefn a_is_expected(&self) -> bool
fn a_is_expected(&self) -> bool
true
if the value a
is the “expected” type in the
relation. Just affects error messages. Read moresourcefn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: Variance,
info: VarianceDiagInfo<'tcx>,
a: T,
b: T
) -> RelateResult<'tcx, T>
fn relate_with_variance<T: Relate<'tcx>>(
&mut self,
variance: Variance,
info: VarianceDiagInfo<'tcx>,
a: T,
b: T
) -> RelateResult<'tcx, T>
a
and b
.fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>>
fn regions(
&mut self,
a: Region<'tcx>,
b: Region<'tcx>
) -> RelateResult<'tcx, Region<'tcx>>
fn consts(
&mut self,
a: Const<'tcx>,
b: Const<'tcx>
) -> RelateResult<'tcx, Const<'tcx>>
fn binders<T>(
&mut self,
a: Binder<'tcx, T>,
b: Binder<'tcx, T>
) -> RelateResult<'tcx, Binder<'tcx, T>>where
T: Relate<'tcx>,
fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> Rwhere
F: FnOnce(&mut Self) -> R,
sourcefn relate<T>(&mut self, a: T, b: T) -> Result<T, TypeError<'tcx>>where
T: Relate<'tcx>,
fn relate<T>(&mut self, a: T, b: T) -> Result<T, TypeError<'tcx>>where
T: Relate<'tcx>,
sourcefn relate_item_substs(
&mut self,
item_def_id: DefId,
a_subst: &'tcx List<GenericArg<'tcx>>,
b_subst: &'tcx List<GenericArg<'tcx>>
) -> Result<&'tcx List<GenericArg<'tcx>>, TypeError<'tcx>>
fn relate_item_substs(
&mut self,
item_def_id: DefId,
a_subst: &'tcx List<GenericArg<'tcx>>,
b_subst: &'tcx List<GenericArg<'tcx>>
) -> Result<&'tcx List<GenericArg<'tcx>>, TypeError<'tcx>>
Auto Trait Implementations
impl<'me, 'tcx, D> !RefUnwindSafe for TypeRelating<'me, 'tcx, D>
impl<'me, 'tcx, D> !Send for TypeRelating<'me, 'tcx, D>
impl<'me, 'tcx, D> !Sync for TypeRelating<'me, 'tcx, D>
impl<'me, 'tcx, D> Unpin for TypeRelating<'me, 'tcx, D>where
D: Unpin,
'tcx: 'me,
impl<'me, 'tcx, D> !UnwindSafe for TypeRelating<'me, 'tcx, D>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
Layout
Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.