]>
Commit | Line | Data |
---|---|---|
9c376795 FG |
1 | use crate::infer::InferCtxt; |
2 | ||
9ffffee4 FG |
3 | use rustc_infer::infer::ObligationEmittingRelation; |
4 | use rustc_infer::traits::PredicateObligations; | |
9c376795 FG |
5 | use rustc_middle::ty::error::TypeError; |
6 | use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; | |
7 | use rustc_middle::ty::{self, Ty, TyCtxt}; | |
8 | ||
9 | pub struct CollectAllMismatches<'a, 'tcx> { | |
10 | pub infcx: &'a InferCtxt<'tcx>, | |
11 | pub param_env: ty::ParamEnv<'tcx>, | |
12 | pub errors: Vec<TypeError<'tcx>>, | |
13 | } | |
14 | ||
15 | impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> { | |
16 | fn tag(&self) -> &'static str { | |
17 | "CollectAllMismatches" | |
18 | } | |
19 | ||
20 | fn tcx(&self) -> TyCtxt<'tcx> { | |
21 | self.infcx.tcx | |
22 | } | |
23 | ||
9c376795 FG |
24 | fn param_env(&self) -> ty::ParamEnv<'tcx> { |
25 | self.param_env | |
26 | } | |
27 | ||
28 | fn a_is_expected(&self) -> bool { | |
29 | true | |
30 | } | |
31 | ||
9c376795 FG |
32 | fn relate_with_variance<T: Relate<'tcx>>( |
33 | &mut self, | |
34 | _: ty::Variance, | |
35 | _: ty::VarianceDiagInfo<'tcx>, | |
36 | a: T, | |
37 | b: T, | |
38 | ) -> RelateResult<'tcx, T> { | |
39 | self.relate(a, b) | |
40 | } | |
41 | ||
42 | fn regions( | |
43 | &mut self, | |
44 | a: ty::Region<'tcx>, | |
45 | _b: ty::Region<'tcx>, | |
46 | ) -> RelateResult<'tcx, ty::Region<'tcx>> { | |
47 | Ok(a) | |
48 | } | |
49 | ||
50 | fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { | |
51 | self.infcx.probe(|_| { | |
52 | if a.is_ty_var() || b.is_ty_var() { | |
53 | Ok(a) | |
54 | } else { | |
55 | self.infcx.super_combine_tys(self, a, b).or_else(|e| { | |
56 | self.errors.push(e); | |
57 | Ok(a) | |
58 | }) | |
59 | } | |
60 | }) | |
61 | } | |
62 | ||
63 | fn consts( | |
64 | &mut self, | |
65 | a: ty::Const<'tcx>, | |
66 | b: ty::Const<'tcx>, | |
67 | ) -> RelateResult<'tcx, ty::Const<'tcx>> { | |
68 | self.infcx.probe(|_| { | |
69 | if a.is_ct_infer() || b.is_ct_infer() { | |
70 | Ok(a) | |
71 | } else { | |
72 | relate::super_relate_consts(self, a, b) // could do something similar here for constants! | |
73 | } | |
74 | }) | |
75 | } | |
76 | ||
77 | fn binders<T: Relate<'tcx>>( | |
78 | &mut self, | |
79 | a: ty::Binder<'tcx, T>, | |
80 | b: ty::Binder<'tcx, T>, | |
81 | ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> { | |
82 | Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) | |
83 | } | |
84 | } | |
9ffffee4 FG |
85 | |
86 | impl<'tcx> ObligationEmittingRelation<'tcx> for CollectAllMismatches<'_, 'tcx> { | |
353b0b11 FG |
87 | fn alias_relate_direction(&self) -> ty::AliasRelationDirection { |
88 | // FIXME(deferred_projection_equality): We really should get rid of this relation. | |
89 | ty::AliasRelationDirection::Equate | |
90 | } | |
91 | ||
9ffffee4 FG |
92 | fn register_obligations(&mut self, _obligations: PredicateObligations<'tcx>) { |
93 | // FIXME(deferred_projection_equality) | |
94 | } | |
95 | ||
96 | fn register_predicates( | |
97 | &mut self, | |
98 | _obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>, | |
99 | ) { | |
100 | // FIXME(deferred_projection_equality) | |
101 | } | |
102 | } |