1use rustc_hir::def_id::DefId;
2use rustc_infer::infer::relate::{
3 self, Relate, RelateResult, TypeRelation, structurally_relate_tys,
4};
5use rustc_middle::ty::error::{ExpectedFound, TypeError};
6use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
7use tracing::instrument;
8
9pub(crate) struct MatchAgainstFreshVars<'tcx> {
26 tcx: TyCtxt<'tcx>,
27}
28
29impl<'tcx> MatchAgainstFreshVars<'tcx> {
30 pub(crate) fn new(tcx: TyCtxt<'tcx>) -> MatchAgainstFreshVars<'tcx> {
31 MatchAgainstFreshVars { tcx }
32 }
33}
34
35impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstFreshVars<'tcx> {
36 fn cx(&self) -> TyCtxt<'tcx> {
37 self.tcx
38 }
39
40 fn relate_ty_args(
41 &mut self,
42 a_ty: Ty<'tcx>,
43 _: Ty<'tcx>,
44 _: DefId,
45 a_args: ty::GenericArgsRef<'tcx>,
46 b_args: ty::GenericArgsRef<'tcx>,
47 _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>,
48 ) -> RelateResult<'tcx, Ty<'tcx>> {
49 relate::relate_args_invariantly(self, a_args, b_args)?;
50 Ok(a_ty)
51 }
52
53 fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
54 &mut self,
55 _: ty::Variance,
56 _: ty::VarianceDiagInfo<TyCtxt<'tcx>>,
57 a: T,
58 b: T,
59 ) -> RelateResult<'tcx, T> {
60 self.relate(a, b)
61 }
62
63 #[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_trait_selection::traits::select::_match",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/select/_match.rs"),
::tracing_core::__macro_support::Option::Some(63u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::select::_match"),
::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;
}
{ Ok(a) }
}
}#[instrument(skip(self), level = "trace")]
64 fn regions(
65 &mut self,
66 a: ty::Region<'tcx>,
67 _b: ty::Region<'tcx>,
68 ) -> RelateResult<'tcx, ty::Region<'tcx>> {
69 Ok(a)
70 }
71
72 #[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_trait_selection::traits::select::_match",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/select/_match.rs"),
::tracing_core::__macro_support::Option::Some(72u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::select::_match"),
::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); }
match (a.kind(), b.kind()) {
(_,
&ty::Infer(ty::FreshTy(_)) | &ty::Infer(ty::FreshIntTy(_)) |
&ty::Infer(ty::FreshFloatTy(_))) => Ok(a),
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
Err(TypeError::Sorts(ExpectedFound::new(a, b)))
}
(&ty::Error(guar), _) | (_, &ty::Error(guar)) =>
Ok(Ty::new_error(self.cx(), guar)),
_ => structurally_relate_tys(self, a, b),
}
}
}
}#[instrument(skip(self), level = "trace")]
73 fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
74 if a == b {
75 return Ok(a);
76 }
77
78 match (a.kind(), b.kind()) {
79 (
80 _,
81 &ty::Infer(ty::FreshTy(_))
82 | &ty::Infer(ty::FreshIntTy(_))
83 | &ty::Infer(ty::FreshFloatTy(_)),
84 ) => Ok(a),
85
86 (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
87 Err(TypeError::Sorts(ExpectedFound::new(a, b)))
88 }
89
90 (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.cx(), guar)),
91
92 _ => structurally_relate_tys(self, a, b),
93 }
94 }
95
96 #[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_trait_selection::traits::select::_match",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/select/_match.rs"),
::tracing_core::__macro_support::Option::Some(96u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::select::_match"),
::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 a == b { return Ok(a); }
match (a.kind(), b.kind()) {
(_, ty::ConstKind::Infer(InferConst::Fresh(_))) => {
return Ok(a);
}
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) =>
{
return Err(TypeError::ConstMismatch(ExpectedFound::new(a,
b)));
}
_ => {}
}
relate::structurally_relate_consts(self, a, b)
}
}
}#[instrument(skip(self), level = "trace")]
97 fn consts(
98 &mut self,
99 a: ty::Const<'tcx>,
100 b: ty::Const<'tcx>,
101 ) -> RelateResult<'tcx, ty::Const<'tcx>> {
102 if a == b {
103 return Ok(a);
104 }
105
106 match (a.kind(), b.kind()) {
107 (_, ty::ConstKind::Infer(InferConst::Fresh(_))) => {
108 return Ok(a);
109 }
110
111 (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
112 return Err(TypeError::ConstMismatch(ExpectedFound::new(a, b)));
113 }
114
115 _ => {}
116 }
117
118 relate::structurally_relate_consts(self, a, b)
119 }
120
121 fn binders<T>(
122 &mut self,
123 a: ty::Binder<'tcx, T>,
124 b: ty::Binder<'tcx, T>,
125 ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
126 where
127 T: Relate<TyCtxt<'tcx>>,
128 {
129 Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
130 }
131}