]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs
Preparing for merge from rustc
[rust.git] / compiler / rustc_trait_selection / src / traits / error_reporting / method_chain.rs
1 use crate::infer::InferCtxt;
2
3 use rustc_middle::ty::error::TypeError;
4 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
5 use rustc_middle::ty::{self, Ty, TyCtxt};
6
7 pub struct CollectAllMismatches<'a, 'tcx> {
8     pub infcx: &'a InferCtxt<'tcx>,
9     pub param_env: ty::ParamEnv<'tcx>,
10     pub errors: Vec<TypeError<'tcx>>,
11 }
12
13 impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
14     fn tag(&self) -> &'static str {
15         "CollectAllMismatches"
16     }
17     fn tcx(&self) -> TyCtxt<'tcx> {
18         self.infcx.tcx
19     }
20     fn intercrate(&self) -> bool {
21         false
22     }
23     fn param_env(&self) -> ty::ParamEnv<'tcx> {
24         self.param_env
25     }
26     fn a_is_expected(&self) -> bool {
27         true
28     } // irrelevant
29     fn mark_ambiguous(&mut self) {
30         bug!()
31     }
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     fn regions(
42         &mut self,
43         a: ty::Region<'tcx>,
44         _b: ty::Region<'tcx>,
45     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
46         Ok(a)
47     }
48     fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
49         if a == b || matches!(a.kind(), ty::Infer(_)) || matches!(b.kind(), ty::Infer(_)) {
50             return Ok(a);
51         }
52         relate::super_relate_tys(self, a, b).or_else(|e| {
53             self.errors.push(e);
54             Ok(a)
55         })
56     }
57     fn consts(
58         &mut self,
59         a: ty::Const<'tcx>,
60         b: ty::Const<'tcx>,
61     ) -> RelateResult<'tcx, ty::Const<'tcx>> {
62         if a == b {
63             return Ok(a);
64         }
65         relate::super_relate_consts(self, a, b) // could do something similar here for constants!
66     }
67     fn binders<T: Relate<'tcx>>(
68         &mut self,
69         a: ty::Binder<'tcx, T>,
70         b: ty::Binder<'tcx, T>,
71     ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> {
72         Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
73     }
74 }