]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #69591 - matthewjasper:query-response-relate, r=nikomatsakis
authorMazdak Farrokhzad <twingoow@gmail.com>
Wed, 11 Mar 2020 09:36:19 +0000 (10:36 +0100)
committerGitHub <noreply@github.com>
Wed, 11 Mar 2020 09:36:19 +0000 (10:36 +0100)
Use TypeRelating for instantiating query responses

`eq` can add constraints to `RegionConstraintData`, which isn't allowed during borrow checking outside of a `CustomTypeOp`. Use `TypeRelating` instead to always push constraints to the obligations list.

closes #69490

1  2 
src/librustc_infer/infer/canonical/query_response.rs

index 77f1c6bf28109fcc8675330f423d5a4b821f0fe7,2873618cfadc1f92b648f55eebcd5e51b23d5677..966bd99787729f19112511dc9f11118508835c2c
@@@ -12,14 -12,15 +12,15 @@@ use crate::infer::canonical::
      Canonical, CanonicalVarValues, CanonicalizedQueryResponse, Certainty, OriginalQueryValues,
      QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse,
  };
+ use crate::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
  use crate::infer::region_constraints::{Constraint, RegionConstraintData};
- use crate::infer::InferCtxtBuilder;
- use crate::infer::{InferCtxt, InferOk, InferResult};
+ use crate::infer::{InferCtxt, InferCtxtBuilder, InferOk, InferResult, NLLRegionVariableOrigin};
  use crate::traits::query::{Fallible, NoSolution};
- use crate::traits::TraitEngine;
+ use crate::traits::{DomainGoal, TraitEngine};
  use crate::traits::{Obligation, ObligationCause, PredicateObligation};
  use rustc::arena::ArenaAllocatable;
  use rustc::ty::fold::TypeFoldable;
+ use rustc::ty::relate::TypeRelation;
  use rustc::ty::subst::{GenericArg, GenericArgKind};
  use rustc::ty::{self, BoundVar, Ty, TyCtxt};
  use rustc_data_structures::captures::Captures;
@@@ -304,13 -305,31 +305,31 @@@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> 
                  }
  
                  (GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => {
-                     let ok = self.at(cause, param_env).eq(v1, v2)?;
-                     obligations.extend(ok.into_obligations());
+                     TypeRelating::new(
+                         self,
+                         QueryTypeRelatingDelegate {
+                             infcx: self,
+                             param_env,
+                             cause,
+                             obligations: &mut obligations,
+                         },
+                         ty::Variance::Invariant,
+                     )
+                     .relate(&v1, &v2)?;
                  }
  
                  (GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => {
-                     let ok = self.at(cause, param_env).eq(v1, v2)?;
-                     obligations.extend(ok.into_obligations());
+                     TypeRelating::new(
+                         self,
+                         QueryTypeRelatingDelegate {
+                             infcx: self,
+                             param_env,
+                             cause,
+                             obligations: &mut obligations,
+                         },
+                         ty::Variance::Invariant,
+                     )
+                     .relate(&v1, &v2)?;
                  }
  
                  _ => {
          for _ in num_universes_in_query..num_universes_in_response {
              universe_map.push(self.create_next_universe());
          }
 -        assert!(universe_map.len() >= 1); // always have the root universe
 +        assert!(!universe_map.is_empty()); // always have the root universe
          assert_eq!(universe_map[ty::UniverseIndex::ROOT.as_usize()], ty::UniverseIndex::ROOT);
  
          // Every canonical query result includes values for each of
@@@ -630,7 -649,7 +649,7 @@@ pub fn make_query_region_constraints<'t
      assert!(givens.is_empty());
  
      let outlives: Vec<_> = constraints
 -        .into_iter()
 +        .iter()
          .map(|(k, _)| match *k {
              // Swap regions because we are going from sub (<=) to outlives
              // (>=).
  
      QueryRegionConstraints { outlives, member_constraints: member_constraints.clone() }
  }
+ struct QueryTypeRelatingDelegate<'a, 'tcx> {
+     infcx: &'a InferCtxt<'a, 'tcx>,
+     obligations: &'a mut Vec<PredicateObligation<'tcx>>,
+     param_env: ty::ParamEnv<'tcx>,
+     cause: &'a ObligationCause<'tcx>,
+ }
+ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
+     fn create_next_universe(&mut self) -> ty::UniverseIndex {
+         self.infcx.create_next_universe()
+     }
+     fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> {
+         let origin = NLLRegionVariableOrigin::Existential { from_forall };
+         self.infcx.next_nll_region_var(origin)
+     }
+     fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
+         self.infcx.tcx.mk_region(ty::RePlaceholder(placeholder))
+     }
+     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
+         self.infcx.next_nll_region_var_in_universe(
+             NLLRegionVariableOrigin::Existential { from_forall: false },
+             universe,
+         )
+     }
+     fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
+         self.obligations.push(Obligation {
+             cause: self.cause.clone(),
+             param_env: self.param_env,
+             predicate: ty::Predicate::RegionOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
+                 sup, sub,
+             ))),
+             recursion_depth: 0,
+         });
+     }
+     fn push_domain_goal(&mut self, _: DomainGoal<'tcx>) {
+         bug!("should never be invoked with eager normalization")
+     }
+     fn normalization() -> NormalizationStrategy {
+         NormalizationStrategy::Eager
+     }
+     fn forbid_inference_vars() -> bool {
+         true
+     }
+ }