Skip to content

Commit

Permalink
Rollup merge of rust-lang#131420 - compiler-errors:post-mono-layout-c…
Browse files Browse the repository at this point in the history
…ycle, r=wesleywiser

Dont ICE when encountering post-mono layout cycle error

It's possible to encounter post-mono layout cycle errors in `fn_abi_of_instance`. Don't ICE in those cases.

This was originally discovered in an async fn, but that's not the only way to encounter such an error (which the other test I added should demonstrate).

Error messsages suck, but this fix is purely about suppressing the ICE.

Fixes rust-lang#131409
  • Loading branch information
jieyouxu authored Oct 9, 2024
2 parents 4fee411 + 17eca60 commit 87046c6
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 5 deletions.
11 changes: 6 additions & 5 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:?}",);
}
Expand All @@ -1200,7 +1201,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
"`fn_abi_of_instance({instance}, {extra_args:?})` failed: {err:?}",
);
}
}
},
}
}
}
59 changes: 59 additions & 0 deletions tests/ui/layout/post-mono-layout-cycle-2.rs
Original file line number Diff line number Diff line change
@@ -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<T>(fut: impl Future<Output = T>) -> 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<T>(&mut self, iterator: T)
where
T: IntoIterator<Item = ()>;
}

impl Blah for () {
async fn iter<T>(&mut self, iterator: T)
//~^ ERROR recursion in an async fn requires boxing
where
T: IntoIterator<Item = ()>,
{
Blah::iter(self, iterator).await
}
}

struct Wrap<T: Blah> {
t: T,
}

impl<T: Blah> Wrap<T>
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();
})
}
23 changes: 23 additions & 0 deletions tests/ui/layout/post-mono-layout-cycle-2.stderr
Original file line number Diff line number Diff line change
@@ -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<T>(&mut self, iterator: T)
LL | |
LL | | where
LL | | T: IntoIterator<Item = ()>,
| |___________________________________^
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`.
25 changes: 25 additions & 0 deletions tests/ui/layout/post-mono-layout-cycle.rs
Original file line number Diff line number Diff line change
@@ -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<T: Trait> {
_x: <T as Trait>::Assoc,
}

fn abi<T: Trait>(_: Option<Wrapper<T>>) {}
//~^ ERROR a cycle occurred during layout computation

fn indirect<T: Trait>() {
abi::<T>(None);
}

fn main() {
indirect::<()>();
}
16 changes: 16 additions & 0 deletions tests/ui/layout/post-mono-layout-cycle.stderr
Original file line number Diff line number Diff line change
@@ -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<Wrapper<()>>`
= 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<T: Trait>(_: Option<Wrapper<T>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0391`.

0 comments on commit 87046c6

Please sign in to comment.