]> git.lizzy.rs Git - rust.git/commitdiff
Use TypeRelating for instantiating query responses
authorMatthew Jasper <mjjasper1@gmail.com>
Sat, 29 Feb 2020 12:28:32 +0000 (12:28 +0000)
committerMatthew Jasper <mjjasper1@gmail.com>
Sat, 29 Feb 2020 12:28:32 +0000 (12:28 +0000)
src/librustc_infer/infer/canonical/query_response.rs
src/test/ui/nll/user-annotations/type-annotation-with-hrtb.rs [new file with mode: 0644]

index f4196e576054af9fc2224d71d5abb8db8d040746..2873618cfadc1f92b648f55eebcd5e51b23d5677 100644 (file)
     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 @@ pub fn instantiate_nll_query_response_and_region_obligations<R>(
                 }
 
                 (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)?;
                 }
 
                 _ => {
@@ -656,3 +675,55 @@ pub fn make_query_region_constraints<'tcx>(
 
     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
+    }
+}
diff --git a/src/test/ui/nll/user-annotations/type-annotation-with-hrtb.rs b/src/test/ui/nll/user-annotations/type-annotation-with-hrtb.rs
new file mode 100644 (file)
index 0000000..1f7c060
--- /dev/null
@@ -0,0 +1,33 @@
+// Regression test for issue #69490
+
+// check-pass
+
+pub trait Trait<T> {
+    const S: &'static str;
+}
+
+impl<T> Trait<()> for T
+where
+    T: for<'a> Trait<&'a ()>,
+{
+    // Use of `T::S` here caused an ICE
+    const S: &'static str = T::S;
+}
+
+// Some similar cases that didn't ICE:
+
+impl<'a, T> Trait<()> for (T,)
+where
+    T: Trait<&'a ()>,
+{
+    const S: &'static str = T::S;
+}
+
+impl<T> Trait<()> for [T; 1]
+where
+    T: Trait<for<'a> fn(&'a ())>,
+{
+    const S: &'static str = T::S;
+}
+
+fn main() {}