1use rustc_hir::def_id::DefId;
2use rustc_middle::traits::solve::Goal;
3use rustc_middle::ty::relate::combine::{combine_ty_args, super_combine_consts, super_combine_tys};
4use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation, relate_args_invariantly};
5use rustc_middle::ty::{self, DelayedSet, Ty, TyCtxt, TyVar};
6use rustc_span::Span;
7use tracing::{debug, instrument};
8
9use crate::infer::BoundRegionConversionTime::HigherRankedType;
10use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
11use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace};
12use crate::traits::{Obligation, PredicateObligations};
13
14pub(crate) struct TypeRelating<'infcx, 'tcx> {
16 infcx: &'infcx InferCtxt<'tcx>,
17
18 trace: TypeTrace<'tcx>,
20 param_env: ty::ParamEnv<'tcx>,
21 define_opaque_types: DefineOpaqueTypes,
22
23 ambient_variance: ty::Variance,
25 obligations: PredicateObligations<'tcx>,
26 cache: DelayedSet<(ty::Variance, Ty<'tcx>, Ty<'tcx>)>,
49}
50
51impl<'infcx, 'tcx> TypeRelating<'infcx, 'tcx> {
52 pub(crate) fn new(
53 infcx: &'infcx InferCtxt<'tcx>,
54 trace: TypeTrace<'tcx>,
55 param_env: ty::ParamEnv<'tcx>,
56 define_opaque_types: DefineOpaqueTypes,
57 ambient_variance: ty::Variance,
58 ) -> TypeRelating<'infcx, 'tcx> {
59 if !!infcx.next_trait_solver {
::core::panicking::panic("assertion failed: !infcx.next_trait_solver")
};assert!(!infcx.next_trait_solver);
60 TypeRelating {
61 infcx,
62 trace,
63 param_env,
64 define_opaque_types,
65 ambient_variance,
66 obligations: PredicateObligations::new(),
67 cache: Default::default(),
68 }
69 }
70
71 pub(crate) fn into_obligations(self) -> PredicateObligations<'tcx> {
72 self.obligations
73 }
74}
75
76impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
77 fn cx(&self) -> TyCtxt<'tcx> {
78 self.infcx.tcx
79 }
80
81 fn relate_ty_args(
82 &mut self,
83 a_ty: Ty<'tcx>,
84 b_ty: Ty<'tcx>,
85 def_id: DefId,
86 a_args: ty::GenericArgsRef<'tcx>,
87 b_args: ty::GenericArgsRef<'tcx>,
88 _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>,
89 ) -> RelateResult<'tcx, Ty<'tcx>> {
90 if self.ambient_variance == ty::Invariant {
91 relate_args_invariantly(self, a_args, b_args)?;
95 Ok(a_ty)
96 } else {
97 let variances = self.cx().variances_of(def_id);
98 combine_ty_args(self.infcx, self, a_ty, b_ty, variances, a_args, b_args, |_| a_ty)
99 }
100 }
101
102 fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
103 &mut self,
104 variance: ty::Variance,
105 _info: ty::VarianceDiagInfo<TyCtxt<'tcx>>,
106 a: T,
107 b: T,
108 ) -> RelateResult<'tcx, T> {
109 let old_ambient_variance = self.ambient_variance;
110 self.ambient_variance = self.ambient_variance.xform(variance);
111 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_infer/src/infer/relate/type_relating.rs:111",
"rustc_infer::infer::relate::type_relating",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/relate/type_relating.rs"),
::tracing_core::__macro_support::Option::Some(111u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::type_relating"),
::tracing_core::field::FieldSet::new(&["message",
"self.ambient_variance"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("new ambient variance")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&self.ambient_variance)
as &dyn Value))])
});
} else { ; }
};debug!(?self.ambient_variance, "new ambient variance");
112
113 let r = if self.ambient_variance == ty::Bivariant { Ok(a) } else { self.relate(a, b) };
114
115 self.ambient_variance = old_ambient_variance;
116 r
117 }
118
119 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("tys",
"rustc_infer::infer::relate::type_relating",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/relate/type_relating.rs"),
::tracing_core::__macro_support::Option::Some(119u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::type_relating"),
::tracing_core::field::FieldSet::new(&["a", "b"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: RelateResult<'tcx, Ty<'tcx>> =
loop {};
return __tracing_attr_fake_return;
}
{
if a == b { return Ok(a); }
let infcx = self.infcx;
let a = infcx.shallow_resolve(a);
let b = infcx.shallow_resolve(b);
if self.cache.contains(&(self.ambient_variance, a, b)) {
return Ok(a);
}
match (a.kind(), b.kind()) {
(&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
match self.ambient_variance {
ty::Covariant => {
self.obligations.push(Obligation::new(self.cx(),
self.trace.cause.clone(), self.param_env,
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
a_is_expected: true,
a,
b,
}))));
}
ty::Contravariant => {
self.obligations.push(Obligation::new(self.cx(),
self.trace.cause.clone(), self.param_env,
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
a_is_expected: false,
a: b,
b: a,
}))));
}
ty::Invariant => {
infcx.inner.borrow_mut().type_variables().equate(a_id,
b_id);
}
ty::Bivariant => {
{
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Expected bivariance to be handled in relate_with_variance")));
}
}
}
}
(&ty::Infer(TyVar(a_vid)), _) => {
infcx.instantiate_ty_var(self, true, a_vid,
self.ambient_variance, b)?;
}
(_, &ty::Infer(TyVar(b_vid))) => {
infcx.instantiate_ty_var(self, false, b_vid,
self.ambient_variance.xform(ty::Contravariant), a)?;
}
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, ..
})) if a_def_id == b_def_id => {
super_combine_tys(infcx, self, a, b)?;
}
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _) |
(_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) if
self.define_opaque_types == DefineOpaqueTypes::Yes &&
def_id.is_local() => {
self.register_goals(infcx.handle_opaque_type(a, b,
self.trace.cause.span, self.param_env())?);
}
_ => { super_combine_tys(infcx, self, a, b)?; }
}
if !self.cache.insert((self.ambient_variance, a, b)) {
::core::panicking::panic("assertion failed: self.cache.insert((self.ambient_variance, a, b))")
};
Ok(a)
}
}
}#[instrument(skip(self), level = "trace")]
120 fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
121 if a == b {
122 return Ok(a);
123 }
124
125 let infcx = self.infcx;
126 let a = infcx.shallow_resolve(a);
127 let b = infcx.shallow_resolve(b);
128
129 if self.cache.contains(&(self.ambient_variance, a, b)) {
130 return Ok(a);
131 }
132
133 match (a.kind(), b.kind()) {
134 (&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
135 match self.ambient_variance {
136 ty::Covariant => {
137 self.obligations.push(Obligation::new(
140 self.cx(),
141 self.trace.cause.clone(),
142 self.param_env,
143 ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
144 a_is_expected: true,
145 a,
146 b,
147 })),
148 ));
149 }
150 ty::Contravariant => {
151 self.obligations.push(Obligation::new(
154 self.cx(),
155 self.trace.cause.clone(),
156 self.param_env,
157 ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
158 a_is_expected: false,
159 a: b,
160 b: a,
161 })),
162 ));
163 }
164 ty::Invariant => {
165 infcx.inner.borrow_mut().type_variables().equate(a_id, b_id);
166 }
167 ty::Bivariant => {
168 unreachable!("Expected bivariance to be handled in relate_with_variance")
169 }
170 }
171 }
172
173 (&ty::Infer(TyVar(a_vid)), _) => {
174 infcx.instantiate_ty_var(self, true, a_vid, self.ambient_variance, b)?;
175 }
176 (_, &ty::Infer(TyVar(b_vid))) => {
177 infcx.instantiate_ty_var(
178 self,
179 false,
180 b_vid,
181 self.ambient_variance.xform(ty::Contravariant),
182 a,
183 )?;
184 }
185
186 (
187 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
188 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
189 ) if a_def_id == b_def_id => {
190 super_combine_tys(infcx, self, a, b)?;
191 }
192
193 (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
194 | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
195 if self.define_opaque_types == DefineOpaqueTypes::Yes && def_id.is_local() =>
196 {
197 self.register_goals(infcx.handle_opaque_type(
198 a,
199 b,
200 self.trace.cause.span,
201 self.param_env(),
202 )?);
203 }
204
205 _ => {
206 super_combine_tys(infcx, self, a, b)?;
207 }
208 }
209
210 assert!(self.cache.insert((self.ambient_variance, a, b)));
211
212 Ok(a)
213 }
214
215 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("regions",
"rustc_infer::infer::relate::type_relating",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/relate/type_relating.rs"),
::tracing_core::__macro_support::Option::Some(215u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::type_relating"),
::tracing_core::field::FieldSet::new(&["a", "b"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
RelateResult<'tcx, ty::Region<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
let origin =
SubregionOrigin::Subtype(Box::new(self.trace.clone()));
match self.ambient_variance {
ty::Covariant => {
self.infcx.inner.borrow_mut().unwrap_region_constraints().make_subregion(origin,
b, a);
}
ty::Contravariant => {
self.infcx.inner.borrow_mut().unwrap_region_constraints().make_subregion(origin,
a, b);
}
ty::Invariant => {
self.infcx.inner.borrow_mut().unwrap_region_constraints().make_eqregion(origin,
a, b);
}
ty::Bivariant => {
{
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Expected bivariance to be handled in relate_with_variance")));
}
}
}
Ok(a)
}
}
}#[instrument(skip(self), level = "trace")]
216 fn regions(
217 &mut self,
218 a: ty::Region<'tcx>,
219 b: ty::Region<'tcx>,
220 ) -> RelateResult<'tcx, ty::Region<'tcx>> {
221 let origin = SubregionOrigin::Subtype(Box::new(self.trace.clone()));
222
223 match self.ambient_variance {
224 ty::Covariant => {
226 self.infcx
227 .inner
228 .borrow_mut()
229 .unwrap_region_constraints()
230 .make_subregion(origin, b, a);
231 }
232 ty::Contravariant => {
234 self.infcx
235 .inner
236 .borrow_mut()
237 .unwrap_region_constraints()
238 .make_subregion(origin, a, b);
239 }
240 ty::Invariant => {
241 self.infcx
242 .inner
243 .borrow_mut()
244 .unwrap_region_constraints()
245 .make_eqregion(origin, a, b);
246 }
247 ty::Bivariant => {
248 unreachable!("Expected bivariance to be handled in relate_with_variance")
249 }
250 }
251
252 Ok(a)
253 }
254
255 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("consts",
"rustc_infer::infer::relate::type_relating",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/relate/type_relating.rs"),
::tracing_core::__macro_support::Option::Some(255u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::relate::type_relating"),
::tracing_core::field::FieldSet::new(&["a", "b"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
RelateResult<'tcx, ty::Const<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{ super_combine_consts(self.infcx, self, a, b) }
}
}#[instrument(skip(self), level = "trace")]
256 fn consts(
257 &mut self,
258 a: ty::Const<'tcx>,
259 b: ty::Const<'tcx>,
260 ) -> RelateResult<'tcx, ty::Const<'tcx>> {
261 super_combine_consts(self.infcx, self, a, b)
262 }
263
264 fn binders<T>(
265 &mut self,
266 a: ty::Binder<'tcx, T>,
267 b: ty::Binder<'tcx, T>,
268 ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
269 where
270 T: Relate<TyCtxt<'tcx>>,
271 {
272 if a == b {
273 } else if let Some(a) = a.no_bound_vars()
275 && let Some(b) = b.no_bound_vars()
276 {
277 self.relate(a, b)?;
278 } else {
279 let span = self.trace.cause.span;
280 let infcx = self.infcx;
281
282 match self.ambient_variance {
283 ty::Covariant => {
299 infcx.enter_forall(b, |b| {
300 let a = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, a);
301 self.relate(a, b)
302 })?;
303 }
304 ty::Contravariant => {
305 infcx.enter_forall(a, |a| {
306 let b = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, b);
307 self.relate(a, b)
308 })?;
309 }
310
311 ty::Invariant => {
322 infcx.enter_forall(b, |b| {
323 let a = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, a);
324 self.relate(a, b)
325 })?;
326
327 infcx.enter_forall(a, |a| {
329 let b = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, b);
330 self.relate(a, b)
331 })?;
332 }
333 ty::Bivariant => {
334 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Expected bivariance to be handled in relate_with_variance")));
}unreachable!("Expected bivariance to be handled in relate_with_variance")
335 }
336 }
337 }
338
339 Ok(a)
340 }
341}
342
343impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
344 fn span(&self) -> Span {
345 self.trace.span()
346 }
347
348 fn param_env(&self) -> ty::ParamEnv<'tcx> {
349 self.param_env
350 }
351
352 fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
353 StructurallyRelateAliases::No
354 }
355
356 fn register_predicates(
357 &mut self,
358 preds: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
359 ) {
360 self.obligations.extend(preds.into_iter().map(|pred| {
361 Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, pred)
362 }))
363 }
364
365 fn register_goals(&mut self, goals: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>) {
366 self.obligations.extend(goals.into_iter().map(|goal| {
367 Obligation::new(
368 self.infcx.tcx,
369 self.trace.cause.clone(),
370 goal.param_env,
371 goal.predicate,
372 )
373 }))
374 }
375
376 fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
377 self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
378 ty::Covariant => ty::PredicateKind::AliasRelate(
379 a.into(),
380 b.into(),
381 ty::AliasRelationDirection::Subtype,
382 ),
383 ty::Contravariant => ty::PredicateKind::AliasRelate(
385 b.into(),
386 a.into(),
387 ty::AliasRelationDirection::Subtype,
388 ),
389 ty::Invariant => ty::PredicateKind::AliasRelate(
390 a.into(),
391 b.into(),
392 ty::AliasRelationDirection::Equate,
393 ),
394 ty::Bivariant => {
395 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Expected bivariance to be handled in relate_with_variance")));
}unreachable!("Expected bivariance to be handled in relate_with_variance")
396 }
397 })]);
398 }
399}