]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_infer/src/infer/nll_relate/mod.rs
Add variance-related information to lifetime error messages
[rust.git] / compiler / rustc_infer / src / infer / nll_relate / mod.rs
index 077d2cc20a25c3fdaf7bc8f20c4325f024baf5d1..20be06adfd09e1a37c64991476ee00f4d85cedca 100644 (file)
@@ -55,6 +55,8 @@ pub struct TypeRelating<'me, 'tcx, D>
     /// - Bivariant means that it doesn't matter.
     ambient_variance: ty::Variance,
 
+    ambient_variance_info: ty::VarianceDiagInfo<'tcx>,
+
     /// When we pass through a set of binders (e.g., when looking into
     /// a `fn` type), we push a new bound region scope onto here. This
     /// will contain the instantiated region for each region in those
@@ -78,7 +80,12 @@ pub trait TypeRelatingDelegate<'tcx> {
     /// satisfied for the two types to be related. `sub` and `sup` may
     /// be regions from the type or new variables created through the
     /// delegate.
-    fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
+    fn push_outlives(
+        &mut self,
+        sup: ty::Region<'tcx>,
+        sub: ty::Region<'tcx>,
+        info: ty::VarianceDiagInfo<'tcx>,
+    );
 
     fn const_equate(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
 
@@ -138,7 +145,14 @@ pub fn new(
         delegate: D,
         ambient_variance: ty::Variance,
     ) -> Self {
-        Self { infcx, delegate, ambient_variance, a_scopes: vec![], b_scopes: vec![] }
+        Self {
+            infcx,
+            delegate,
+            ambient_variance,
+            ambient_variance_info: ty::VarianceDiagInfo::default(),
+            a_scopes: vec![],
+            b_scopes: vec![],
+        }
     }
 
     fn ambient_covariance(&self) -> bool {
@@ -239,10 +253,15 @@ fn replace_bound_region(
 
     /// Push a new outlives requirement into our output set of
     /// constraints.
-    fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
+    fn push_outlives(
+        &mut self,
+        sup: ty::Region<'tcx>,
+        sub: ty::Region<'tcx>,
+        info: ty::VarianceDiagInfo<'tcx>,
+    ) {
         debug!("push_outlives({:?}: {:?})", sup, sub);
 
-        self.delegate.push_outlives(sup, sub);
+        self.delegate.push_outlives(sup, sub, info);
     }
 
     /// Relate a projection type and some value type lazily. This will always
@@ -490,6 +509,7 @@ fn a_is_expected(&self) -> bool {
     fn relate_with_variance<T: Relate<'tcx>>(
         &mut self,
         variance: ty::Variance,
+        info: ty::VarianceDiagInfo<'tcx>,
         a: T,
         b: T,
     ) -> RelateResult<'tcx, T> {
@@ -497,6 +517,7 @@ fn relate_with_variance<T: Relate<'tcx>>(
 
         let old_ambient_variance = self.ambient_variance;
         self.ambient_variance = self.ambient_variance.xform(variance);
+        self.ambient_variance_info = self.ambient_variance_info.clone().xform(info);
 
         debug!("relate_with_variance: ambient_variance = {:?}", self.ambient_variance);
 
@@ -574,12 +595,12 @@ fn regions(
 
         if self.ambient_covariance() {
             // Covariance: a <= b. Hence, `b: a`.
-            self.push_outlives(v_b, v_a);
+            self.push_outlives(v_b, v_a, self.ambient_variance_info.clone());
         }
 
         if self.ambient_contravariance() {
             // Contravariant: b <= a. Hence, `a: b`.
-            self.push_outlives(v_a, v_b);
+            self.push_outlives(v_a, v_b, self.ambient_variance_info.clone());
         }
 
         Ok(a)
@@ -835,6 +856,7 @@ fn a_is_expected(&self) -> bool {
     fn relate_with_variance<T: Relate<'tcx>>(
         &mut self,
         variance: ty::Variance,
+        _info: ty::VarianceDiagInfo<'tcx>,
         a: T,
         b: T,
     ) -> RelateResult<'tcx, T> {