diff options
| author | bors <bors@rust-lang.org> | 2023-08-14 00:33:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-08-14 00:33:17 +0000 |
| commit | 3071e0aef6dfd0a150c3fb1da0abad4ec86ca0aa (patch) | |
| tree | f94595fcf5383971acef3454348b0a1eccd825b5 | |
| parent | e81522aa0e0bef810c8e8298128a652339c992c3 (diff) | |
| parent | b6b5a65ae6714f39a2d2dcf5909fee9f64dd4dcd (diff) | |
| download | rust-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`
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() {} |
