diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 81b828404725c..0a116971e0783 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -1187,10 +1187,11 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { - if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { - self.tcx.dcx().emit_fatal(Spanned { span, node: err }) - } else { - match fn_abi_request { + match err { + FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::Cycle(_)) => { + self.tcx.dcx().emit_fatal(Spanned { span, node: err }); + } + _ => match fn_abi_request { FnAbiRequest::OfFnPtr { sig, extra_args } => { span_bug!(span, "`fn_abi_of_fn_ptr({sig}, {extra_args:?})` failed: {err:?}",); } @@ -1200,7 +1201,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { "`fn_abi_of_instance({instance}, {extra_args:?})` failed: {err:?}", ); } - } + }, } } } diff --git a/tests/ui/layout/post-mono-layout-cycle-2.rs b/tests/ui/layout/post-mono-layout-cycle-2.rs new file mode 100644 index 0000000000000..356f1e777c7d0 --- /dev/null +++ b/tests/ui/layout/post-mono-layout-cycle-2.rs @@ -0,0 +1,59 @@ +//@ build-fail +//@ edition: 2021 + +#![feature(async_closure, noop_waker)] + +use std::future::Future; +use std::pin::pin; +use std::task::*; + +pub fn block_on(fut: impl Future) -> T { + let mut fut = pin!(fut); + // Poll loop, just to test the future... + let ctx = &mut Context::from_waker(Waker::noop()); + + loop { + match fut.as_mut().poll(ctx) { + Poll::Pending => {} + Poll::Ready(t) => break t, + } + } +} + +trait Blah { + async fn iter(&mut self, iterator: T) + where + T: IntoIterator; +} + +impl Blah for () { + async fn iter(&mut self, iterator: T) + //~^ ERROR recursion in an async fn requires boxing + where + T: IntoIterator, + { + Blah::iter(self, iterator).await + } +} + +struct Wrap { + t: T, +} + +impl Wrap +where + T: Blah, +{ + async fn ice(&mut self) { + //~^ ERROR a cycle occurred during layout computation + let arr: [(); 0] = []; + self.t.iter(arr.into_iter()).await; + } +} + +fn main() { + block_on(async { + let mut t = Wrap { t: () }; + t.ice(); + }) +} diff --git a/tests/ui/layout/post-mono-layout-cycle-2.stderr b/tests/ui/layout/post-mono-layout-cycle-2.stderr new file mode 100644 index 0000000000000..ad01c2694faf5 --- /dev/null +++ b/tests/ui/layout/post-mono-layout-cycle-2.stderr @@ -0,0 +1,23 @@ +error[E0733]: recursion in an async fn requires boxing + --> $DIR/post-mono-layout-cycle-2.rs:30:5 + | +LL | / async fn iter(&mut self, iterator: T) +LL | | +LL | | where +LL | | T: IntoIterator, + | |___________________________________^ +LL | { +LL | Blah::iter(self, iterator).await + | -------------------------------- recursive call here + | + = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future + +error: a cycle occurred during layout computation + --> $DIR/post-mono-layout-cycle-2.rs:47:5 + | +LL | async fn ice(&mut self) { + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0733`. diff --git a/tests/ui/layout/post-mono-layout-cycle.rs b/tests/ui/layout/post-mono-layout-cycle.rs new file mode 100644 index 0000000000000..8d136190c0052 --- /dev/null +++ b/tests/ui/layout/post-mono-layout-cycle.rs @@ -0,0 +1,25 @@ +//@ build-fail +//~^ cycle detected when computing layout of `Wrapper<()>` + +trait Trait { + type Assoc; +} + +impl Trait for () { + type Assoc = Wrapper<()>; +} + +struct Wrapper { + _x: ::Assoc, +} + +fn abi(_: Option>) {} +//~^ ERROR a cycle occurred during layout computation + +fn indirect() { + abi::(None); +} + +fn main() { + indirect::<()>(); +} diff --git a/tests/ui/layout/post-mono-layout-cycle.stderr b/tests/ui/layout/post-mono-layout-cycle.stderr new file mode 100644 index 0000000000000..47f7f30b1cb4c --- /dev/null +++ b/tests/ui/layout/post-mono-layout-cycle.stderr @@ -0,0 +1,16 @@ +error[E0391]: cycle detected when computing layout of `Wrapper<()>` + | + = note: ...which requires computing layout of `<() as Trait>::Assoc`... + = note: ...which again requires computing layout of `Wrapper<()>`, completing the cycle + = note: cycle used when computing layout of `core::option::Option>` + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: a cycle occurred during layout computation + --> $DIR/post-mono-layout-cycle.rs:16:1 + | +LL | fn abi(_: Option>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0391`.