alexcrichton opened issue #11590:
The
bindgen!macro was redesigned in https://github.com/bytecodealliance/wasmtime/pull/11328 to have a more flexible configuration of imports/exports/flags. One of the motivations for doing this was to expose the concept ofstoreas a flag on imported functions. Component-model-async imports, for example, get access to the store plus get to be async through theAccessortype. This is a pretty powerful feature compared to what we had prior where you only get&selfor&mut self. While usingselfis more ergonomic it loses expressive power because the store can't be used during the import.With #11328 it's now possible to say this through a flag where
imports: { default: store }in theory means "all imports have access to theStore". Currently, however, this is unimplemented and just panics. The purpose of this issue is to track the implementation of this feature and serve as a discussion point for it.In my head what I was thinking is something along the lines of:
- Currently
"foo": asyncand"foo": async | storeworks.- Currently nothing works and
"foo": storedoes not work. This issue is about fixing that.- When using
async | storeaHostWithStoretrait is created. Functions are defined asasync fnin Rust and the store is provided as an&Accessor<...>- With using just
storemy thinking is that it should also put the function in theHostWithStoretrait. The function signature would be just a plainfnand it would take anAccess<...>(not anAccessor<...>)This will require one of two routes. I've no preference to which:
"foo": storewill require thecomponent-model-asyncfeature- The
AccessandAccessortypes need to not be gated bycomponent-model-asyncAfter all this the idea then is that
"foo": storeis a valid and supported configuration. Hosts then implementHostWithStoreand theAccessprovides access to&mut selfjust as it does today but it additionally provides access to theStoreContextMut<T>through theAsContextMutimplementation.
alexcrichton added the wasmtime:api label to Issue #11590.
alexcrichton added the wasm-proposal:component-model label to Issue #11590.
fuzing commented on issue #11590:
Hi Alex -
I have a rust embedded wasmtime that's utilizing components and has a wit file as follows:
package abc:runtime@0.1.0; interface functions { expensivefunction: func(); // other function definitions here } world with-imports { import functions; }I would like to implement the
expensivefunctionfunction such that it has access to the store (potentially through my custom state):struct CustomState { name: String, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // need access to my store here........ see below for details } // other function implementations go here }I've spent a good while attempting to add (a clone of) my store to my state, such that
expensivefunctionhas access to the store - e.g. something like:struct CustomState { name: String, // adding the store to state store: Option<Store<CustomState>>, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // we want this function to 'burn fuel' because it's expensive to run, so we'd like access to our store // can safely unwrap option because we know it's set up prior to anyone calling let store = self.store.unwrap(); let current_fuel = store.get_fuel().expect("cannot get fuel"); // set_fuel doesn't tolerate underflow, so make sure we don't do that! let actual_charge = std::cmp::min(current_fuel, 100_000); store.set_fuel(current_fuel - actual_charge).expect("error setting fuel"); // // do expensive things after accounting for it by burning 100_000 worth of fuel // } // other function implementations go here } fn init() -> anyhow::Result<()> { .. .. // // prior to this line is boilerplate to set up the wasmtime engine with the appropriate options // let mut state = CustomState { name: "hello".to_string(), // we don't have a store yet, so set to None for now store: None, }; let program_bytes = std::fs::read("target/wasm32-unknown-unknown/release/wasm_component.wasm")?; let wasm_component = Component::from_binary(&engine, &program_bytes)?; // Component Linker let mut linker = ComponentLinker::<CustomState>::new(&engine); let mut store = Store::new(&engine, state); store.set_fuel(FUEL_LIMIT)?; // this doesn't work - can't be cloned - how to access? state.store = Some(store.clone()); // add the with imports component to the linker WithImports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; // below here is boilerplate to call a `run` function in our `wasm_component.wasm` component // if/when this component's `run` function calls our hosted `expensivefunction` we'd like it to // access the store and burn some extra fuel as demonstrated above .. .. }Can you tell me whether the planned implementation outlined in this issue might help me with this - or whether there's another way to achieve my objective (i.e. getting access to the store from the
expensivefunctionimplementation?Many thanks for a great project!
fuzing edited a comment on issue #11590:
Hi Alex -
I have a rust embedded wasmtime that's utilizing components and has a wit file as follows:
package abc:runtime@0.1.0; interface functions { expensivefunction: func(); // other function definitions here } world with-imports { import functions; }I would like to implement the
expensivefunctionfunction such that it has access to the store (potentially through my custom state):struct CustomState { name: String, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // need access to my store here........ see below for details } // other function implementations go here }I've spent a good while attempting to add (a clone of) my store to my state, such that
expensivefunctionhas access to the store - e.g. something like:struct CustomState { name: String, // adding the store to state store: Option<Store<CustomState>>, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // we want this function to 'burn fuel' because it's expensive to run, so we'd like access to our store // can safely unwrap option because we know it's set up prior to anyone calling let store = self.store.unwrap(); let current_fuel = store.get_fuel().expect("cannot get fuel"); // set_fuel doesn't tolerate underflow, so make sure we don't do that! let actual_charge = std::cmp::min(current_fuel, 100_000); store.set_fuel(current_fuel - actual_charge).expect("error setting fuel"); // // do expensive things after accounting for it by burning 100_000 worth of fuel // } // other function implementations go here } fn init() -> anyhow::Result<()> { .. .. // // prior to this line is boilerplate to set up the wasmtime engine with the appropriate options // let mut state = CustomState { name: "hello".to_string(), // we don't have a store yet, so set to None for now store: None, }; let program_bytes = std::fs::read("target/wasm32-unknown-unknown/release/wasm_component.wasm")?; let wasm_component = Component::from_binary(&engine, &program_bytes)?; // Component Linker let mut linker = ComponentLinker::<CustomState>::new(&engine); let mut store = Store::new(&engine, state); store.set_fuel(FUEL_LIMIT)?; // this doesn't work - can't be cloned - how to access? state.store = Some(store.clone()); // add the with imports component to the linker WithImports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; // below here is boilerplate to call a `run` function in our `wasm_component.wasm` component // if/when this component's `run` function calls our hosted `expensivefunction` we'd like it to // access the store and burn some extra fuel as demonstrated above .. .. }Unfortunately, I can't see a way to add the store to my state because it appears to be non-clonable.
Can you tell me whether the planned implementation outlined in this issue might help me with this - or whether there's another way to achieve my objective (i.e. getting access to the store from the
expensivefunctionimplementation?Many thanks for a great project!
fuzing edited a comment on issue #11590:
Hi Alex -
I have a rust embedded wasmtime that's utilizing components and has a wit file as follows:
package abc:runtime@0.1.0; interface functions { expensivefunction: func(); // other function definitions here } world with-imports { import functions; }I would like to implement the
expensivefunctionfunction such that it has access to the store (potentially through my custom state):struct CustomState { name: String, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // need access to my store here........ see below for details } // other function implementations go here }I've spent a good while attempting to add (a clone of) my store to my state, such that
expensivefunctionhas access to the store - e.g. something like:struct CustomState { name: String, // adding the store to state store: Option<Store<CustomState>>, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // we want this function to 'burn fuel' because it's expensive to run, so we'd like access to our store // can safely unwrap option because we know it's set up prior to anyone calling let store = self.store.unwrap(); let current_fuel = store.get_fuel().expect("cannot get fuel"); // set_fuel doesn't tolerate underflow, so make sure we don't do that! let actual_charge = std::cmp::min(current_fuel, 100_000); store.set_fuel(current_fuel - actual_charge).expect("error setting fuel"); // // do expensive things after accounting for it by burning 100_000 worth of fuel // } // other function implementations go here } fn init() -> anyhow::Result<()> { .. .. // // prior to this line is boilerplate to set up the wasmtime engine with the appropriate options // let mut state = CustomState { name: "hello".to_string(), // we don't have a store yet, so set to None for now store: None, }; let program_bytes = std::fs::read("target/wasm32-unknown-unknown/release/wasm_component.wasm")?; let wasm_component = Component::from_binary(&engine, &program_bytes)?; // Component Linker let mut linker = ComponentLinker::<CustomState>::new(&engine); let mut store = Store::new(&engine, state); store.set_fuel(FUEL_LIMIT)?; // this doesn't work - can't be cloned - how to access? state.store = Some(store.clone()); // add the with imports component to the linker WithImports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; // below here is boilerplate to call a `run` function in our `wasm_component.wasm` component // if/when this component's `run` function calls our hosted `expensivefunction` we'd like it to // access the store and burn some extra fuel as demonstrated above .. .. }We're currently using
wasmerand are hoping to move to wasmtime - the mechanism I'm attempting above is used to inject the store into one's state forwasmer's embedding, but wasmer's store is behind an Arc<Mutex> so the Arc can be cloned and the mutex unlocked when contention free access is desired.Unfortunately with wasmtime, I can't see a way to add the store to my state because it appears to be non-clonable.
Can you tell me whether the planned implementation outlined in this issue might help me with this - or whether there's another way to achieve my objective (i.e. getting access to the store from the
expensivefunctionimplementation?Many thanks for a great project!
fuzing edited a comment on issue #11590:
Hi Alex -
I have a rust embedded wasmtime that's utilizing components and has a wit file as follows:
package abc:runtime@0.1.0; interface functions { expensivefunction: func(); // other function definitions here } world with-imports { import functions; }I would like to implement the
expensivefunctionfunction such that it has access to the store (potentially through my custom state):struct CustomState { name: String, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // need access to my store here........ see below for details } // other function implementations go here }I've spent a good while attempting to add (a clone of) my store to my state, such that
expensivefunctionhas access to the store - e.g. something like:struct CustomState { name: String, // adding the store to state store: Option<Store<CustomState>>, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // we want this function to 'burn fuel' because it's expensive to run, so we'd like access to our store // can safely unwrap option because we know it's set up prior to anyone calling let store = self.store.unwrap(); let current_fuel = store.get_fuel().expect("cannot get fuel"); // set_fuel doesn't tolerate underflow, so make sure we don't do that! let actual_charge = std::cmp::min(current_fuel, 100_000); store.set_fuel(current_fuel - actual_charge).expect("error setting fuel"); // // do expensive things after accounting for it by burning 100_000 worth of fuel // } // other function implementations go here } fn init() -> anyhow::Result<()> { .. .. // // prior to this line is boilerplate to set up the wasmtime engine with the appropriate options // let mut state = CustomState { name: "hello".to_string(), // we don't have a store yet, so set to None for now store: None, }; let program_bytes = std::fs::read("target/wasm32-unknown-unknown/release/wasm_component.wasm")?; let wasm_component = Component::from_binary(&engine, &program_bytes)?; // Component Linker let mut linker = ComponentLinker::<CustomState>::new(&engine); let mut store = Store::new(&engine, state); store.set_fuel(FUEL_LIMIT)?; // this doesn't work - can't be cloned - how to access? state.store = Some(store.clone()); // add the with imports component to the linker WithImports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; // below here is boilerplate to call a `run` function in our `wasm_component.wasm` component // if/when this component's `run` function calls our hosted `expensivefunction` we'd like it to // access the store and burn some extra fuel as demonstrated above .. .. }We're currently using
wasmerand are hoping to move to wasmtime - the mechanism I'm attempting above is used to inject the store into one's state forwasmer's embedding, but wasmer's store is behind an Arc-Mutex so a clone().unlock() can be used for contention free access.Unfortunately with wasmtime, I can't see a way to add the store to my state because it appears to be non-clonable.
Can you tell me whether the planned implementation outlined in this issue might help me with this - or whether there's another way to achieve my objective (i.e. getting access to the store from the
expensivefunctionimplementation?Many thanks for a great project!
fuzing edited a comment on issue #11590:
Hi Alex (@alexcrichton ) -
I have a rust embedded wasmtime that's utilizing components and has a wit file as follows:
package abc:runtime@0.1.0; interface functions { expensivefunction: func(); // other function definitions here } world with-imports { import functions; }I would like to implement the
expensivefunctionfunction such that it has access to the store (potentially through my custom state):struct CustomState { name: String, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // need access to my store here........ see below for details } // other function implementations go here }I've spent a good while attempting to add (a clone of) my store to my state, such that
expensivefunctionhas access to the store - e.g. something like:struct CustomState { name: String, // adding the store to state store: Option<Store<CustomState>>, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // we want this function to 'burn fuel' because it's expensive to run, so we'd like access to our store // can safely unwrap option because we know it's set up prior to anyone calling let store = self.store.unwrap(); let current_fuel = store.get_fuel().expect("cannot get fuel"); // set_fuel doesn't tolerate underflow, so make sure we don't do that! let actual_charge = std::cmp::min(current_fuel, 100_000); store.set_fuel(current_fuel - actual_charge).expect("error setting fuel"); // // do expensive things after accounting for it by burning 100_000 worth of fuel // } // other function implementations go here } fn init() -> anyhow::Result<()> { .. .. // // prior to this line is boilerplate to set up the wasmtime engine with the appropriate options // let mut state = CustomState { name: "hello".to_string(), // we don't have a store yet, so set to None for now store: None, }; let program_bytes = std::fs::read("target/wasm32-unknown-unknown/release/wasm_component.wasm")?; let wasm_component = Component::from_binary(&engine, &program_bytes)?; // Component Linker let mut linker = ComponentLinker::<CustomState>::new(&engine); let mut store = Store::new(&engine, state); store.set_fuel(FUEL_LIMIT)?; // this doesn't work - can't be cloned - how to access? state.store = Some(store.clone()); // add the with imports component to the linker WithImports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; // below here is boilerplate to call a `run` function in our `wasm_component.wasm` component // if/when this component's `run` function calls our hosted `expensivefunction` we'd like it to // access the store and burn some extra fuel as demonstrated above .. .. }We're currently using
wasmerand are hoping to move to wasmtime - the mechanism I'm attempting above is used to inject the store into one's state forwasmer's embedding, but wasmer's store is behind an Arc-Mutex so a clone().unlock() can be used for contention free access.Unfortunately with wasmtime, I can't see a way to add the store to my state because it appears to be non-clonable.
Can you tell me whether the planned implementation outlined in this issue might help me with this - or whether there's another way to achieve my objective (i.e. getting access to the store from the
expensivefunctionimplementation?Many thanks for a great project!
fuzing edited a comment on issue #11590:
Hi Alex (@alexcrichton ) -
Our wasmtime embedding is required to be strictly deterministic, and hence all component functions are synchronous. I'm hoping this issue may address our need to avail our host implemented component functions with a mutable reference to the store.
I have a rust embedded wasmtime that's utilizing components and has a wit file as follows:
package abc:runtime@0.1.0; interface functions { expensivefunction: func(); // other function definitions here } world with-imports { import functions; }I would like to implement the
expensivefunctionfunction such that it has access to the store (potentially through my custom state):struct CustomState { name: String, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // need access to my store here........ see below for details } // other function implementations go here }I've spent a good while attempting to add (a clone of) my store to my state, such that
expensivefunctionhas access to the store - e.g. something like:struct CustomState { name: String, // adding the store to state store: Option<Store<CustomState>>, } bindgen!({ path: "wit", world: "with-imports", }); impl abc::runtime::functions::Host for CustomState { fn expensivefunction(&mut self) { // we want this function to 'burn fuel' because it's expensive to run, so we'd like access to our store // can safely unwrap option because we know it's set up prior to anyone calling let store = self.store.unwrap(); let current_fuel = store.get_fuel().expect("cannot get fuel"); // set_fuel doesn't tolerate underflow, so make sure we don't do that! let actual_charge = std::cmp::min(current_fuel, 100_000); store.set_fuel(current_fuel - actual_charge).expect("error setting fuel"); // // do expensive things after accounting for it by burning 100_000 worth of fuel // } // other function implementations go here } fn init() -> anyhow::Result<()> { .. .. // // prior to this line is boilerplate to set up the wasmtime engine with the appropriate options // let mut state = CustomState { name: "hello".to_string(), // we don't have a store yet, so set to None for now store: None, }; let program_bytes = std::fs::read("target/wasm32-unknown-unknown/release/wasm_component.wasm")?; let wasm_component = Component::from_binary(&engine, &program_bytes)?; // Component Linker let mut linker = ComponentLinker::<CustomState>::new(&engine); let mut store = Store::new(&engine, state); store.set_fuel(FUEL_LIMIT)?; // this doesn't work - can't be cloned - how to access? state.store = Some(store.clone()); // add the with imports component to the linker WithImports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; // below here is boilerplate to call a `run` function in our `wasm_component.wasm` component // if/when this component's `run` function calls our hosted `expensivefunction` we'd like it to // access the store and burn some extra fuel as demonstrated above .. .. }We're currently using
wasmerand are hoping to move to wasmtime - the mechanism I'm attempting above is used to inject the store into one's state forwasmer's embedding, but wasmer's store is behind an Arc-Mutex so a clone().unlock() can be used for contention free access.Unfortunately with wasmtime, I can't see a way to add the store to my state because it appears to be non-clonable.
Can you tell me whether the planned implementation outlined in this issue might help me with this - or whether there's another way to achieve my objective (i.e. getting access to the store from the
expensivefunctionimplementation?Many thanks for a great project!
alexcrichton commented on issue #11590:
Makes sense, thanks for explaining. And yes, the feature described here should solve your use case. You'll be able to manipulate the store directly since your host function will be given one of these through which you can get
StoreContextMutthrough which you can manipulate fuel.
fuzing commented on issue #11590:
Fantastic - thanks for the feedback. I'll be sure to put this through its paces once implemented. Cheers!
alexcrichton closed issue #11590:
The
bindgen!macro was redesigned in https://github.com/bytecodealliance/wasmtime/pull/11328 to have a more flexible configuration of imports/exports/flags. One of the motivations for doing this was to expose the concept ofstoreas a flag on imported functions. Component-model-async imports, for example, get access to the store plus get to be async through theAccessortype. This is a pretty powerful feature compared to what we had prior where you only get&selfor&mut self. While usingselfis more ergonomic it loses expressive power because the store can't be used during the import.With #11328 it's now possible to say this through a flag where
imports: { default: store }in theory means "all imports have access to theStore". Currently, however, this is unimplemented and just panics. The purpose of this issue is to track the implementation of this feature and serve as a discussion point for it.In my head what I was thinking is something along the lines of:
- Currently
"foo": asyncand"foo": async | storeworks.- Currently nothing works and
"foo": storedoes not work. This issue is about fixing that.- When using
async | storeaHostWithStoretrait is created. Functions are defined asasync fnin Rust and the store is provided as an&Accessor<...>- With using just
storemy thinking is that it should also put the function in theHostWithStoretrait. The function signature would be just a plainfnand it would take anAccess<...>(not anAccessor<...>)This will require one of two routes. I've no preference to which:
"foo": storewill require thecomponent-model-asyncfeature- The
AccessandAccessortypes need to not be gated bycomponent-model-asyncAfter all this the idea then is that
"foo": storeis a valid and supported configuration. Hosts then implementHostWithStoreand theAccessprovides access to&mut selfjust as it does today but it additionally provides access to theStoreContextMut<T>through theAsContextMutimplementation.
fuzing commented on issue #11590:
Just tested this new functionality and it works like a charm.
One thing that might be of interest.
Accessis gated behind thecomponent-model-asyncfeature, which might not make sense any more.Thank you so much for your effort here - it's much appreciated :folded_hands:
alexcrichton reopened issue #11590:
The
bindgen!macro was redesigned in https://github.com/bytecodealliance/wasmtime/pull/11328 to have a more flexible configuration of imports/exports/flags. One of the motivations for doing this was to expose the concept ofstoreas a flag on imported functions. Component-model-async imports, for example, get access to the store plus get to be async through theAccessortype. This is a pretty powerful feature compared to what we had prior where you only get&selfor&mut self. While usingselfis more ergonomic it loses expressive power because the store can't be used during the import.With #11328 it's now possible to say this through a flag where
imports: { default: store }in theory means "all imports have access to theStore". Currently, however, this is unimplemented and just panics. The purpose of this issue is to track the implementation of this feature and serve as a discussion point for it.In my head what I was thinking is something along the lines of:
- Currently
"foo": asyncand"foo": async | storeworks.- Currently nothing works and
"foo": storedoes not work. This issue is about fixing that.- When using
async | storeaHostWithStoretrait is created. Functions are defined asasync fnin Rust and the store is provided as an&Accessor<...>- With using just
storemy thinking is that it should also put the function in theHostWithStoretrait. The function signature would be just a plainfnand it would take anAccess<...>(not anAccessor<...>)This will require one of two routes. I've no preference to which:
"foo": storewill require thecomponent-model-asyncfeature- The
AccessandAccessortypes need to not be gated bycomponent-model-asyncAfter all this the idea then is that
"foo": storeis a valid and supported configuration. Hosts then implementHostWithStoreand theAccessprovides access to&mut selfjust as it does today but it additionally provides access to theStoreContextMut<T>through theAsContextMutimplementation.
alexcrichton commented on issue #11590:
Yeah that's one where it's possible to ungate it outside of component-model-async but the feature is likely to be on-by-default in the near future so I figured it's fine to leave it there for now
alexcrichton closed issue #11590:
The
bindgen!macro was redesigned in https://github.com/bytecodealliance/wasmtime/pull/11328 to have a more flexible configuration of imports/exports/flags. One of the motivations for doing this was to expose the concept ofstoreas a flag on imported functions. Component-model-async imports, for example, get access to the store plus get to be async through theAccessortype. This is a pretty powerful feature compared to what we had prior where you only get&selfor&mut self. While usingselfis more ergonomic it loses expressive power because the store can't be used during the import.With #11328 it's now possible to say this through a flag where
imports: { default: store }in theory means "all imports have access to theStore". Currently, however, this is unimplemented and just panics. The purpose of this issue is to track the implementation of this feature and serve as a discussion point for it.In my head what I was thinking is something along the lines of:
- Currently
"foo": asyncand"foo": async | storeworks.- Currently nothing works and
"foo": storedoes not work. This issue is about fixing that.- When using
async | storeaHostWithStoretrait is created. Functions are defined asasync fnin Rust and the store is provided as an&Accessor<...>- With using just
storemy thinking is that it should also put the function in theHostWithStoretrait. The function signature would be just a plainfnand it would take anAccess<...>(not anAccessor<...>)This will require one of two routes. I've no preference to which:
"foo": storewill require thecomponent-model-asyncfeature- The
AccessandAccessortypes need to not be gated bycomponent-model-asyncAfter all this the idea then is that
"foo": storeis a valid and supported configuration. Hosts then implementHostWithStoreand theAccessprovides access to&mut selfjust as it does today but it additionally provides access to theStoreContextMut<T>through theAsContextMutimplementation.
alexcrichton commented on issue #11590:
er, wrong button
anlavandier commented on issue #11590:
Yeah that's one where it's possible to ungate it outside of component-model-async but the feature is likely to be on-by-default in the near future so I figured it's fine to leave it there for now
Hi, I would like to point out that the
component-model-asyncis incompatible withno_stduse cases so if it's possible to ungateAcessto use this withno_stdit would be much appreciated.
alexcrichton commented on issue #11590:
Mind opening an issue for that?
anlavandier commented on issue #11590:
Mind opening an issue for that?
@alexcrichton did so, here's the issue #11705
Last updated: Dec 06 2025 at 07:03 UTC