• Ideas on How to Elect Rust Project Directors

    One of the first tasks for the Rust Leadership Council is to elect new Project Directors. But before we can do that, we need to create a process for doing so. To do this, and in the spirit of delegation from the Leadership Council, we've formed a smaller group to focus on designing this process. This group so far consists of myself, Jane Losare-Lusby, and Ryan Levick.

    We have the beginnings of a proposal, but I wanted to write it up in my own blog to help make sure I understand it. Note that this is a draft proposal at best at this point and nothing is set in stone. I also want to recognize Jane's work in coming up with this process. This is largely based on her initial suggestion and I want to make sure I'm not taking credit for something I didn't come up with. But, any failings in this post should be viewed as my own and not hers.

    Read more...
  • An Exercise on Culture

    A few days ago at work we did an exercise on company culture that got me thinking so I thought I'd share some of those thoughts here. I've been interested in organizational culture for a few years now. Some organizations seem to have a great culture while other organizations have a not so great culture. Sometimes culture is improving, and other times it is declining. The declining case can be particularly frustrating because in my experience everyone can see it's getting worse, everyone wants to change it, but nobody knows how.

    One of the reasons I chose to come work for Microsoft is that they seem to be one of the few examples of a large, established organization that intentionally and dramatically changed their culture. I've been curious how they did that, and what other organizations can learn from that.

    It seems like an important part of it is to have regular conversations about culture, such as by doing exercises like the one I'm going to discuss in this post. So with this background in mind, let's talk about the exercise.

    Read more...
  • I'm Here to Serve

    Today we announced on the Rust Blog that the Leadership Council has been created and is now the top level governance body of the Rust Project. I am the Compiler Team's representative to the Council, so I wanted to share a little more about how I hope to approach this role.

    The Leadership Council is new, and in many ways its first tasks will be to define what it is. We know it's sort of a replacement for the Core Team, but it's also supposed to be significantly different. A lot of our first tasks are going to seem relatively mundane: figuring out when we regularly meet, how to propose items to the agenda, how we communicate what we're working on, etc. After that, we can get on to the "more substantial" questions. One colleague of mine told me once that Rust has at least two years of governance debt, and given that they said that two years ago, at this point we probably have at least four years of governance debt!

    While we figure these things out, I know there are a few things I can say about myself and values, and how I hope I can bring these to the Leadership Council. Keep in mind that these are my own opinions. I'm not speaking for the Leadership Council or the Compiler Team, so the priorities I suggest here will evolve over time.

    Read more...
  • Lightweight, Predictable Async Send Bounds

    The last week or two has been exciting in Rust async land. We're making great progress on one of the open questions around async functions in traits, and I think we're close to being ready to propose something officially. In this post, I'd like to describe the proposal and discuss some of the tradeoffs and open questions with it.

    We've had a couple of ideas going around so far. One of the main ones is Return Type Notation (RTN), which Niko describes in his recent post. In my last post, I suggested that we could infer the necessary bounds in many cases.

    While I was excited about inferring bounds at first, one major shortcoming is that it creates new semantic versioning hazards. The inference depends on the body of the the function you've annotated, which means when modifying the function you could easily add or remove bounds from the signature by accident.

    In the discussions we've had since then, we have been converging on a solution that we expect will work in the common cases, but avoids both the verbosity inherent in RTN and the semver hazards with inferring bounds. This is the solution I'll be describing in this post.

    Read more...
  • Inferred Async Send Bounds

    One of the issues we're working on with async functions in traits for Rust is how to attach Send bounds to futures returned by async methods. Niko Matsakis has been writing on this subject recently, so if you haven't seen his posts, definitely check them out! His first post outlines the problem, while the second post introduces a possible solution: Return Type Notation (RTN). I'm going to write this post assuming you're familiar with those.

    I'm mostly a fan of the proposed return type notation. It's a very powerful feature that gives a solution to the Send bound problem but is also generally useful in other cases. There are some significant shortcomings though, so I don't think it should be the only or even primary solution people reach for to solve the Send bound question.

    In this post I'd like to explore some more implicit approaches that address the issue while using much lighter syntax.

    Read more...
  • Hello from Eric's Blog Generator

    As of my previous post, I'm now generating this site using my very own static site generator that I've creatively named Eric's Blog Generator or EBG for short. Depending on how you count, this is the about the fifth time I've changed blogging platforms.

    Read more...
  • Who Makes the Boxes?

    As I've written about before, one of the major features we're working on adding to Rust is to allow async functions in traits. Today we have support in nightly for async methods in traits in static contexts. This lets you write code like the following:

    trait AsyncCounter {
        async fn get_value(&self) -> usize;
        async fn increment_by(&mut self, amount: usize);
    }
    
    async fn use_counter(mut counter: impl AsyncCounter) -> usize {
        counter.increment_by(42).await;
        counter.get_value().await;
    }
    

    This empowers a lot of use cases, but we also want to support this feature in dynamic dispatch contexts. In other words, we'd like to be able to write use_counter like this:

    async fn use_counter(mut counter: &mut dyn AsyncCounter) -> usize {
        counter.increment_by(42).await;
        counter.get_value().await;
    }
    

    While this looks like a straightforward extension on what we already have, I've been surprised by the amount of additional functionality needed to support this change.

    It turns out there are also a lot of design questions that in my mind do not have an obviously right answer. There are cases to be made for many different points in the design space, but ultimately the right one will depend on what people use in practice.

    In this post, I'd like to explore the space for one of these questions.

    Read more...
  • Async Functions in Trait Objects Update

    As 2022 draws to a close, I want to take a moment to look at where we are with supporting async functions in dyn traits (AFIDT) and suggest some ideas for how to make progress in 2023.

    The set the stage, we'd like to make the following snippet of code work:

    trait AsyncCounter {
        async fn increment_by(&mut self, amount: usize);
        async fn get_value(&self) -> usize;
    }
    
    async fn use_counter(counter: &mut dyn AsyncCounter) {
        counter.increment_by(42).await;
        counter.get_value().await
    }
    

    Through the rest of this post we'll see how close we are to getting that working and what's left to get it across the finish line.

    Read more...
  • A Look at dyn* Code Generation

    As I've written about before, an important goal for async Rust is to support async functions everywhere, including in trait objects (dyn Trait). To this end, we are adding a new experimental type called dyn* that will give us more flexibility to support dynamic dispatch for async methods. We now have experimental support for dyn* in nightly Rust now, so we can start to kick the tires and use our experience to inform future development.

    One thing we'd like to ensure is that using dyn* does not impose significant costs above what's already incurred by dyn. Ideally we'd be able to generate essentially the same code for dyn* Trait that we do for dyn Trait. With that in mind, in this post, I'd like to look at some of the code we currently generate. We'll start by looking at dyn Trait objects, and then we'll see how things change for dyn* Trait.

    Read more...
  • Something That Confused Me About Rust Specialization

    I recently read through RFC 1210 to understand Rust's proposed specialization features. I found the example given in Going down the rabbit hole confusing, so I started writing a question to post to IRLO. In the course of writing up my question I also figured out the solution, so now I'm posting my solution here instead.

    Read more...