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, TypeVisitableExt};
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 true {
if !!a.has_rigid_aliases() {
::core::panicking::panic("assertion failed: !a.has_rigid_aliases()")
};
};
if true {
if !!b.has_rigid_aliases() {
::core::panicking::panic("assertion failed: !b.has_rigid_aliases()")
};
};
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::AliasTy {
kind: ty::Opaque { def_id: a_def_id }, .. }),
&ty::Alias(_, ty::AliasTy {
kind: ty::Opaque { def_id: b_def_id }, .. })) if
a_def_id == b_def_id => {
super_combine_tys(infcx, self, a, b)?;
}
(&ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, ..
}), _) |
(_,
&ty::Alias(_, ty::AliasTy { kind: ty::Opaque { 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 debug_assert!(!a.has_rigid_aliases());
123 debug_assert!(!b.has_rigid_aliases());
124
125 if a == b {
126 return Ok(a);
127 }
128
129 let infcx = self.infcx;
130 let a = infcx.shallow_resolve(a);
131 let b = infcx.shallow_resolve(b);
132
133 if self.cache.contains(&(self.ambient_variance, a, b)) {
134 return Ok(a);
135 }
136
137 match (a.kind(), b.kind()) {
138 (&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
139 match self.ambient_variance {
140 ty::Covariant => {
141 self.obligations.push(Obligation::new(
144 self.cx(),
145 self.trace.cause.clone(),
146 self.param_env,
147 ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
148 a_is_expected: true,
149 a,
150 b,
151 })),
152 ));
153 }
154 ty::Contravariant => {
155 self.obligations.push(Obligation::new(
158 self.cx(),
159 self.trace.cause.clone(),
160 self.param_env,
161 ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
162 a_is_expected: false,
163 a: b,
164 b: a,
165 })),
166 ));
167 }
168 ty::Invariant => {
169 infcx.inner.borrow_mut().type_variables().equate(a_id, b_id);
170 }
171 ty::Bivariant => {
172 unreachable!("Expected bivariance to be handled in relate_with_variance")
173 }
174 }
175 }
176
177 (&ty::Infer(TyVar(a_vid)), _) => {
178 infcx.instantiate_ty_var(self, true, a_vid, self.ambient_variance, b)?;
179 }
180 (_, &ty::Infer(TyVar(b_vid))) => {
181 infcx.instantiate_ty_var(
182 self,
183 false,
184 b_vid,
185 self.ambient_variance.xform(ty::Contravariant),
186 a,
187 )?;
188 }
189
190 (
191 &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id: a_def_id }, .. }),
192 &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id: b_def_id }, .. }),
193 ) if a_def_id == b_def_id => {
194 super_combine_tys(infcx, self, a, b)?;
195 }
196
197 (&ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }), _)
198 | (_, &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }))
199 if self.define_opaque_types == DefineOpaqueTypes::Yes && def_id.is_local() =>
200 {
201 self.register_goals(infcx.handle_opaque_type(
202 a,
203 b,
204 self.trace.cause.span,
205 self.param_env(),
206 )?);
207 }
208
209 _ => {
210 super_combine_tys(infcx, self, a, b)?;
211 }
212 }
213
214 assert!(self.cache.insert((self.ambient_variance, a, b)));
215
216 Ok(a)
217 }
218
219 #[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(219u32),
::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::VisibleForLeakCheck::Yes);
}
ty::Contravariant => {
self.infcx.inner.borrow_mut().unwrap_region_constraints().make_subregion(origin,
a, b, ty::VisibleForLeakCheck::Yes);
}
ty::Invariant => {
self.infcx.inner.borrow_mut().unwrap_region_constraints().make_eqregion(origin,
a, b, ty::VisibleForLeakCheck::Yes);
}
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")]
220 fn regions(
221 &mut self,
222 a: ty::Region<'tcx>,
223 b: ty::Region<'tcx>,
224 ) -> RelateResult<'tcx, ty::Region<'tcx>> {
225 let origin = SubregionOrigin::Subtype(Box::new(self.trace.clone()));
226
227 match self.ambient_variance {
228 ty::Covariant => {
230 self.infcx.inner.borrow_mut().unwrap_region_constraints().make_subregion(
231 origin,
232 b,
233 a,
234 ty::VisibleForLeakCheck::Yes,
235 );
236 }
237 ty::Contravariant => {
239 self.infcx.inner.borrow_mut().unwrap_region_constraints().make_subregion(
240 origin,
241 a,
242 b,
243 ty::VisibleForLeakCheck::Yes,
244 );
245 }
246 ty::Invariant => {
247 self.infcx.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
248 origin,
249 a,
250 b,
251 ty::VisibleForLeakCheck::Yes,
252 );
253 }
254 ty::Bivariant => {
255 unreachable!("Expected bivariance to be handled in relate_with_variance")
256 }
257 }
258
259 Ok(a)
260 }
261
262 #[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(262u32),
::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;
}
{
if true {
if !!a.has_rigid_aliases() {
::core::panicking::panic("assertion failed: !a.has_rigid_aliases()")
};
};
if true {
if !!b.has_rigid_aliases() {
::core::panicking::panic("assertion failed: !b.has_rigid_aliases()")
};
};
super_combine_consts(self.infcx, self, a, b)
}
}
}#[instrument(skip(self), level = "trace")]
263 fn consts(
264 &mut self,
265 a: ty::Const<'tcx>,
266 b: ty::Const<'tcx>,
267 ) -> RelateResult<'tcx, ty::Const<'tcx>> {
268 debug_assert!(!a.has_rigid_aliases());
270 debug_assert!(!b.has_rigid_aliases());
271
272 super_combine_consts(self.infcx, self, a, b)
273 }
274
275 fn binders<T>(
276 &mut self,
277 a: ty::Binder<'tcx, T>,
278 b: ty::Binder<'tcx, T>,
279 ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
280 where
281 T: Relate<TyCtxt<'tcx>>,
282 {
283 if a == b {
284 } else if let Some(a) = a.no_bound_vars()
286 && let Some(b) = b.no_bound_vars()
287 {
288 self.relate(a, b)?;
289 } else {
290 let span = self.trace.cause.span;
291 let infcx = self.infcx;
292
293 match self.ambient_variance {
294 ty::Covariant => {
310 infcx.enter_forall(b, |b| {
311 let a = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, a);
312 self.relate(a, b)
313 })?;
314 }
315 ty::Contravariant => {
316 infcx.enter_forall(a, |a| {
317 let b = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, b);
318 self.relate(a, b)
319 })?;
320 }
321
322 ty::Invariant => {
333 infcx.enter_forall(b, |b| {
334 let a = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, a);
335 self.relate(a, b)
336 })?;
337
338 infcx.enter_forall(a, |a| {
340 let b = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, b);
341 self.relate(a, b)
342 })?;
343 }
344 ty::Bivariant => {
345 {
::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")
346 }
347 }
348 }
349
350 Ok(a)
351 }
352}
353
354impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
355 fn span(&self) -> Span {
356 self.trace.span()
357 }
358
359 fn param_env(&self) -> ty::ParamEnv<'tcx> {
360 self.param_env
361 }
362
363 fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
364 StructurallyRelateAliases::No
365 }
366
367 fn register_predicates(
368 &mut self,
369 preds: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
370 ) {
371 self.obligations.extend(preds.into_iter().map(|pred| {
372 Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, pred)
373 }))
374 }
375
376 fn register_goals(&mut self, goals: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>) {
377 self.obligations.extend(goals.into_iter().map(|goal| {
378 Obligation::new(
379 self.infcx.tcx,
380 self.trace.cause.clone(),
381 goal.param_env,
382 goal.predicate,
383 )
384 }))
385 }
386
387 fn ambient_variance(&self) -> ty::Variance {
388 self.ambient_variance
389 }
390}