]> git.lizzy.rs Git - rust.git/blob - src/librustc_traits/chalk_context/unify.rs
Auto merge of #61203 - memoryruins:bare_trait_objects, r=Centril
[rust.git] / src / librustc_traits / chalk_context / unify.rs
1 use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate, NormalizationStrategy};
2 use rustc::infer::{InferCtxt, RegionVariableOrigin};
3 use rustc::traits::{DomainGoal, Goal, Environment, InEnvironment};
4 use rustc::ty::relate::{Relate, TypeRelation, RelateResult};
5 use rustc::ty;
6 use syntax_pos::DUMMY_SP;
7
8 crate struct UnificationResult<'tcx> {
9     crate goals: Vec<InEnvironment<'tcx, Goal<'tcx>>>,
10     crate constraints: Vec<super::RegionConstraint<'tcx>>,
11 }
12
13 crate fn unify<'me, 'gcx, 'tcx, T: Relate<'tcx>>(
14     infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
15     environment: Environment<'tcx>,
16     variance: ty::Variance,
17     a: &T,
18     b: &T
19 ) -> RelateResult<'tcx, UnificationResult<'tcx>> {
20     debug!("unify(
21         a = {:?},
22         b = {:?},
23         environment = {:?},
24     )", a, b, environment);
25
26     let mut delegate = ChalkTypeRelatingDelegate::new(
27         infcx,
28         environment
29     );
30
31     TypeRelating::new(
32         infcx,
33         &mut delegate,
34         variance
35     ).relate(a, b)?;
36
37     debug!("unify: goals = {:?}, constraints = {:?}", delegate.goals, delegate.constraints);
38
39     Ok(UnificationResult {
40         goals: delegate.goals,
41         constraints: delegate.constraints,
42     })
43 }
44
45 struct ChalkTypeRelatingDelegate<'me, 'gcx: 'tcx, 'tcx: 'me> {
46     infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
47     environment: Environment<'tcx>,
48     goals: Vec<InEnvironment<'tcx, Goal<'tcx>>>,
49     constraints: Vec<super::RegionConstraint<'tcx>>,
50 }
51
52 impl ChalkTypeRelatingDelegate<'me, 'gcx, 'tcx> {
53     fn new(
54         infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
55         environment: Environment<'tcx>,
56     ) -> Self {
57         Self {
58             infcx,
59             environment,
60             goals: Vec::new(),
61             constraints: Vec::new(),
62         }
63     }
64 }
65
66 impl TypeRelatingDelegate<'tcx> for &mut ChalkTypeRelatingDelegate<'_, '_, 'tcx> {
67     fn create_next_universe(&mut self) -> ty::UniverseIndex {
68         self.infcx.create_next_universe()
69     }
70
71     fn next_existential_region_var(&mut self) -> ty::Region<'tcx> {
72         self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
73     }
74
75     fn next_placeholder_region(
76         &mut self,
77         placeholder: ty::PlaceholderRegion
78     ) -> ty::Region<'tcx> {
79         self.infcx.tcx.mk_region(ty::RePlaceholder(placeholder))
80     }
81
82     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
83         self.infcx.next_region_var_in_universe(
84             RegionVariableOrigin::MiscVariable(DUMMY_SP),
85             universe
86         )
87     }
88
89     fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
90         self.constraints.push(ty::OutlivesPredicate(sup.into(), sub));
91     }
92
93     fn push_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>) {
94         let goal = self.environment.with(
95             self.infcx.tcx.mk_goal(domain_goal.into_goal())
96         );
97         self.goals.push(goal);
98     }
99
100     fn normalization() -> NormalizationStrategy {
101         NormalizationStrategy::Lazy
102     }
103
104     fn forbid_inference_vars() -> bool {
105         false
106     }
107 }