1use std::iter;
2
3use derive_where::derive_where;
4use rustc_ast_ir::Mutability;
5use tracing::{instrument, trace};
6
7use crate::error::{ExpectedFound, TypeError};
8use crate::fold::TypeFoldable;
9use crate::inherent::*;
10use crate::{self as ty, Interner};
11
12pub mod combine;
13pub mod solver_relating;
14
15pub type RelateResult<I, T> = Result<T, TypeError<I>>;
16
17#[derive(#[automatically_derived]
impl ::core::fmt::Debug for StructurallyRelateAliases {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
StructurallyRelateAliases::Yes => "Yes",
StructurallyRelateAliases::No => "No",
})
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for StructurallyRelateAliases { }Copy, #[automatically_derived]
impl ::core::clone::Clone for StructurallyRelateAliases {
#[inline]
fn clone(&self) -> StructurallyRelateAliases { *self }
}Clone)]
24pub enum StructurallyRelateAliases {
25 Yes,
26 No,
27}
28
29#[automatically_derived]
impl<I: Interner> ::core::default::Default for VarianceDiagInfo<I> where
I: Interner {
fn default() -> Self { VarianceDiagInfo::None }
}#[derive_where(Clone, Copy, PartialEq, Debug, Default; I: Interner)]
37pub enum VarianceDiagInfo<I: Interner> {
38 #[derive_where(default)]
41 None,
42 Invariant {
45 ty: I::Ty,
48 param_index: u32,
51 },
52}
53
54impl<I: Interner> Eq for VarianceDiagInfo<I> {}
55
56impl<I: Interner> VarianceDiagInfo<I> {
57 pub fn xform(self, other: VarianceDiagInfo<I>) -> VarianceDiagInfo<I> {
60 match self {
62 VarianceDiagInfo::None => other,
63 VarianceDiagInfo::Invariant { .. } => self,
64 }
65 }
66}
67
68pub trait TypeRelation<I: Interner>: Sized {
69 fn cx(&self) -> I;
70
71 fn relate<T: Relate<I>>(&mut self, a: T, b: T) -> RelateResult<I, T> {
73 Relate::relate(self, a, b)
74 }
75
76 fn relate_ty_args(
77 &mut self,
78 a_ty: I::Ty,
79 b_ty: I::Ty,
80 ty_def_id: I::DefId,
81 a_arg: I::GenericArgs,
82 b_arg: I::GenericArgs,
83 mk: impl FnOnce(I::GenericArgs) -> I::Ty,
84 ) -> RelateResult<I, I::Ty>;
85
86 fn relate_with_variance<T: Relate<I>>(
88 &mut self,
89 variance: ty::Variance,
90 info: VarianceDiagInfo<I>,
91 a: T,
92 b: T,
93 ) -> RelateResult<I, T>;
94
95 fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty>;
102
103 fn regions(&mut self, a: I::Region, b: I::Region) -> RelateResult<I, I::Region>;
104
105 fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult<I, I::Const>;
106
107 fn binders<T>(
108 &mut self,
109 a: ty::Binder<I, T>,
110 b: ty::Binder<I, T>,
111 ) -> RelateResult<I, ty::Binder<I, T>>
112 where
113 T: Relate<I>;
114}
115
116pub trait Relate<I: Interner>: TypeFoldable<I> + PartialEq + Copy {
117 fn relate<R: TypeRelation<I>>(relation: &mut R, a: Self, b: Self) -> RelateResult<I, Self>;
118}
119
120#[inline]
124pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
125 relation: &mut R,
126 a_arg: I::GenericArgs,
127 b_arg: I::GenericArgs,
128) -> RelateResult<I, I::GenericArgs> {
129 relation.cx().mk_args_from_iter(iter::zip(a_arg.iter(), b_arg.iter()).map(|(a, b)| {
130 relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b)
131 }))
132}
133
134pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
135 relation: &mut R,
136 variances: I::VariancesOf,
137 a_args: I::GenericArgs,
138 b_args: I::GenericArgs,
139) -> RelateResult<I, I::GenericArgs> {
140 let cx = relation.cx();
141 let args = iter::zip(a_args.iter(), b_args.iter()).enumerate().map(|(i, (a, b))| {
142 let variance = variances.get(i).unwrap();
143 relation.relate_with_variance(variance, VarianceDiagInfo::None, a, b)
144 });
145 cx.mk_args_from_iter(args)
147}
148
149impl<I: Interner> Relate<I> for ty::FnSig<I> {
150 fn relate<R: TypeRelation<I>>(
151 relation: &mut R,
152 a: ty::FnSig<I>,
153 b: ty::FnSig<I>,
154 ) -> RelateResult<I, ty::FnSig<I>> {
155 let cx = relation.cx();
156
157 if a.c_variadic() != b.c_variadic() {
158 return Err(TypeError::VariadicMismatch(ExpectedFound::new(
159 a.c_variadic(),
160 b.c_variadic(),
161 )));
162 }
163
164 if a.safety() != b.safety() {
165 return Err(TypeError::SafetyMismatch(ExpectedFound::new(a.safety(), b.safety())));
166 }
167
168 if a.abi() != b.abi() {
169 return Err(TypeError::AbiMismatch(ExpectedFound::new(a.abi(), b.abi())));
170 };
171
172 if a.splatted() != b.splatted() {
173 return Err(TypeError::SplatMismatch(ExpectedFound::new(a.splatted(), b.splatted())));
174 }
175
176 let a_inputs = a.inputs();
177 let b_inputs = b.inputs();
178 if a_inputs.len() != b_inputs.len() {
179 return Err(TypeError::ArgCount);
180 }
181
182 let inputs_and_output = iter::zip(a_inputs.iter(), b_inputs.iter())
183 .map(|(a, b)| ((a, b), false))
184 .chain(iter::once(((a.output(), b.output()), true)))
185 .map(|((a, b), is_output)| {
186 if is_output {
187 relation.relate(a, b)
188 } else {
189 relation.relate_with_variance(
190 ty::Contravariant,
191 VarianceDiagInfo::default(),
192 a,
193 b,
194 )
195 }
196 })
197 .enumerate()
198 .map(|(i, r)| match r {
199 Err(TypeError::Sorts(exp_found) | TypeError::ArgumentSorts(exp_found, _)) => {
200 Err(TypeError::ArgumentSorts(exp_found, i))
201 }
202 Err(TypeError::Mutability | TypeError::ArgumentMutability(_)) => {
203 Err(TypeError::ArgumentMutability(i))
204 }
205 r => r,
206 });
207 Ok(ty::FnSig {
208 inputs_and_output: cx.mk_type_list_from_iter(inputs_and_output)?,
209 fn_sig_kind: a.fn_sig_kind,
210 })
211 }
212}
213
214impl<I: Interner> Relate<I> for ty::AliasTy<I> {
215 fn relate<R: TypeRelation<I>>(
216 relation: &mut R,
217 a: ty::AliasTy<I>,
218 b: ty::AliasTy<I>,
219 ) -> RelateResult<I, ty::AliasTy<I>> {
220 if a.kind != b.kind {
221 Err(TypeError::ProjectionMismatched(ExpectedFound::new(a.kind.into(), b.kind.into())))
222 } else {
223 let cx = relation.cx();
224 let args = if let Some(variances) = cx.opt_alias_variances(a.kind) {
225 relate_args_with_variances(relation, variances, a.args, b.args)?
226 } else {
227 relate_args_invariantly(relation, a.args, b.args)?
228 };
229 Ok(ty::AliasTy::new_from_args(relation.cx(), a.kind, args))
230 }
231 }
232}
233
234impl<I: Interner> Relate<I> for ty::AliasConst<I> {
235 fn relate<R: TypeRelation<I>>(
236 relation: &mut R,
237 a: ty::AliasConst<I>,
238 b: ty::AliasConst<I>,
239 ) -> RelateResult<I, ty::AliasConst<I>> {
240 let cx = relation.cx();
241 if a.kind != b.kind {
242 Err(TypeError::ConstMismatch(ExpectedFound::new(
243 Const::new_alias(cx, ty::IsRigid::yes_if_next_solver(cx), a),
244 Const::new_alias(cx, ty::IsRigid::yes_if_next_solver(cx), b),
245 )))
246 } else {
247 if true {
{
match (&a.type_of(cx).skip_norm_wip(), &b.type_of(cx).skip_norm_wip())
{
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
};debug_assert_eq!(a.type_of(cx).skip_norm_wip(), b.type_of(cx).skip_norm_wip());
249
250 let args = relate_args_invariantly(relation, a.args, b.args)?;
251
252 Ok(ty::AliasConst::new(cx, a.kind, args))
253 }
254 }
255}
256
257impl<I: Interner> Relate<I> for ty::AliasTerm<I> {
258 fn relate<R: TypeRelation<I>>(
259 relation: &mut R,
260 a: ty::AliasTerm<I>,
261 b: ty::AliasTerm<I>,
262 ) -> RelateResult<I, ty::AliasTerm<I>> {
263 if a.kind != b.kind {
264 Err(TypeError::ProjectionMismatched(ExpectedFound::new(a.kind, b.kind)))
265 } else {
266 let args = match a.kind {
267 ty::AliasTermKind::OpaqueTy { def_id } => relate_args_with_variances(
268 relation,
269 relation.cx().variances_of(def_id.into()),
270 a.args,
271 b.args,
272 )?,
273 ty::AliasTermKind::ProjectionTy { .. }
274 | ty::AliasTermKind::FreeConst { .. }
275 | ty::AliasTermKind::FreeTy { .. }
276 | ty::AliasTermKind::InherentTy { .. }
277 | ty::AliasTermKind::InherentConst { .. }
278 | ty::AliasTermKind::AnonConst { .. }
279 | ty::AliasTermKind::ProjectionConst { .. } => {
280 relate_args_invariantly(relation, a.args, b.args)?
281 }
282 };
283 Ok(a.with_args(relation.cx(), args))
284 }
285 }
286}
287
288impl<I: Interner> Relate<I> for ty::ExistentialProjection<I> {
289 fn relate<R: TypeRelation<I>>(
290 relation: &mut R,
291 a: ty::ExistentialProjection<I>,
292 b: ty::ExistentialProjection<I>,
293 ) -> RelateResult<I, ty::ExistentialProjection<I>> {
294 if a.def_id != b.def_id {
295 Err(TypeError::ProjectionMismatched(ExpectedFound::new(
296 relation.cx().alias_term_kind_from_def_id(a.def_id.into()),
297 relation.cx().alias_term_kind_from_def_id(b.def_id.into()),
298 )))
299 } else {
300 let term = relation.relate_with_variance(
301 ty::Invariant,
302 VarianceDiagInfo::default(),
303 a.term,
304 b.term,
305 )?;
306 let args = relation.relate_with_variance(
307 ty::Invariant,
308 VarianceDiagInfo::default(),
309 a.args,
310 b.args,
311 )?;
312 Ok(ty::ExistentialProjection::new_from_args(relation.cx(), a.def_id, args, term))
313 }
314 }
315}
316
317impl<I: Interner> Relate<I> for ty::TraitRef<I> {
318 fn relate<R: TypeRelation<I>>(
319 relation: &mut R,
320 a: ty::TraitRef<I>,
321 b: ty::TraitRef<I>,
322 ) -> RelateResult<I, ty::TraitRef<I>> {
323 if a.def_id != b.def_id {
325 Err(TypeError::Traits({
326 let a = a.def_id;
327 let b = b.def_id;
328 ExpectedFound::new(a, b)
329 }))
330 } else {
331 let args = relate_args_invariantly(relation, a.args, b.args)?;
332 Ok(ty::TraitRef::new_from_args(relation.cx(), a.def_id, args))
333 }
334 }
335}
336
337impl<I: Interner> Relate<I> for ty::ExistentialTraitRef<I> {
338 fn relate<R: TypeRelation<I>>(
339 relation: &mut R,
340 a: ty::ExistentialTraitRef<I>,
341 b: ty::ExistentialTraitRef<I>,
342 ) -> RelateResult<I, ty::ExistentialTraitRef<I>> {
343 if a.def_id != b.def_id {
345 Err(TypeError::Traits({
346 let a = a.def_id;
347 let b = b.def_id;
348 ExpectedFound::new(a, b)
349 }))
350 } else {
351 let args = relate_args_invariantly(relation, a.args, b.args)?;
352 Ok(ty::ExistentialTraitRef::new_from_args(relation.cx(), a.def_id, args))
353 }
354 }
355}
356
357x;#[instrument(level = "trace", skip(relation), ret)]
361pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
362 relation: &mut R,
363 a: I::Ty,
364 b: I::Ty,
365) -> RelateResult<I, I::Ty> {
366 let cx = relation.cx();
367 match (a.kind(), b.kind()) {
368 (ty::Infer(_), _) | (_, ty::Infer(_)) => {
369 panic!("var types encountered in structurally_relate_tys")
371 }
372
373 (ty::Bound(..), _) | (_, ty::Bound(..)) => {
374 panic!("bound types encountered in structurally_relate_tys")
375 }
376
377 (ty::Error(guar), _) | (_, ty::Error(guar)) => Ok(Ty::new_error(cx, guar)),
378
379 (ty::Never, _)
380 | (ty::Char, _)
381 | (ty::Bool, _)
382 | (ty::Int(_), _)
383 | (ty::Uint(_), _)
384 | (ty::Float(_), _)
385 | (ty::Str, _)
386 if a == b =>
387 {
388 Ok(a)
389 }
390
391 (ty::Param(a_p), ty::Param(b_p)) if a_p.index() == b_p.index() => {
392 Ok(a)
395 }
396
397 (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
398
399 (ty::Adt(a_def, a_args), ty::Adt(b_def, b_args)) if a_def == b_def => {
400 if a_args.is_empty() {
401 Ok(a)
402 } else {
403 relation.relate_ty_args(a, b, a_def.def_id().into(), a_args, b_args, |args| {
404 Ty::new_adt(cx, a_def, args)
405 })
406 }
407 }
408
409 (ty::Foreign(a_id), ty::Foreign(b_id)) if a_id == b_id => Ok(Ty::new_foreign(cx, a_id)),
410
411 (ty::Dynamic(a_obj, a_region), ty::Dynamic(b_obj, b_region)) => Ok(Ty::new_dynamic(
412 cx,
413 relation.relate(a_obj, b_obj)?,
414 relation.relate(a_region, b_region)?,
415 )),
416
417 (ty::Coroutine(a_id, a_args), ty::Coroutine(b_id, b_args)) if a_id == b_id => {
418 let args = relate_args_invariantly(relation, a_args, b_args)?;
422 Ok(Ty::new_coroutine(cx, a_id, args))
423 }
424
425 (ty::CoroutineWitness(a_id, a_args), ty::CoroutineWitness(b_id, b_args))
426 if a_id == b_id =>
427 {
428 let args = relate_args_invariantly(relation, a_args, b_args)?;
432 Ok(Ty::new_coroutine_witness(cx, a_id, args))
433 }
434
435 (ty::Closure(a_id, a_args), ty::Closure(b_id, b_args)) if a_id == b_id => {
436 let args = relate_args_invariantly(relation, a_args, b_args)?;
440 Ok(Ty::new_closure(cx, a_id, args))
441 }
442
443 (ty::CoroutineClosure(a_id, a_args), ty::CoroutineClosure(b_id, b_args))
444 if a_id == b_id =>
445 {
446 let args = relate_args_invariantly(relation, a_args, b_args)?;
447 Ok(Ty::new_coroutine_closure(cx, a_id, args))
448 }
449
450 (ty::RawPtr(a_ty, a_mutbl), ty::RawPtr(b_ty, b_mutbl)) => {
451 if a_mutbl != b_mutbl {
452 return Err(TypeError::Mutability);
453 }
454
455 let (variance, info) = match a_mutbl {
456 Mutability::Not => (ty::Covariant, VarianceDiagInfo::None),
457 Mutability::Mut => {
458 (ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
459 }
460 };
461
462 let ty = relation.relate_with_variance(variance, info, a_ty, b_ty)?;
463
464 Ok(Ty::new_ptr(cx, ty, a_mutbl))
465 }
466
467 (ty::Ref(a_r, a_ty, a_mutbl), ty::Ref(b_r, b_ty, b_mutbl)) => {
468 if a_mutbl != b_mutbl {
469 return Err(TypeError::Mutability);
470 }
471
472 let (variance, info) = match a_mutbl {
473 Mutability::Not => (ty::Covariant, VarianceDiagInfo::None),
474 Mutability::Mut => {
475 (ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
476 }
477 };
478
479 let r = relation.relate(a_r, b_r)?;
480 let ty = relation.relate_with_variance(variance, info, a_ty, b_ty)?;
481
482 Ok(Ty::new_ref(cx, r, ty, a_mutbl))
483 }
484
485 (ty::Array(a_t, sz_a), ty::Array(b_t, sz_b)) => {
486 let t = relation.relate(a_t, b_t)?;
487 match relation.relate(sz_a, sz_b) {
488 Ok(sz) => Ok(Ty::new_array_with_const_len(cx, t, sz)),
489 Err(TypeError::ConstMismatch(_)) => {
490 Err(TypeError::ArraySize(ExpectedFound::new(sz_a, sz_b)))
491 }
492 Err(e) => Err(e),
493 }
494 }
495
496 (ty::Slice(a_t), ty::Slice(b_t)) => {
497 let t = relation.relate(a_t, b_t)?;
498 Ok(Ty::new_slice(cx, t))
499 }
500
501 (ty::Tuple(as_), ty::Tuple(bs)) => {
502 if as_.len() == bs.len() {
503 Ok(Ty::new_tup_from_iter(
504 cx,
505 iter::zip(as_.iter(), bs.iter()).map(|(a, b)| relation.relate(a, b)),
506 )?)
507 } else if !(as_.is_empty() || bs.is_empty()) {
508 Err(TypeError::TupleSize(ExpectedFound::new(as_.len(), bs.len())))
509 } else {
510 Err(TypeError::Sorts(ExpectedFound::new(a, b)))
511 }
512 }
513
514 (ty::FnDef(a_def_id, a_args), ty::FnDef(b_def_id, b_args)) if a_def_id == b_def_id => {
515 if a_args.is_empty() {
516 Ok(a)
517 } else {
518 relation.relate_ty_args(a, b, a_def_id.into(), a_args, b_args, |args| {
519 Ty::new_fn_def(cx, a_def_id, args)
520 })
521 }
522 }
523
524 (ty::FnPtr(a_sig_tys, a_hdr), ty::FnPtr(b_sig_tys, b_hdr)) => {
525 let fty = relation.relate(a_sig_tys.with(a_hdr), b_sig_tys.with(b_hdr))?;
526 Ok(Ty::new_fn_ptr(cx, fty))
527 }
528
529 (ty::Alias(is_rigid_a, alias_a), ty::Alias(is_rigid_b, alias_b)) => {
531 debug_assert_eq!(is_rigid_a, is_rigid_b, "{a:?} != {b:?}");
534 let alias_ty = relation.relate(alias_a, alias_b)?;
535 Ok(Ty::new_alias(cx, is_rigid_a, alias_ty))
536 }
537
538 (ty::Pat(a_ty, a_pat), ty::Pat(b_ty, b_pat)) => {
539 let ty = relation.relate(a_ty, b_ty)?;
540 let pat = relation.relate(a_pat, b_pat)?;
541 Ok(Ty::new_pat(cx, ty, pat))
542 }
543
544 (ty::UnsafeBinder(a_binder), ty::UnsafeBinder(b_binder)) => {
545 Ok(Ty::new_unsafe_binder(cx, relation.binders(*a_binder, *b_binder)?))
546 }
547
548 _ => Err(TypeError::Sorts(ExpectedFound::new(a, b))),
549 }
550}
551
552pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
559 relation: &mut R,
560 mut a: I::Const,
561 mut b: I::Const,
562) -> RelateResult<I, I::Const> {
563 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_type_ir/src/relate.rs:563",
"rustc_type_ir::relate", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/relate.rs"),
::tracing_core::__macro_support::Option::Some(563u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::relate"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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!("structurally_relate_consts::<{0}>(a = {1:?}, b = {2:?})",
std::any::type_name::<R>(), a, b) as &dyn Value))])
});
} else { ; }
};trace!(
564 "structurally_relate_consts::<{}>(a = {:?}, b = {:?})",
565 std::any::type_name::<R>(),
566 a,
567 b
568 );
569 let cx = relation.cx();
570
571 if cx.features().generic_const_exprs() {
572 a = cx.expand_abstract_consts(a);
573 b = cx.expand_abstract_consts(b);
574 }
575
576 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_type_ir/src/relate.rs:576",
"rustc_type_ir::relate", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_type_ir/src/relate.rs"),
::tracing_core::__macro_support::Option::Some(576u32),
::tracing_core::__macro_support::Option::Some("rustc_type_ir::relate"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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!("structurally_relate_consts::<{0}>(normed_a = {1:?}, normed_b = {2:?})",
std::any::type_name::<R>(), a, b) as &dyn Value))])
});
} else { ; }
};trace!(
577 "structurally_relate_consts::<{}>(normed_a = {:?}, normed_b = {:?})",
578 std::any::type_name::<R>(),
579 a,
580 b
581 );
582
583 let is_match = match (a.kind(), b.kind()) {
587 (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
588 {
::core::panicking::panic_fmt(format_args!("var types encountered in structurally_relate_consts: {0:?} {1:?}",
a, b));
}panic!("var types encountered in structurally_relate_consts: {:?} {:?}", a, b)
590 }
591
592 (ty::ConstKind::Error(_), _) => return Ok(a),
593 (_, ty::ConstKind::Error(_)) => return Ok(b),
594
595 (ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index() == b_p.index() => {
596 true
599 }
600 (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
601 (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => {
602 match (a_val.valtree().kind(), b_val.valtree().kind()) {
603 (ty::ValTreeKind::Leaf(scalar_a), ty::ValTreeKind::Leaf(scalar_b)) => {
604 scalar_a == scalar_b
605 }
606 (ty::ValTreeKind::Branch(branches_a), ty::ValTreeKind::Branch(branches_b))
607 if branches_a.len() == branches_b.len() =>
608 {
609 branches_a
610 .iter()
611 .zip(branches_b.iter())
612 .all(|(a, b)| relation.relate(a, b).is_ok())
613 }
614 _ => false,
615 }
616 }
617
618 (ty::ConstKind::Alias(is_rigid_a, au), ty::ConstKind::Alias(is_rigid_b, bu)) => {
622 if true {
{
match (&is_rigid_a, &is_rigid_b) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val,
::core::option::Option::Some(format_args!("{0:?} != {1:?}",
a, b)));
}
}
}
};
};debug_assert_eq!(is_rigid_a, is_rigid_b, "{a:?} != {b:?}");
625 return Ok(Const::new_alias(cx, is_rigid_a, relation.relate(au, bu)?));
626 }
627 (ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => {
628 let expr = relation.relate(ae, be)?;
629 return Ok(Const::new_expr(cx, expr));
630 }
631 _ => false,
632 };
633 if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(ExpectedFound::new(a, b))) }
634}
635
636impl<I: Interner, T: Relate<I>> Relate<I> for ty::Binder<I, T> {
637 fn relate<R: TypeRelation<I>>(
638 relation: &mut R,
639 a: ty::Binder<I, T>,
640 b: ty::Binder<I, T>,
641 ) -> RelateResult<I, ty::Binder<I, T>> {
642 relation.binders(a, b)
643 }
644}
645
646impl<I: Interner> Relate<I> for ty::TraitPredicate<I> {
647 fn relate<R: TypeRelation<I>>(
648 relation: &mut R,
649 a: ty::TraitPredicate<I>,
650 b: ty::TraitPredicate<I>,
651 ) -> RelateResult<I, ty::TraitPredicate<I>> {
652 let trait_ref = relation.relate(a.trait_ref, b.trait_ref)?;
653 if a.polarity != b.polarity {
654 return Err(TypeError::PolarityMismatch(ExpectedFound::new(a.polarity, b.polarity)));
655 }
656 Ok(ty::TraitPredicate { trait_ref, polarity: a.polarity })
657 }
658}