about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-14 00:33:17 +0000
committerbors <bors@rust-lang.org>2023-08-14 00:33:17 +0000
commit3071e0aef6dfd0a150c3fb1da0abad4ec86ca0aa (patch)
treef94595fcf5383971acef3454348b0a1eccd825b5
parente81522aa0e0bef810c8e8298128a652339c992c3 (diff)
parentb6b5a65ae6714f39a2d2dcf5909fee9f64dd4dcd (diff)
downloadrust-3071e0aef6dfd0a150c3fb1da0abad4ec86ca0aa.tar.gz
rust-3071e0aef6dfd0a150c3fb1da0abad4ec86ca0aa.zip
Auto merge of #114787 - compiler-errors:issue-114783, r=jackh726
Select obligations before processing wf obligation in `compare_method_predicate_entailment`

We need to select obligations before processing the WF obligation for the `IMPLIED_BOUNDS_ENTAILMENT` lint, since it skips over type variables.

Fixes #114783

r? `@jackh726`
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs11
-rw-r--r--tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-1.rs26
-rw-r--r--tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-2.rs26
3 files changed, 62 insertions, 1 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 044fb405e32..ad02ca252c4 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -308,6 +308,15 @@ fn compare_method_predicate_entailment<'tcx>(
     }
 
     if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
+        // Select obligations to make progress on inference before processing
+        // the wf obligation below.
+        // FIXME(-Ztrait-solver=next): Not needed when the hack below is removed.
+        let errors = ocx.select_where_possible();
+        if !errors.is_empty() {
+            let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
+            return Err(reported);
+        }
+
         // See #108544. Annoying, we can end up in cases where, because of winnowing,
         // we pick param env candidates over a more general impl, leading to more
         // stricter lifetime requirements than we would otherwise need. This can
@@ -378,7 +387,7 @@ fn compare_method_predicate_entailment<'tcx>(
     // lifetime parameters.
     let outlives_env = OutlivesEnvironment::with_bounds(
         param_env,
-        infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys.clone()),
+        infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
     );
     let errors = infcx.resolve_regions(&outlives_env);
     if !errors.is_empty() {
diff --git a/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-1.rs b/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-1.rs
new file mode 100644
index 00000000000..9b793642d07
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-1.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+pub trait Foo {
+    type Error: Error;
+
+    fn foo(&self, stream: &<Self::Error as Error>::Span);
+}
+
+pub struct Wrapper<Inner>(Inner);
+
+impl<E: Error, Inner> Foo for Wrapper<Inner>
+where
+    Inner: Foo<Error = E>,
+{
+    type Error = E;
+
+    fn foo(&self, stream: &<Self::Error as Error>::Span) {
+        todo!()
+    }
+}
+
+pub trait Error {
+    type Span;
+}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-2.rs b/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-2.rs
new file mode 100644
index 00000000000..86b10a56c9d
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-2.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+trait AsBufferView {
+    type Device;
+}
+
+trait Error {
+    type Span;
+}
+
+trait Foo {
+    type Error: Error;
+    fn foo(&self) -> &<Self::Error as Error>::Span;
+}
+
+impl<D: Error, VBuf0> Foo for VBuf0
+where
+    VBuf0: AsBufferView<Device = D>,
+{
+    type Error = D;
+    fn foo(&self) -> &<Self::Error as Error>::Span {
+        todo!()
+    }
+}
+
+fn main() {}