about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-09-21 18:02:22 +0000
committerMichael Goulet <michael@errs.io>2023-10-14 15:35:01 +0100
commite425d85518b4e3c2dc6edfccab638db26380198a (patch)
tree6e9b835987ed2da39bf1922a221699d52a90eec1
parent184d5ef1077869c58479d0c3fcab404b99090ed3 (diff)
downloadrust-e425d85518b4e3c2dc6edfccab638db26380198a.tar.gz
rust-e425d85518b4e3c2dc6edfccab638db26380198a.zip
Consider param-env candidates, too
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs22
-rw-r--r--tests/ui/borrowck/alias-liveness/gat-static.rs20
2 files changed, 41 insertions, 1 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 432c7a12071..d0078f71cd8 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -3,6 +3,8 @@ use rustc_data_structures::graph::WithSuccessors;
 use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix};
 use rustc_index::interval::IntervalSet;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
+use rustc_infer::infer::outlives::test_type_match;
+use rustc_infer::infer::region_constraints::VerifyIfEq;
 use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
 use rustc_middle::traits::query::DropckOutlivesResult;
 use rustc_middle::ty::{
@@ -622,6 +624,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
                     bug!();
                 };
                 let tcx = self.typeck.infcx.tcx;
+                let param_env = self.typeck.param_env;
                 let mut outlives_bounds = tcx
                     .item_bounds(alias_ty.def_id)
                     .iter_instantiated(tcx, alias_ty.args)
@@ -633,7 +636,24 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
                     } else {
                         None
                     }
-                    });
+                    })
+                    .chain(param_env.caller_bounds().iter().filter_map(|clause| {
+                        let outlives = clause.as_type_outlives_clause()?;
+                        if let Some(outlives) = outlives.no_bound_vars()
+                            && outlives.0 == t
+                        {
+                            Some(outlives.1)
+                        } else {
+                            test_type_match::extract_verify_if_eq(
+                                tcx,
+                                param_env,
+                                &outlives.map_bound(|ty::OutlivesPredicate(ty, bound)| {
+                                    VerifyIfEq { ty, bound }
+                                }),
+                                t,
+                            )
+                        }
+                    }));
                 if let Some(r) = outlives_bounds.next()
                     && !r.is_late_bound()
                     && outlives_bounds.all(|other_r| {
diff --git a/tests/ui/borrowck/alias-liveness/gat-static.rs b/tests/ui/borrowck/alias-liveness/gat-static.rs
new file mode 100644
index 00000000000..1ab40fe828c
--- /dev/null
+++ b/tests/ui/borrowck/alias-liveness/gat-static.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+trait Foo {
+    type Assoc<'a>
+    where
+        Self: 'a;
+
+    fn assoc(&mut self) -> Self::Assoc<'_>;
+}
+
+fn test<T>(mut t: T)
+where
+    T: Foo,
+    for<'a> T::Assoc<'a>: 'static,
+{
+    let a = t.assoc();
+    let b = t.assoc();
+}
+
+fn main() {}