1 use rustc::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
2 use rustc::infer::{InferCtxt, RegionVariableOrigin};
3 use rustc::traits::{DomainGoal, Environment, Goal, InEnvironment};
5 use rustc::ty::relate::{Relate, RelateResult, TypeRelation};
6 use rustc_span::DUMMY_SP;
8 crate struct UnificationResult<'tcx> {
9 crate goals: Vec<InEnvironment<'tcx, Goal<'tcx>>>,
10 crate constraints: Vec<super::RegionConstraint<'tcx>>,
13 crate fn unify<'me, 'tcx, T: Relate<'tcx>>(
14 infcx: &'me InferCtxt<'me, 'tcx>,
15 environment: Environment<'tcx>,
16 variance: ty::Variance,
19 ) -> RelateResult<'tcx, UnificationResult<'tcx>> {
29 let mut delegate = ChalkTypeRelatingDelegate::new(infcx, environment);
31 TypeRelating::new(infcx, &mut delegate, variance).relate(a, b)?;
33 debug!("unify: goals = {:?}, constraints = {:?}", delegate.goals, delegate.constraints);
35 Ok(UnificationResult { goals: delegate.goals, constraints: delegate.constraints })
38 struct ChalkTypeRelatingDelegate<'me, 'tcx> {
39 infcx: &'me InferCtxt<'me, 'tcx>,
40 environment: Environment<'tcx>,
41 goals: Vec<InEnvironment<'tcx, Goal<'tcx>>>,
42 constraints: Vec<super::RegionConstraint<'tcx>>,
45 impl ChalkTypeRelatingDelegate<'me, 'tcx> {
46 fn new(infcx: &'me InferCtxt<'me, 'tcx>, environment: Environment<'tcx>) -> Self {
47 Self { infcx, environment, goals: Vec::new(), constraints: Vec::new() }
51 impl TypeRelatingDelegate<'tcx> for &mut ChalkTypeRelatingDelegate<'_, 'tcx> {
52 fn create_next_universe(&mut self) -> ty::UniverseIndex {
53 self.infcx.create_next_universe()
56 fn next_existential_region_var(&mut self, _was_placeholder: bool) -> ty::Region<'tcx> {
57 self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
60 fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
61 self.infcx.tcx.mk_region(ty::RePlaceholder(placeholder))
64 fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
66 .next_region_var_in_universe(RegionVariableOrigin::MiscVariable(DUMMY_SP), universe)
69 fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
70 self.constraints.push(ty::OutlivesPredicate(sup.into(), sub));
73 fn push_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>) {
74 let goal = self.environment.with(self.infcx.tcx.mk_goal(domain_goal.into_goal()));
75 self.goals.push(goal);
78 fn normalization() -> NormalizationStrategy {
79 NormalizationStrategy::Lazy
82 fn forbid_inference_vars() -> bool {