]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_trait_selection/src/solve/infcx_ext.rs
42f597c781d257e0f97506d931d5121b5d5a83fd
[rust.git] / compiler / rustc_trait_selection / src / solve / infcx_ext.rs
1 use rustc_infer::infer::at::ToTrace;
2 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
3 use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
4 use rustc_infer::traits::query::NoSolution;
5 use rustc_infer::traits::ObligationCause;
6 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
7 use rustc_middle::ty::{self, Ty, TypeFoldable};
8 use rustc_span::DUMMY_SP;
9
10 use super::Goal;
11
12 /// Methods used inside of the canonical queries of the solver.
13 ///
14 /// Most notably these do not care about diagnostics information.
15 /// If you find this while looking for methods to use outside of the
16 /// solver, you may look at the implementation of these method for
17 /// help.
18 pub(super) trait InferCtxtExt<'tcx> {
19     fn next_ty_infer(&self) -> Ty<'tcx>;
20     fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx>;
21
22     fn eq<T: ToTrace<'tcx>>(
23         &self,
24         param_env: ty::ParamEnv<'tcx>,
25         lhs: T,
26         rhs: T,
27     ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>;
28
29     fn instantiate_bound_vars_with_infer<T: TypeFoldable<'tcx> + Copy>(
30         &self,
31         value: ty::Binder<'tcx, T>,
32     ) -> T;
33 }
34
35 impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
36     fn next_ty_infer(&self) -> Ty<'tcx> {
37         self.next_ty_var(TypeVariableOrigin {
38             kind: TypeVariableOriginKind::MiscVariable,
39             span: DUMMY_SP,
40         })
41     }
42     fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
43         self.next_const_var(
44             ty,
45             ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP },
46         )
47     }
48
49     #[instrument(level = "debug", skip(self, param_env), ret)]
50     fn eq<T: ToTrace<'tcx>>(
51         &self,
52         param_env: ty::ParamEnv<'tcx>,
53         lhs: T,
54         rhs: T,
55     ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
56         self.at(&ObligationCause::dummy(), param_env)
57             .define_opaque_types(false)
58             .eq(lhs, rhs)
59             .map(|InferOk { value: (), obligations }| {
60                 obligations.into_iter().map(|o| o.into()).collect()
61             })
62             .map_err(|e| {
63                 debug!(?e, "failed to equate");
64                 NoSolution
65             })
66     }
67
68     fn instantiate_bound_vars_with_infer<T: TypeFoldable<'tcx> + Copy>(
69         &self,
70         value: ty::Binder<'tcx, T>,
71     ) -> T {
72         self.replace_bound_vars_with_fresh_vars(
73             DUMMY_SP,
74             LateBoundRegionConversionTime::HigherRankedType,
75             value,
76         )
77     }
78 }