rustc_trait_selection/traits/select/
_match.rs1use 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 #[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 #[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 #[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}