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