about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2023-05-23 19:34:17 +0200
committerlcnr <rust@lcnr.de>2023-05-30 13:03:40 +0200
commit6f9041bd1572239bec2d8653b84ea4ddd2a7d22d (patch)
tree7209f9775747ea653b3a60a8f4436229254088f8
parent04056b5c04e0574d5631f04baab99d6fcd778550 (diff)
add the leak check to the new solver
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs5
-rw-r--r--tests/ui/higher-ranked/leak-check-in-selection.rs24
2 files changed, 29 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index fdb209fbff8..91a093f30bd 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -137,6 +137,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
     #[instrument(level = "debug", skip(self), ret)]
     fn compute_external_query_constraints(&self) -> Result<ExternalConstraints<'tcx>, NoSolution> {
+        self.infcx.leak_check(ty::UniverseIndex::ROOT, None).map_err(|e| {
+            debug!(?e, "failed the leak check");
+            NoSolution
+        })?;
+
         // Cannot use `take_registered_region_obligations` as we may compute the response
         // inside of a `probe` whenever we have multiple choices inside of the solver.
         let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
diff --git a/tests/ui/higher-ranked/leak-check-in-selection.rs b/tests/ui/higher-ranked/leak-check-in-selection.rs
new file mode 100644
index 00000000000..e8d6cff856c
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check-in-selection.rs
@@ -0,0 +1,24 @@
+// run-pass
+// revisions: old next
+//[next] compile-flags: -Ztrait-solver=next
+#![allow(coherence_leak_check)]
+
+trait Trait: Sized {
+    fn is_higher_ranked(self) -> bool;
+}
+
+impl Trait for for<'a> fn(&'a ()) {
+    fn is_higher_ranked(self) -> bool {
+        true
+    }
+}
+impl<'a> Trait for fn(&'a ()) {
+    fn is_higher_ranked(self) -> bool {
+        false
+    }
+}
+
+fn main() {
+    let x: for<'a> fn(&'a ()) = |&()| ();
+    assert!(x.is_higher_ranked());
+}