owned this note
owned this note
Published
Linked with GitHub
---
title: "Design meeting 2024-04-25: Open discussion"
tags: ["WG-async", "design-meeting", "minutes"]
date: 2024-04-25
discussion: https://rust-lang.zulipchat.com/#narrow/stream/187312-wg-async/topic/Design.20meeting.202024-04-25
url: https://hackmd.io/1FasSjY4T_a78hRAsQjO-Q
---
# Discussion
## Attendance
- People: TC, eholk, Daria
## Meeting roles
- Minutes, driver: TC
## async Drop progress
Daria: Our PRs have come to the stage that we need to combine them. We have different people working on different aspects of async drop. My own PRs have been merged here.
TC: Related links:
- https://github.com/rust-lang/compiler-team/issues/727
- https://github.com/rust-lang/rust/pull/121801
- https://github.com/rust-lang/rust/pull/123948
- https://github.com/zetanumbers/rust/tree/postmono_forgettable
- https://zetanumbers.github.io/book/myosotis.html
- https://github.com/rust-lang/rust/pull/120706
- https://github.com/rust-lang/rust/pull/121676
- https://github.com/Bryanskiy/posts/blob/master/default%20auto%20traits.md
Daria: One of the difficulties is in knowing when to use asynchronous drop or synchronous drop.
Daria: One of the questions we came up against is, e.g. how do you implement async drop on a vector?
TC: Are you planning to move forward on the `postmono_forgettable` and turn that into a PR?
Daria: It's currently broken. It's not really a proper solution and would restrict the language too much.
Daria: One question is how macros with unsafe code would escape the error about unforgettable types, e.g.:
```rust
macro_rules! forget {
($t:ty, $e:expr) => {{
// emits `unsafe` keyword = bad?
let _ = unsafe { ::core::mem::transmute::<$t, ::core::mem::ManuallyDrop<$t>>($e) };
}};
}
```
Eric: So this is an example of how things that were sound would become unsound because there are additional guarantees that you would have to uphold.
Daria: Yes, we may need some edition system here. (Except would probably work with attributes instead of a rustc option)
TC: This would be edition hygiene for macros.
Daria: Yes, exactly, and this would require some type system support.
eholk: I wonder if we might already have something like this.
Does this work?
```rust
// crate A (edition 2018+)
macro_rules! fake_async {
($e: expr) => { async { $e }}
}
// crate B (edition 2015)
fn main {
// simple
let f = fake_async!(42);
// complex
let g = fake_async!(async { 42 }.await);
}
```
Daria: I have some thoughts about how effect generics could be applicable here. Technically a bit similar to Yoshua's proposal:
https://github.com/rust-lang/keyword-generics-initiative/pull/56
TC: The test:
```rust
// crate `macros`
//@ edition: 2021
#[macro_export]
macro_rules! fake_async {
($($t:tt)*) => {
async { $($t)* }
};
}
// main crate
//@ edition: 2015
#[macro_use]
extern crate macros;
fn main() {
let _f = fake_async!(42);
let _g = fake_async!(async { 42 }.await);
}
```
TC/eholk: The first example works (`let _f`), the second does not (`let _g`).
eholk: We track from what edition the tokens came. That's probably what explains the second example.
TC/eholk: We should think more carefully about the implications of this when migrating macro fragment specifiers.
## Default auto traits
TC: Bryanskly wrote up an explainer about default auto traits here:
https://github.com/Bryanskiy/posts/blob/master/default%20auto%20traits.md
Perhaps we should read and discuss that. It's short enough.
petrochenkov: I planned to also edit it a bit, but it's probably fine as is, Daria can explain if something is unclear.
## The meaning of `Leak` and `'static`
https://github.com/zetanumbers/posts/blob/main/myosotis.md
TC: When I read the document before, and thought about it for awhile, it made me think of this as an analogy:
```rust
struct Scoped<'s, T: 's> {
inner: T,
_p: PhantomData<fn(&'s ()) -> &'s ()>,
}
impl<'s, T: 's> Scoped<'s, T> {
pub fn new(inner: T) -> Self {
Scoped { inner, _p: PhantomData }
}
}
macro_rules! scoped_let {
($name:ident, $e:expr) => {
let $name = $crate::Scoped::new($e);
{
fn helper<'s, T: 's>(_: &'s Scoped<'s, T>) {}
helper(&$name);
}
};
}
fn main() {
scoped_let!(x, Guard);
// We cannot move `x`.
let x = x;
//~^ ERROR cannot move out of `x` because it is borrowed
}
```
Daria: Yes. Unfortunately this doesn't work with async. :(
## Double drops
Daria: We should think about double drops; things being dropped both synchronously and asynchronously.
TC/eholk: We can have the async drop impl set a flag, then have the sync drop that always runs check that, and then the impl there could decide what to do. It could panic, it could block, etc.
Daria: I consider this to be a suboptimal solution.
(The meeting ended here.)