Dont ICE when encountering post-mono layout cycle error

This commit is contained in:
Michael Goulet 2024-10-08 16:46:00 -04:00
parent 6a3c45e1c6
commit 17eca60c24
5 changed files with 129 additions and 5 deletions

View File

@ -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:?}",
);
}
}
},
}
}
}

View File

@ -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();
})
}

View File

@ -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`.

View File

@ -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::<()>();
}

View File

@ -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`.