1 use crate::ty
::error
::TypeError
;
2 use crate::ty
::relate
::{self, Relate, RelateResult, TypeRelation}
;
3 use crate::ty
::{self, InferConst, Ty, TyCtxt}
;
5 /// A type "A" *matches* "B" if the fresh types in B could be
6 /// substituted with values so as to make it equal to A. Matching is
7 /// intended to be used only on freshened types, and it basically
8 /// indicates if the non-freshened versions of A and B could have been
11 /// It is only an approximation. If it yields false, unification would
12 /// definitely fail, but a true result doesn't mean unification would
13 /// succeed. This is because we don't track the "side-constraints" on
14 /// type variables, nor do we track if the same freshened type appears
15 /// more than once. To some extent these approximations could be
16 /// fixed, given effort.
18 /// Like subtyping, matching is really a binary relation, so the only
19 /// important thing about the result is Ok/Err. Also, matching never
20 /// affects any type variables or unification state.
21 pub struct Match
<'tcx
> {
23 param_env
: ty
::ParamEnv
<'tcx
>,
26 impl<'tcx
> Match
<'tcx
> {
27 pub fn new(tcx
: TyCtxt
<'tcx
>, param_env
: ty
::ParamEnv
<'tcx
>) -> Match
<'tcx
> {
28 Match { tcx, param_env }
32 impl<'tcx
> TypeRelation
<'tcx
> for Match
<'tcx
> {
33 fn tag(&self) -> &'
static str {
36 fn tcx(&self) -> TyCtxt
<'tcx
> {
39 fn param_env(&self) -> ty
::ParamEnv
<'tcx
> {
42 fn a_is_expected(&self) -> bool
{
46 fn relate_with_variance
<T
: Relate
<'tcx
>>(
49 _
: ty
::VarianceDiagInfo
<'tcx
>,
52 ) -> RelateResult
<'tcx
, T
> {
56 #[instrument(skip(self), level = "debug")]
61 ) -> RelateResult
<'tcx
, ty
::Region
<'tcx
>> {
65 #[instrument(skip(self), level = "debug")]
66 fn tys(&mut self, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> RelateResult
<'tcx
, Ty
<'tcx
>> {
71 match (a
.kind(), b
.kind()) {
74 &ty
::Infer(ty
::FreshTy(_
))
75 | &ty
::Infer(ty
::FreshIntTy(_
))
76 | &ty
::Infer(ty
::FreshFloatTy(_
)),
79 (&ty
::Infer(_
), _
) | (_
, &ty
::Infer(_
)) => {
80 Err(TypeError
::Sorts(relate
::expected_found(self, a
, b
)))
83 (&ty
::Error(_
), _
) | (_
, &ty
::Error(_
)) => Ok(self.tcx().ty_error()),
85 _
=> relate
::super_relate_tys(self, a
, b
),
93 ) -> RelateResult
<'tcx
, ty
::Const
<'tcx
>> {
94 debug
!("{}.consts({:?}, {:?})", self.tag(), a
, b
);
99 match (a
.val(), b
.val()) {
100 (_
, ty
::ConstKind
::Infer(InferConst
::Fresh(_
))) => {
104 (ty
::ConstKind
::Infer(_
), _
) | (_
, ty
::ConstKind
::Infer(_
)) => {
105 return Err(TypeError
::ConstMismatch(relate
::expected_found(self, a
, b
)));
111 relate
::super_relate_consts(self, a
, b
)
116 a
: ty
::Binder
<'tcx
, T
>,
117 b
: ty
::Binder
<'tcx
, T
>,
118 ) -> RelateResult
<'tcx
, ty
::Binder
<'tcx
, T
>>
122 Ok(a
.rebind(self.relate(a
.skip_binder(), b
.skip_binder())?
))