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
>,
27 pub fn new(tcx
: TyCtxt
<'tcx
>, param_env
: ty
::ParamEnv
<'tcx
>) -> Match
<'tcx
> {
28 Match { tcx, param_env }
32 impl 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
>>(
51 ) -> RelateResult
<'tcx
, T
> {
59 ) -> RelateResult
<'tcx
, ty
::Region
<'tcx
>> {
60 debug
!("{}.regions({:?}, {:?})", self.tag(), a
, b
);
64 fn tys(&mut self, a
: Ty
<'tcx
>, b
: Ty
<'tcx
>) -> RelateResult
<'tcx
, Ty
<'tcx
>> {
65 debug
!("{}.tys({:?}, {:?})", self.tag(), a
, b
);
70 match (&a
.kind
, &b
.kind
) {
73 &ty
::Infer(ty
::FreshTy(_
))
74 | &ty
::Infer(ty
::FreshIntTy(_
))
75 | &ty
::Infer(ty
::FreshFloatTy(_
)),
78 (&ty
::Infer(_
), _
) | (_
, &ty
::Infer(_
)) => {
79 Err(TypeError
::Sorts(relate
::expected_found(self, &a
, &b
)))
82 (&ty
::Error
, _
) | (_
, &ty
::Error
) => Ok(self.tcx().types
.err
),
84 _
=> relate
::super_relate_tys(self, a
, b
),
90 a
: &'tcx ty
::Const
<'tcx
>,
91 b
: &'tcx ty
::Const
<'tcx
>,
92 ) -> RelateResult
<'tcx
, &'tcx ty
::Const
<'tcx
>> {
93 debug
!("{}.consts({:?}, {:?})", self.tag(), a
, b
);
98 match (a
.val
, b
.val
) {
99 (_
, ty
::ConstKind
::Infer(InferConst
::Fresh(_
))) => {
103 (ty
::ConstKind
::Infer(_
), _
) | (_
, ty
::ConstKind
::Infer(_
)) => {
104 return Err(TypeError
::ConstMismatch(relate
::expected_found(self, &a
, &b
)));
110 relate
::super_relate_consts(self, a
, b
)
117 ) -> RelateResult
<'tcx
, ty
::Binder
<T
>>
121 Ok(ty
::Binder
::bind(self.relate(a
.skip_binder(), b
.skip_binder())?
))