Michael Goulet

@compiler-errors

Joined on Jan 18, 2022

  • This is the third<sup>(I think?)</sup> installment in the "This Month in Errs" series where I try to talk about all the contributions I've done this month. Between the holiday season and getting a pretty bad cold in the middle of the month, it actually turned out a bit more productive than expected. There wasn't a major theme to my contributions this month, though I did kick off some work (e.g. unsafe binders, and async fn in dyn trait) that I expect to follow through with in 2025. And while I didn't work on it this month, I also expect to put up some stabilization reports, namely return type notation (RTN, #109417) and precise capturing in traits (#130044). Stay tuned. Async closures This month was a huge milestone for async closures. Specifically, they're finally stabilized (on nightly), and they're set to land in 1.85[^coincidentally] -- #132706 <small>"Stabilize async closures (RFC 3668)"</small>. I'm pretty proud with the stabilization report, so give it a read if you'd like. [^coincidentally]: Coincidentally also when we'll land Rust edition 2024. I believe I mentioned it in last month's blog post, but during the stabilization process, we decided against stabilizing the async Fn() trait bounds syntax. It was moved behind a new feature gate in #132612 <small>"Gate async fn trait bound modifier on async_trait_bounds"</small>.
     Like 4 Bookmark
  • dyn Trait unsoundness Near the end of this month, I spent a large chunk of time trying to patch an unsoundness with dyn Trait types. I filed an issue for this in #133361 <small>"Coherence with object types with overlapping supertrait projections is incomplete"</small>. I left a brief comment about the problem in the issue, but The tl;dr is that we handle associated type bounds in dyn traits (like "Item = i32" in dyn Iterator<Item = i32>) in a funky kind of way when they come from supertrait bounds, like: /// An iterator that only returns `i32`s trait ConstrainedIterator: Iterator<Item = i32> {} impl<T> ConstrainedIterator for T where T: Iterator<Item = i32> {} // You can now write `dyn ConstrainedIterator` instead of typing
     Like  Bookmark
  • I've seen some "this month in XYZ" posts recently, and I'm interested in posting my own, highlighting a variety of things I've been contributing to in the Rust compiler in the last month. This covers the month of October, so it's a bit out of date. More details Although I think I'm quite a prolific contributor to the Rust compiler, I often forget exactly what I'm doing day to day and week to week. My contributions often come in response to my being made aware of things that need urgent help, pings from people, hearing about things from the tweet-o-sphere, or most rarely, just having a strike of random inspiration. So, ironically, when I'm "between" work, I often feel like motivation is difficult to find, and feel a bit of despair that maybe I've finally run out of things to do -- impostor syndrome sucks! And it never goes away! Hopefully these blog post will help with that. Const traits
     Like 1 Bookmark
  • For the purposes of keeping the implementation mostly future-compatible (i.e. with gen || {} and async gen || {}), most of this document calls async closures "coroutine-closures". Coroutine-closures are a generalization of async closures, being special syntax for closure expressions which return a coroutine, notably one that is allowed to capture from the closure's upvars. For now, the only usable kind of coroutine-closure is the async closure, and supporting async closures is the extent of this PR. We may eventually support gen ||, etc., and all of the problems and curiosities described in this document apply to all coroutine-closures in general. TyKind::CoroutineClosure The main thing that this PR introduces is a new TyKind called CoroutineClosure and corresponding variants on other relevant enums in typeck and borrowck (UpvarArgs, DefiningTy, AggregateKind). Signature A traditional closure has a fn_sig_as_fn_ptr_ty which it uses to represent the signature of the closure. The problem with this sig type is that it doesn't actually reference the closure input: e.g., for a closure like || -> i32 { 0 }, the ptr type is fn(()) -> i32.
     Like  Bookmark
  • This post attempts to motivate some of the concrete technical reasons why the #![feature(async_closure)] that I've been working on recently[^rework][^more][^more2][^more3] is so complicated. Specifically, why can't we just use || async {} that we can express on stable today, an interesting but very important note about the relationship between a "lending" FnMut and the FnOnce trait that I haven't seen written anywhere yet, and how async closures are a tractable solution to an otherwise intractable problem with lending closures. [^rework]: https://github.com/rust-lang/rust/pull/120361 [^more]: https://github.com/rust-lang/rust/pull/120712 [^more2]: https://github.com/rust-lang/rust/pull/123518 [^more3]: https://github.com/rust-lang/rust/pull/125259 We have async closures at home... You may have tried in the past to make your closures async by writing a regular closure that returns an async block: let x = || async {};
     Like 3 Bookmark