-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Next-gen solver: Compiler "hang" & eventual OOM when facing complex mutually recursive structs & many projections #126196
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
cc @lcnr |
Ofc, I will try to minimize this in the coming hours or days. |
Slightly smaller: Reproducer (78 LOC)use std::sync::{Mutex, Arc, Weak};
use std::collections::HashMap;
pub trait Api: Clone {
type Surface: Surface<A = Self>;
type Buffer: WasmNotSendSync + 'static;
type Texture: WasmNotSendSync + 'static;
type SurfaceTexture: WasmNotSendSync + std::borrow::Borrow<Self::Texture>;
type TextureView: WasmNotSendSync;
type Sampler: WasmNotSendSync;
type QuerySet: WasmNotSendSync;
}
pub trait Surface: WasmNotSendSync {
type A: Api;
}
pub trait WasmNotSendSync: WasmNotSend + WasmNotSync {}
impl<T: WasmNotSend + WasmNotSync> WasmNotSendSync for T {}
pub trait WasmNotSend: Send {}
impl<T: Send> WasmNotSend for T {}
pub trait WasmNotSync: Sync {}
impl<T: Sync> WasmNotSync for T {}
trait HalApi: Api + 'static {}
struct BindGroup<A: HalApi>(Box<Device<A>>);
struct Device<A: HalApi>(LifetimeTracker<A>);
struct LifetimeTracker<A: HalApi>(
Vec<Arc<Texture<A>>>,
ResourceMaps<A>,
Vec<ActiveSubmission<A>>,
);
struct Buffer<A: HalApi>(
A::Buffer,
Arc<Device<A>>,
std::marker::PhantomData<Buffer<A>>,
Mutex<Vec<Weak<BindGroup<A>>>>,
);
struct StagingBuffer<A: HalApi>(
Mutex<Option<A::Buffer>>,
Arc<Device<A>>,
std::marker::PhantomData<StagingBuffer<A>>,
);
struct Texture<A: HalApi>(
Arc<Device<A>>,
std::marker::PhantomData<Texture<A>>,
Mutex<Vec<Weak<TextureView<A>>>>,
Mutex<Vec<Weak<BindGroup<A>>>>,
);
struct TextureView<A: HalApi>(
A::TextureView,
Arc<Texture<A>>,
Arc<Device<A>>,
std::marker::PhantomData<TextureView<A>>,
);
struct Sampler<A: HalApi>(
Option<A::Sampler>,
Arc<Device<A>>,
std::marker::PhantomData<Self>,
);
struct ResourceMaps<A: HalApi>(
HashMap<i32, Arc<Buffer<A>>>,
HashMap<i32, Arc<StagingBuffer<A>>>,
HashMap<i32, Arc<Texture<A>>>,
HashMap<i32, Arc<TextureView<A>>>,
HashMap<i32, Arc<Sampler<A>>>,
HashMap<i32, Arc<BindGroup<A>>>,
HashMap<i32, Arc<A>>,
HashMap<i32, Arc<A>>,
HashMap<i32, Arc<A>>,
HashMap<i32, Arc<A>>,
HashMap<i32, Arc<A>>,
);
struct ActiveSubmission<A: HalApi>(
ResourceMaps<A>,
Vec<Arc<Buffer<A>>>,
Vec<std::marker::PhantomData<A>>,
);
fn main() {
check::<BindGroup<_>>();
fn check<T: WasmNotSync>() {}
} Even smaller: Reproducer (61 LOC)use std::sync::{Mutex, Arc, Weak};
pub trait Api {
type Surface: Surface<A = Self>;
type Buffer: WasmNotSendSync + 'static;
type Texture: WasmNotSendSync + 'static;
type SurfaceTexture: WasmNotSendSync + std::borrow::Borrow<Self::Texture>;
type TextureView: WasmNotSendSync;
type Sampler: WasmNotSendSync;
type QuerySet: WasmNotSendSync;
}
pub trait Surface: WasmNotSendSync {
type A: Api;
}
pub trait WasmNotSendSync: WasmNotSend + WasmNotSync {}
impl<T: WasmNotSend + WasmNotSync> WasmNotSendSync for T {}
pub trait WasmNotSend: Send {}
impl<T: Send> WasmNotSend for T {}
pub trait WasmNotSync: Sync {}
impl<T: Sync> WasmNotSync for T {}
trait HalApi: Api {}
struct BindGroup<A: HalApi>(Box<Device<A>>);
struct Device<A: HalApi>(ResourceMaps<A>);
struct Buffer<A: HalApi>(
A::Buffer,
Arc<Device<A>>,
std::marker::PhantomData<Buffer<A>>,
Mutex<Vec<Weak<BindGroup<A>>>>,
);
struct StagingBuffer<A: HalApi>(
Mutex<Option<A::Buffer>>,
Arc<Device<A>>,
std::marker::PhantomData<StagingBuffer<A>>,
);
struct Texture<A: HalApi>(
Arc<Device<A>>,
std::marker::PhantomData<Texture<A>>,
Mutex<Vec<Weak<TextureView<A>>>>,
Mutex<Vec<Weak<BindGroup<A>>>>,
);
struct TextureView<A: HalApi>(
A::TextureView,
Arc<Texture<A>>,
Arc<Device<A>>,
std::marker::PhantomData<TextureView<A>>,
);
struct Sampler<A: HalApi>(
Option<A::Sampler>,
Arc<Device<A>>,
std::marker::PhantomData<Self>,
);
struct ResourceMaps<A: HalApi>(
Arc<Buffer<A>>,
Arc<StagingBuffer<A>>,
Arc<TextureView<A>>,
Arc<Sampler<A>>,
Arc<BindGroup<A>>,
);
fn main() {
check::<BindGroup<_>>();
fn check<T: WasmNotSync>() {}
} |
"Even smaller" (no longer I-hang but still I-compiletime (32.31s on my machine) + I-compilemem (9GB+)): "Reproducer" (53 LOC)use std::sync::{Mutex, Arc, Weak};
pub trait HalApi {
type Surface: Surface<A = Self>;
type Buffer: WasmNotSendSync;
type Texture: WasmNotSendSync ;
type SurfaceTexture: WasmNotSendSync;
type TextureView: WasmNotSendSync;
type Sampler: WasmNotSendSync;
}
pub trait Surface: WasmNotSendSync {
type A: HalApi;
}
pub trait WasmNotSendSync: WasmNotSend + WasmNotSync {}
impl<T: WasmNotSend + WasmNotSync> WasmNotSendSync for T {}
pub trait WasmNotSend: Send {}
impl<T: Send> WasmNotSend for T {}
pub trait WasmNotSync: Sync {}
impl<T: Sync> WasmNotSync for T {}
struct BindGroup<A: HalApi>(Box<Device<A>>);
struct Device<A: HalApi>(ResourceMaps<A>);
struct Buffer<A: HalApi>(
A::Buffer,
Arc<Device<A>>,
std::marker::PhantomData<Buffer<A>>,
Mutex<Vec<Weak<BindGroup<A>>>>,
);
struct Texture<A: HalApi>(
Arc<Device<A>>,
std::marker::PhantomData<Texture<A>>,
Mutex<Vec<Weak<TextureView<A>>>>,
Mutex<Vec<Weak<BindGroup<A>>>>,
);
struct TextureView<A: HalApi>(
A::TextureView,
Arc<Texture<A>>,
Arc<Device<A>>,
std::marker::PhantomData<TextureView<A>>,
);
struct Sampler<A: HalApi>(
Option<A::Sampler>,
Arc<Device<A>>,
std::marker::PhantomData<Self>,
);
struct ResourceMaps<A: HalApi>(
Arc<Buffer<A>>,
Arc<TextureView<A>>,
Arc<Sampler<A>>,
Arc<BindGroup<A>>,
);
fn main() {
check::<BindGroup<_>>();
fn check<T: WasmNotSync>() {}
} Minimization is prone to distortion (at least with the way I was just pursuing). Stopping right now, will pick it up some other time and will try different approaches that are less aggressive. |
(Replacing
I-hang
|
should be fixed by #125981 |
Fixed by #128828. |
Uh oh!
There was an error while loading. Please reload this page.
Context / History
The original issue is a rustdoc[old solver] compiletime issue: #114891.
I was able to reduce that issue to 211 LOC: #114891 (comment).
I then looked into switching rustdoc's blanket impl synthesizer to use the next solver: #125907.
Ignoring the fact that that's blocked on perf, it would actually make #114891 (comment) hang and alloc until the OS's OOM killer swoops in.
Finally, the reproducer below (to be minimized) is the rustdoc[next solver] "MCVE" turned into a rustc[next solver] issue by "reifying" the obligations registered by
blanket_impl
as Rust code.Fixing this issue would partially unblock #125907 / #114891.
Reproducer
Old solver: Error type annotations needed // cannot infer type of the type parameter
T
declared on the functioncheck
.Next solver: Compiler hang & eventual OOM.
Reproducer (215 LOC)
The text was updated successfully, but these errors were encountered: