Bay Area Rust Meetup (Virtual Edition)
The Rust Bay Area Meetup had a hiatus during Covid, but we're back in a virtual format! Join us to hear some titans of the Rust community share the learnings about the technology and community of Rust, including Q&A.
- The Intra-doc Links Saga by Joshua Nelson (jyn514) and Manish Goregaokar (manishearth)
- Lightning: New Rust Libs Team Structure and how to get involved! by Jane Lusby (yaahc)
- Giving back to the community by Andre Bogus (llogiq)
- Rust futures that wrap other futures by Adam Chalmers (adamchalmers)
Hello, hello, hello, welcome. Good morning, good afternoon, good evening from wherever you are joining us from tonight.
My name is Steve Pack. I will be your host of the Rust Bay Area Meetup Virtual Edition.
Yes, that's right. A lot has changed since the last Bay Area Meetup.
I looked into the historical archives. We last came together, at least in the Bay Area, December 2019.
There was 100 plus people crammed into a small space, exchanging germs, sharing pizza.
It's a different world.
I don't know about you, but when COVID started, I immediately decamped to this disused missile silo in Western Montana.
And that's where I'll be broadcasting from today.
Yes, a lot has changed. The thing about meetups, at least at Cloudflare you used, and Mozilla actually, you used to get pizza.
I'm afraid I can't provide pizza.
You'll have to get your own. I recommend you do that now.
Apologies, I was planning to get an NFT version of pizza for everyone to have access to today, but I didn't quite get around to that.
Apologies. But there are some benefits, actually, to the virtual style.
Let me share a couple of things here.
One of the benefits is that we get to have amazing speakers. I put out the call into the ether to see who could come and join us today.
I don't think I exaggerate when I say that absolute titans of the Rust ecosystem and community took up the call.
And that's who's going to be with us today. We're going to start off with Joshua from Cloudflare and Manish, both long-term community members, talking about the IntraDocs link saga.
They're going to talk about some rabbit holes that have a very Rust flavor to them.
Andre, some of you, I learned I can share information with the Rust community.
The way you pronounce Andre's GitHub handle is logic.
I thought it was illogic or maybe L logic. No, it's logic. If you take nothing else away today, that's one thing you've learned.
Andre's going to talk about the community.
As many of you who have been around will know, he's a big contributor to it, both in tools and just being around.
Jane from the Rust Libs team is hoping to stop in to give a quick five -minute lightning talk.
She may be late or she may not make it, but she'll do her best and we'd love to have her.
And Adam, another long-term Rustation at Cloudflare, is going to talk to us about futures and other futures and futures with inside futures that have pins in them.
Again, very Rust theme.
Appreciate that, Adam. So normally in these meetups when they're at Cloudflare, I say that because I gave you pizza, you have to listen to me talk about Cloudflare, but I didn't bring the pizza.
So I'm not going to give the Cloudflare pitch, except to say that we are hiring, and we are hiring specifically for Rust jobs.
So if you want to code Rust at a rocket ship tech company, email rust-jobs at Cloudflare.com.
I can't make it any easier than that. rust-jobs at Cloudflare .com.
You can also just go to the careers page and search for Rust or the other 200 or so engineering positions that are all available all around the world.
London, Austin, Lisbon, San Francisco.
I saw a few remote ones on there as well. So okay, no more pitch, but come work at Cloudflare.
It's really cool. All right. On to the meetup itself.
To try and recreate a little bit of the meetup vibe, we do have questions.
So you can email livestudio at Cloudflare.tv. That's livestudio at Cloudflare.tv.
And when you do that, you should see, yeah, we will see the questions, and then I'll either pass them on to the presenters, or they will see them either way.
So send in your questions. Or if you prefer to call in, go to the Cloudflare.tv forward slash live link, and you'll actually see a phone number there.
You can dial in and ask a real question with your real voice to one of these titans of the community.
So I encourage you to do that. Okay. Enough from me.
I'm going to stop sharing, and I'm going to hand over to Manish and Josh to get us started.
Thank you, guys. Thank you, Steve. Hello.
So I'm Manish Gregoker. Many of you know me. I've been organizing this meetup for a while.
And I'm giving this talk with Joshua Nelson, a member of the Rust Doc team.
And we're talking about intro doc links, which is a feature many of you may know about by now.
Maybe you don't know it by name. But it's a very, very cool feature.
And it took forever to make happen. So we kind of want to tell you about the pain and the wondrousness of making this happen in Rust.
So what are intro doc links?
These are essentially a way to link to items by name, not URL. So in Rust, if you want to, for example, link to a function in your documentation, you normally would have to have a full link to the doc page or a relative path.
But what intro doc links let you do is just say F.
And the Rust doc will figure out exactly what you mean by F, and it'll just insert a link to this here.
These are really nice, because you don't have to type much.
You just type the name that you want.
You don't need to remember Rust doc's URL structure. Before this, you would have to link to things like dot dot slash module slash foo dot struct dot html or something like that.
No one could remember that. It was a pain. It also knows where the crate docs are.
You can link to other crates. So if it's on docs .rs, stuff works the way it should.
It can warn when the link's broken. So it behaves just like an unresolved import when you try to link to something that doesn't exist.
And it even works with re-exports. So if you link to a re-export, it links to the right thing.
As you can see, this feature took three years to make happen.
Someone wrote an RFC for this in 2017.
I and Victoria implemented it in 2018, but it took another two and a half years to actually stabilize.
And the initial implementation was a very fun effort between me and Victoria, also known as Misdreavus, where she knew the basic Rust doc structure of getting this implemented, and I knew the Rust compiler stuff.
So we actually paired, as you can see here, we just we paired back and forth.
There are many more commits down here, but we just paired back and forth, passing the baton.
I was actually visiting family in a different country at the time.
So I would go to bed and I'd wake up with some commits where she'd done some stuff, and then she'd go to bed and I'd wake up with some more commits.
And we would just pass the baton back and forth, squirreling out all the different features.
And there was a lot of nuance to this feature, and it took a lot of work in just this PR.
It took a month and a half to make happen, but eventually we landed it, and it turned out that we were missing a thing.
And the thing we were missing was cross-crate re -exports, where, so let's say if you have two crates, if you have this struct linking to this function in the first crate, the first crate will have its documentation compiled just fine.
But in the second crate, the re-export will, Rustdoc would not be able to re-resolve anything here because it didn't know much about module resolution for other crates.
We didn't have that information in the compiler at the time.
Reconstructing that information was a lot of work.
We had so many different ideas for fixing this, but everything was a lot of work.
And so this feature was almost implemented. I think we even had it available on nightly so people could use it on Docs.rs, but it could not be stabilized because this one thing about re-exports was missing, and Rust stations do use re-exports a lot.
People take their crate and they re-export stuff from other crates all the time.
And if re-exporting something means that its docs are broken, that's not a great trade-off, so we didn't want to do that.
And this just languished, and we kept thinking of ways to fix this, but we just couldn't.
It would require a major compiler refactoring.
And in the end, what happened was Joshua hopped up and was like, what do we need to do to make this happen?
And we had a conversation explaining what needed to be done, and he did the work and realized a lot of the really gnarly refactorings were already done.
I'll hand it over to him to continue.
Absolutely. Yeah, so I looked at this issue. The story of me working IntraDocLinks is sort of the story of me working on RustDoc.
This is how I got involved with the compiler, because I had been working on Rust for I think a year or so now.
And I wanted to use IntraDocLinks in my own project. I was like, this is a really cool feature that I can't use yet.
And every time I look at the issue, no progress, no progress.
And eventually, I'm like, okay, I'm fed up. I'm just going to do it myself.
So I take a look at it, and Manish had written, okay, you need to find a way to take this scope information from the other crate and find a way to persist it into the other crate, right?
You want a way to tell the scope of the documentation where it was originally written.
And so I did that. I said, look at the original module, which in the meantime, Petrochenkov, who works on the compiler also, had done the hard work of making sure that you can see that scoping information between modules.
So that sounds nice and simple. And that PR, that was my first Rustdoc PR.
It was hard, but it wasn't terrible. But that's not the whole story.
So I made this change. I said, okay, look at the original scope information from that other crate.
And this very strange test case started crashing.
And not just with error. Rustdoc internally would crash. And I looked at this, and I'm like, well, A, this is very strange code.
Who would write this? And B, what is Rustdoc doing with this?
Because the error it was giving was something like no def ID found for closure, which means nothing unless you've worked on the compiler for years.
And I look at this, and I'm like, okay, something very strange is going on.
I can go to the next slide. So it turns out that Rustdoc does not see your code as you write it.
The compiler sees your code as you write it. It expands all the configs, and it takes that code, and it compiles it.
Rustdoc takes your code, it takes your functions, and it will actually replace at this time, it would replace the body of every function with an infinite loop.
And I look at this, I'm like, why is Rustdoc replacing function bodies with infinite loop?
Why would this ever make sense to do?
And I go back through the history. I have an adventure with Git log, and I find something in 2017 that says document all platforms for the standard library at once.
So before that time, the standard library was only documented on Linux, which is not a great approach, because it means Linux is kind of the only first class platform with respect to documentation.
So someone had said, okay, well, let's document all the platforms at once, Windows and Mac and Linux.
And the problem they ran into is that, of course, not all code compiles in every platform.
For example, Windows APIs aren't available in Linux and vice versa. So what they did is they said, well, Rustdoc doesn't need to know what the function is doing in order to document it.
All it needs to know is the function signature and the types that it uses.
So it can take the body of the function, which doesn't compile, and just replace it with a loop.
Because a loop in Rust is actually an expression that has the type never.
And never can be converted to any type.
So if you take the function body and you make it a loop, then suddenly it compiles, but it doesn't actually do anything.
It will always compile. And so that seems fine and good, and it worked for a while.
And then we realized, well, there's some subtleties here.
So for example, you can define trait implementations inside of a function.
If you strip those out, then A, the documentation will be wrong.
And B, sometimes the code won't compile at all because you're missing a trait implementation.
So we're like, okay, let's add that back.
Let's do this. And we keep finding more and more edge cases. Oh, in this case, it needs to be added back.
In this case, it needs to be added back. And if you go and look at the original example, and you can flip back to the macro.
Back a few slides. Yeah. What was going on is it sees this macro here, and it replaces the closure with an infinite loop, but it doesn't get rid of the macro.
So the compiler looks at this, and when you try and get to know more information about the macro to document it, it will say, well, I don't know where the closure is, and it will just completely crash, which was not great.
So I look at this, and I look at this, and I'm trying find ways to fix it.
And I'm like, a compiler expert came along, and he said, yeah, we'd have to completely redo how this works.
And I'm like, okay.
Rather than trying to take the function body and turn it into an infinite loop, the original goal was to just not compile that code, right?
There's actually a way to do that.
The compiler has something called the query system. And so the query system, the normal model for a compiler is you do lexing, you do parsing, you expand macros, and then you compile the code.
And the rest compiler does have all those passes, but they're not necessarily in that order.
You can have them intermingled with one another.
So this is called the query system. The query system says we want to end up with a binary at the end here.
And in order to get a binary, we need to do code gen.
And in order to do code gen, we need to parse it.
But it's sort of in the reverse order. You're saying I need this, and in order to get this, I need to do the previous steps.
Rustdoc doesn't need the binary. Rustdoc only needs to do type checking and a very small subset of type checking for the function signatures.
So I look at this, I'm like, okay, well, rather than, if you can go back a slide, yeah.
Rather than trying to type check the whole thing, the query system actually allows you to say exactly what parts of type checking that you want to do.
So I change it rather than type checking the whole function body, only type check the signature.
And that took a very long time, and it was a lot of work, and I think I had like 12 or something links to other issues and PRs in the final change.
But eventually I get it working. It took I think around two or three months.
I get it working. I'm like, great. We can finally stabilize intro documents.
And then three weeks later, I see an issue on GitHub, and it says async standard can no longer be documented on library.
And I look at this, and I'm like, oh, this is bad.
Because the error it's seeing is actually almost exactly the same error that we'd seen in 2017 when we tried to document all the platforms for the standard library.
Async standard is getting those exact same errors. I'm like, I did something wrong here.
And I look at what's going wrong, and it turns out that the difference is that async standard is using async functions everywhere.
It's in the name.
And async functions are not being ignored for type checking. The compiler is still going into those bodies and trying to figure out and trying to compile them.
And I'm like, why is it doing this? It doesn't need to do this, right?
It turns out that when you have an async function, the compiler will internally turn that into another function that returns a future.
If you have an async function that returns result, it's not actually returning result.
It's returning a future that implements result.
So, when the function is desugared is the word for it, you get a function that returns a future.
And to determine what that type is, because it's not just a future, it's some concrete type, the compiler goes and looks at the body, and it generates a type for that.
And so, it creates error.
And I look at this, and I'm like, well, do we actually need to know what the actual type is?
Because Rustdoc doesn't care what the actual type is. Rustdoc only needs to know that it implements future.
And I look at it, and I'm digging through the compiler source.
I'm like, wow, this is really complicated. This is going to be really hard to do.
And I take the line of code that says, should we recurse into the function body?
Should we see whether a type checks? And I say, do that, but only if you're not Rustdoc.
Everybody but Rustdoc gets to know what the type is.
Rustdoc can just ignore it. Rustdoc doesn't care. And I do that, and I make a PR, and someone on the compiler team approves it.
And they say, wow, this is a really big hack.
I say, yeah, this is not great. But it worked. And so, we fixed this issue, async standard builds again, and we got to stabilize introduct.
So, there's a bunch of work after this.
There were a whole bunch of people who helped me convert the standard library to use introduct links, which helped mature the feature and make sure it worked for real world use cases.
But that was the main thing, blocking stabilization, that we thought worked.
All right. Thank you, everyone.
Are there any questions? Very cool, Josh. Looking at the live studio feed, we don't have any questions externally just yet.
I'm going to fire one off to you.
I always wonder how people get involved in the compiler. It just seems to me like this impossibly far away engineering task.
And for you, it was like working on the doc gen because you wanted that to work for your side project.
For the mere mortals sitting out in the crowd, what are other ways to actually get involved in something like the compiler?
Yeah, so, there are a lot of ways to get involved.
You can write documentation for the standard library. You can add new features to the standard library.
You can work on the compiler itself. And you can work on documentation for the Rust language.
And of those, you need to know, like, some Rust in order to document it.
But you don't need to know a ton. You don't need to be an expert.
And we have a whole bunch of instructions. Manisha, if you can go to Rust C dev guide, we have a whole bunch of documentation here on how you can get started.
And there's, like, step-by-step things and how you can get help and who you can talk to.
So, that's a great way to get started with contributing to Rust.
That's cool. Is there a, I know this wasn't specifically a compiler talk, but, like, is there a particular sort of area of need, like, the compiler team has?
Like, where it's most sort of understaffed, say?
So, that's a hard question to answer because I would say a lot of it is understaffed.
Like, the biggest issue we have, I'd say, is manpower.
But a lot of the most understaffed places are probably the dev tools, like Cargo or Rustup or docs.rs.
And those have a much lower barrier to entry, too.
You don't need to be an expert, again.
And you can make a really big impact just by yourself with the help of the maintainers.
Yeah. A couple things I'll add is, firstly, diagnostics are some of the easiest way to get involved in the compiler.
A lot of diagnostics issues are just, like, a couple lines of code change.
The compiler is not that complicated. There's certainly parts of it, like trait resolution, that are a bit intimidating.
But overall, like, the majority of the compiler, it's not that hard to get involved in.
And if you want, like, if you want to have if you want to contribute to the compiler, but you don't want to, like, jump into this large code base that takes a while to compile, I recommend actually contributing to Clippy or something first.
That has been a, like, springboard for a lot of people to contribute to the compiler.
Because Clippy uses all of the compiler stuff, but it's its own repo separate.
And, like, most Clippy PRs are, like, adding a lint or changing a lint. So, you don't need to care about how big the rest of Clippy is.
But, yeah, there are lots of DevTools.
DevTools are, like, a really good place to contribute. Cargo is, I think, it's an interesting code base.
Everyone uses Cargo mostly. And there are probably things you can help with.
Clippy is pretty big. We do a lot of these places, a lot of these code bases do their own mentorship as well.
Rusty also does mentorship.
So, that's the other thing. If you're intimidating, you can get mentorship, especially if you ask around on Zulip or Discord.
Docs.rs, RustDoc, as we've been talking about.
RustDoc has now gotten much bigger and we're better at mentoring as well.
There's also, like, RustUp and RustFormat and, yeah. Yeah, that's cool.
Actually, if Jane makes it later, she's talking about the RustLibs team specifically and how to contribute to that.
So, definitely plenty of options. Cool.
And just last question on questions. No additional questions. So, thank you, guys, very much.
That was an interesting, very Rust-style of rabbit hole. And you did, thankfully, remind me, Manish, I should have mentioned at the start, this sort of meetup was, yeah, like, started at Mozilla, co-hosted by lots of different sort of individuals and companies and whatever.
So, happy to be carrying the baton along.
And thanks to you, Manish and Mozilla for, you know, all the work you did with Rust and getting this meetup off the ground.
Okay. If you finish your screen share, we'll...
Thanks, everyone. Thank you. Thank you. Thank you. So, back quickly to the agenda.
Actually, we'll go back a second. Oh, look. Rust-jobs at Cloudflare.com.
Rust-jobs at Cloudflare .com. You can work with the likes of Josh and Adam, although you haven't met Adam yet.
But you will soon. Hello, Adam. Wave. There you go.
Questions, livestudio at Cloudflare.tv over email or you can dial in if you go to the tv.live.
Now, we're gonna hear from Andre, also known as Logic.
I was joking with Andre and Manish earlier that with the Rust community, it's funny you'll meet people on GitHub or Stack Overflow or anything like that and not in real person in real life necessarily for a while.
And with Andre and Manish both having worked on the Clippy tool, if anyone's ever got recommendations for things they could do better or I suggested the waggly finger.
Andre corrected me. No, no waggly fingers. All helpful suggestions.
Always felt like he was reaching out from his computer all the way across the world to give me some tips.
So, very glad to meet you in person, Andre.
Very much looking forward to hearing about your journey in the community and some of the cool stuff you're working on.
So, I'm going to stop sharing here and please take it away.
Yeah, give me a sec so I can share my screen.
There we are.
So, I'm Andre Bogos.
Most of you will know me as Logic with two L in front and a Q in the back.
And most will have seen my GitHub account or perhaps perhaps on Twitter where I'm also known as a Rust bard for some rhyming reason.
And I'm working at Synth which is a small company doing an open source test data generator.
It's a Rust project too. So, it's also a thing you may want to join if you want to learn Rust.
And I've been blogging about Rust since 2015 a lot.
Also, since last year I'm blogging professionally about Rust and since yesterday also for my company.
And before I learned Rust, I was doing a lot of Java but also a lot of other programming languages because I love programming languages.
And before I found Rust, I was learning a new language every one or two years.
But then in 2015, I found this.
Yes, this is what it looked like in 2015. Now, of course, it looks like this.
And I sort of fell in love with both the language and the way it's designed and implemented in the open and also with the community.
And so, for the last thing I'll be talking about myself is my wife is a yoga instructor.
And with the yoga community, they have the concept of Seva which is serving the community in a way that benefits both the person and the community.
And so, this is basically what I apply to the Rust community.
And boy, has it served me well. So, what I want to convince you of is that this is both easy, approachable, fun and fulfilling.
So, what can one do to serve the community? As you may or may not know, I wrote some Rust code to learn it, which was a lint for Rust then.
And soon, I found that Manish was also doing some work on a tool he called Clippy.
So, we joined forces.
I came with a few lints. And yeah, we've been building Clippy for five years now or almost six years now.
And yeah, it's grown tremendously. We now have more than 400 lints.
And also, the project has more than 500 contributors, which is totally great.
And I also feel that Clippy is kind of a poster child for open and welcoming development.
And again, it's a really good way to get into compiler development.
And yeah, there we are at the compiler development page, of course.
So, it's also not that hard to do something within the Rust code base, because most of it is actually pretty approachable.
And there are many changes you can do that are very self-contained and easy to make, whether it's documentation or even code.
Because, of course, the compiler has been written and rewritten so many times that there ought to be places that are not, let's say, optimal.
And if you can bring in some improvements, even if they are local, then you'll make the whole compiler better.
So, if you are into documentation, as just said, that's also an easy thing to do, mostly.
I think one of the harder Rust PRs I did was a PR to change the number documentation of the Rust number types, because they were all behind macros.
And so, I had to change the macros and the macro invocations, and so on.
It was very interesting.
It was a nice exercise. But again, mostly you can do stuff without learning all of Rust.
I've also soon become an editor at This Week in Rust, because I thought we should perhaps do something like a creator for the week.
And they asked me, do you want to do this?
I said, okay. And so, I've been doing this since 2016, every week.
It's not much work. It's nice. Stay on top of the PR queue and learn about new crates and about funny stuff that people say.
It's nice. So, also, this is all done by volunteers.
So, if you want to join this, just chat us up, send us a mail or something.
I'm also a Redditor for 14 years now. And although I've now mainly on the Rust subreddit, I've sort of disconnected from the rest of Reddit.
Anyway, so, this is also something that I do every week. Just shoot a question, what are people working on?
And do the weekly easy questions thread, which is also nice, because it gives us all kinds of ideas for a new lens.
And so, this is also the Rust users discourse, where I also ask everyone what they're working on every week, which is a very small thing one can do, but someone has to do it.
So, I stepped up and I've been doing it since. Thank you. You're welcome. And so, I became part of the moderation team, because I didn't say no fast enough, apparently.
And I'm also a Rust mentor that page says awesome Rust mentors. I'm sure the other mentors are awesome.
I hope to be too. And it's really easy to become a mentor.
It's not something that you needed to be a demigod to do. So, this is also very, very nice.
Even if you are learning, you can be a mentor for others who are also on the learning curve.
After all, we all are. And you can speak on conferences or, as I did, moderate it or make a workshop or something.
Again, it doesn't need a demigod to do this. You can do this, all of you.
Or if a conference is too large for you, perhaps start with a meetup. This is the one I co-organized and now we have a pandemic, so I usually go to the Berlin online meetup.
Or, of course, speak at other meetups, like a Bay Area Rust meetup, where if someone asks, well, I'm here.
And this is all to convince you that you can join the Rust community.
You can benefit by giving back to the Rust community.
And I feel that if you're doing it right, you should be doing it like this.
Do small things that will help people. And if you do this, you will benefit a lot.
I've learned tremendously doing all this stuff. And also, I have some weight in the Rust community.
When Mozilla was the biggest Rust contributor, I was always asked if I was a Mozilian.
I wasn't. I often wondered. Yeah.
And you learn a lot, you gain a lot, and you can do it, you should do it. Thank you.
Thank you, Andre. Logic. I love the community focus. I have to admit, you can stop screen sharing, too, if you're done with that one.
I remember, like, uh, when I first sort of looked at Rust, I was coding C sharp at the time and just read some interesting article about, like, the, you know, C10K problem, like, you know, handling 10,000 concurrent connections.
And that was yesterday's this was 2014, I think.
And this was yesterday's problem. And tomorrow's problem was, you know, C10M, 10 million concurrent connections.
And I was like, oh, yeah, that's an interesting one.
Like, very different from my day job. Like, how do folks do this? And sort of got led to C and spent a couple of nights writing, like, C programs that were all of five lines and would still crash.
And I was like, this is crazy.
Like, this can't be the way. And didn't sort of find, like, there's so many C programs, obviously, out there, but I just didn't find, like, an easy way to access that community.
And I remember looking around and just, like, how are people looking at this problem?
And Rust came up as this promising alternative. And, yeah, straight away, just sort of got the sense that, like, it was a very welcoming place, even though it was a very intimidating language in its own way, you know?
Like, getting that first program out, you know, and getting it to compile is harder.
But then it just works amazingly well.
That's scary, isn't it?
You forgot this error condition or, like, you're not being exactly clear what's happening here.
And then things just work, which I found super attractive.
But, like, same thing with the community, just the fact that people are always happy to jump on, answer questions.
Like, you know, everybody asks the same questions, I think, when they start.
And, you know, no one seems to tire of it.
There's obviously a lot more Stack Overflow stuff there now. But, yeah, I think community's a very big part of it.
So, very cool to see all the things you've done.
Any, looking at the live stream, no questions.
What about from the rest of the group?
Any questions for Andre? He's contributed to all of our tools or environment in some way.
Any questions from the crowd here? So, Andre, you mentioned that, like, the number bits of the standard library are really hairy.
I think Jane made a PR a few months ago, like, taking all of those macros and making them, like, actual dot comments.
So, it should be a lot easier to contribute to that.
Yeah. Yeah, I saw that as part of, I think I even featured it in the core updates and in this week in Rust.
Yeah, that sounds right. And I wanted to say that the bit about, like, getting started with something that benefits you, like, and then benefits the whole community really struck true with me.
That's how I got involved with the Rust project, is I had, like, this one little feature on Dockster.Rust that I wanted to fix.
And I was, like, okay, I'll just do that one thing.
And then I, like, ended up getting super involved with it. It was a ton of fun.
I would like to know how you came, and maybe this is a human niche, but how you came to choose the most, sort of, hated digital assistant name in the history of the world and decide that was the branding for your tool?
Most hated? I thought that was the app co-pilot.
Oh, yeah, that was me.
I think someone on IRC actually, kind of, so I was writing, at the time, basically, I was having a lot of fun doing compiler plugins.
And, like, lints were one form of compiler plugins.
The predecessor to proc macros, syntax extensions, was another one.
And I was having a lot of fun with them. And I enjoyed writing static analyses.
So, I was poking around with it. And someone, I think, in IRC suggested it would be cool if, like, we could have a thing called Clippy.
And I was, like, oh, yes, that's a good name. I'm going to, now that you have given me a name, I will put effort into making the thing.
This is not the only time I've done something like that.
But, yeah, if you tell me a name that seems clever, I will make the thing behind it if I have the time.
And that's, kind of, what happened.
Yeah. Had you used Office at the time and received helpful hints? Yeah. No, that was the point.
And, I mean, also, like, it is kind of hilarious to me how much the Rust community likes Clippy, given that the Rust compiler is already extremely annoying and tells you that your code is bad.
And then they're, like, no, we want more of this.
Like this, we like this. We want more of this. So, like, in retrospect, I think Clippy is, like, aptly named, given how annoying it can be.
And I'm glad that people use it and like it.
The very funny thing to me is that, like, now that Microsoft uses Rust extensively, they use Rust Clippy, too.
Do we know if any of the original developers of Clippy are around and are using Rust Clippy?
That would be a cool engineering story.
Not that I know of, but it would be cool to find out.
All right. Let's put our feelers out. André, I think you had a quote of the week recently, where, like, new Rust stations are like, oh, why is the compiler preventing me from doing this?
And then experienced Rust stations say, oh, why isn't the compiler preventing me from doing this?
So, I think as you gain more experience, you come to enjoy the handrails that guide you to the right direction.
I think my response to that quote was that, like, at some point as an experienced programmer, you end up, and I was at the time when you said that, I was dealing with exactly this, which is, I am doing something horrible.
Like, morally, the compiler should prevent me from doing this.
But the compiler is preventing me from doing this for reasons that, like, it shouldn't be preventing me from doing this, actually.
Like, I know that this should compile.
I also know that I should not have written this code in the first place, but you should just let me build this anyway, which is what I was dealing with at the time.
I remember in the earlier days, it was, one of the ones was, like, this should compile, because I do this in C++ all the time, or maybe finished with, and it never blows up.
And it's like, well, maybe it doesn't blow up for a week, a month, a year, maybe even a few years.
But, you can't prove that it won't. So, yeah, common theme.
Cool. Also, recently on the subreddit, someone asked, why is the compiler smarter than me?
And I told them, no, the compiler isn't smarter than you, but it is at an advantage, because it only has to check your code, not come up with it.
That's your task. And also, it's got all these awesome improvements by wicked smart folks that make it more helpful, and incidentally, also make it seem smarter.
So, there you have it. Cool.
I'm still going to go with the waggly finger as my thing, however much it's helpful.
Cool. Any other last questions for Ondrej? Okay. Go back to regular program.
Oh, look, there's that link again. crossjobs.Cloudflare.com. All right, let's skip past that.
Oh, careers. Cloudflare.com. Yeah, okay. Questions, we accept questions, live studio at Cloudflare.tv, or go to Cloudflare.tv live, and you can dial in.
That was a great talk. Thank you, Ondrej. And Jane gave us warning that she wouldn't be able to make this, so I just didn't update the agenda.
So, that's my bad. Actually, at the Rust board, I think it was, or foundation board.
So, if there was going to be a reason that you couldn't make a Rust talk, that would be the best one I think I could come up with, but maybe Jane will catch us at the end.
Hope so. So, we're going to move on to Adam Chalmers, long-term Cloudflare Rustation, very active in the Cloudflare Rust Club room, one of the most chatted chat rooms in Cloudflare.
I'm going to stop sharing, Adam, and I'm looking forward to your chat on, well, I think the title might have changed since I wrote this.
So, why don't I just say, handing over to Adam for...
Hello. Can you all see the screen? We can. Cool. Okay. Hello. My name is Adam.
I'm an engineer at Cloudflare, and I used to joke that I was the most prominent Australian Rust user inside this one particular internal work channel, but I then realized that Steven actually is my competitor for that title.
So, one day, the two of us will sort it out, but until then, we're going to be cooperating.
Code trumps organizing meetups, Adam, so you get to take it. I'm not going to disrespect someone who lives inside a nuclear missile bunker or something like that, but we'll sort it out offline.
So, yes, my name's Adam. I'm going to be talking about Rust async today.
I started off writing Rust code and consuming async and not really needing to know how it worked under the hood, and that's really nice.
I'm the kind of programmer who I want to know as little as I can to get my job done, and then once my job's done, maybe I'll go back and learn about how it works.
But I really want to be able to just get it working first, and if I can Google something or look it up on Stack Overflow or ask in the Rust Discord, I'll be happy with that.
So, I was going to give this talk about how to make futures that wrap up other futures, and then as I realized...
As I was writing this talk, I realized I don't actually fully understand it.
I really didn't understand how my code actually worked.
I just knew that it did work through testing and the compiler and everything.
So, I kind of went down this rabbit hole of trying to figure out, okay, well, what is all this generated code from other people's crates actually doing?
So, that's kind of what I'm going to be talking about today.
You're looking a bit more at pin and how futures work. The original talk was just going to be a nice, simple talk about futures.
It was going to be inside Rust futures and inside look at Rust futures inside other Rust futures.
But unfortunately, that talk is not going to see the light of day.
Like I said, my name is Adam.
I'm an engineer at Cloudflare. Before that, I was living in Australia, going to the University of Sydney, and moved to the USA for tech work, like a lot of Australians end up doing these days.
I've been working on Cloudfed Tunnel for a few years now, which my friend, the hacker known as Alex from Twitter, recently dissed it as being, saying it was just production-grade ngrok, but that's actually a really solid sales pitch, in my opinion.
And currently, I'm working on Gateway, which is a product that sends all the traffic from employee devices or corporate devices through some filters, and you can filter out phishing links, and filter out malware websites, and stop data exfiltration, and route people to things that aren't actually publicly accessible on the Internet to keep your infrastructure secure.
You may notice I look a little bit different from when I was at RustConf a few years ago.
The COVID pandemic altered my beard growth a lot and put a very weary look into my eyes.
So that's what I looked like if you ever met me at RustConf.
So we started working with Rust in a pretty small way on my team.
We wanted to write some monitoring infrastructure to see how long a tunnel takes to come up.
And I had a couple of places in this program where I needed to check some condition that took a while to be met.
Maybe it was checking that a tunnel came up properly, or checking that a DNS record had been provisioned properly.
And there were all these parts where I needed to take some condition and wait for it to be true, occasionally polling it, and then if it failed, restart it with a certain amount of time.
And that way transient Internet errors, transient disconnects, whatever, would be retried.
But to eventually give up after a certain time, and to tell me how long it took to succeed, if it did succeed.
So I figured, OK, I've done this pattern a few times in this codebase.
It's time to make a wrapper, or an abstraction, or a function for it.
And when I was doing this, it was 2018.
So Rust did not have any async support in the language yet. Maybe it did in the nightly unstable world.
But I was pretty new to it, didn't want to touch that stuff.
So I just wrote a big loop, loop called a closure. And the closure could return something, or it could sleep.
But then async-await came around. And I thought, OK, yeah, now I can finally start using an event loop.
And I don't have to just parallelize this across all the different CPUs.
I can just use one CPU, because most of, really, the program spends 49 out of every 50 seconds just sleeping.
So I tried to convert it to async. You've probably used async before. I'm not going to waste too much time explaining how to use it.
This is going to be more about how it's implemented under the hood.
But async functions, as one of the previous presenters mentioned, async functions are really just syntactic sugar for functions that return a future object.
And a future is a trait. It has a method called pull, which lets you pull it, see if it's finished.
And when you await a future, you're really just pulling it until it resolves.
So future is pretty straightforward to implement.
Let me put on my fancy laser pointer. Please restrain your cats who are watching this talk.
So we're just going to input the future trait.
I'm going to make a little struct called randomNum. And it's going to implement future.
And when the future resolves, it's going to give you a random number.
So futures have an output, which is whatever the value is that they eventually resolve to.
And there's a function called pull, which you have to implement.
And it takes self, and it takes in some context, whatever. We don't have to worry about that yet.
But when your future is done, it returns pullReady. And so I'm just going to return pullReady and have a random number.
So that's implementing a very straightforward future.
But we'd like to implement a future that's a little bit more complicated.
You can use future methods like map, or andThen, which return futures that wrap up other futures inside them.
These are called combinators.
So I want to make a future called restartable. And it's going to wrap another future up and let you restart it in all the ways we talked about before.
So I know this type signature is very long. It's always bad news when you have a type signature that's more than five lines.
But bear with me. We're going to go through it.
It takes in a future. We know this future can be generic because we can't know in advance what kind of future we're going to get.
So it's going to take some future of type future, which is generic.
But we know it has to at least implement the future trait.
And if that future returns an error, we want to be able to retry it.
So we're also going to take in a factory to make that future again if we need to recreate it.
And that's just going to be a function that outputs the new future of the same type as the first one we get.
So you can see here we're saving the factory.
And we're going to time how long this takes.
So the struct is going to have an option to mark when it started. And the timeout is optional.
If you really want to have it loop forever, that's fine. And when the future eventually resolves, we're going to test it to see if it was OK or not.
So the test is another type, which is just going to be generic. And it's just going to be a function that takes in whatever the future outputted, and write some code.
And it'll just return result, because that's the idiomatic way for Rust programs to say what they returned.
So we've seen how to define the struct. And now we just need to implement a future, which is really just a matter of writing that poll method.
And this is where it gets tricky. There we go. So we're going to, OK, I said we wanted to time things.
So we'll just start a little timer. Just start as an option.
So we're going to set the option to be now. And we're going to get the first time.
Now, because we have this stored future in a field, we're just going to pull that future.
And we're going to see what the result of pulling that was.
That'll tell us whether things are OK or not, and whether we need to keep pulling.
But as soon as we do this, we run into a problem. We get this compiler error here, saying we can't call a poll method.
No method named poll found for the type parameter of future.
Now, I know when I wrote this, we know future is a future. So it should have a poll method.
And of course, as often happens when I have a confusing Rust error, I just need to actually keep reading the error.
Because they can be long, but every line is actually useful.
So it's saying the method is not found in future.
The method is found in pin mutable reference to future. So looking a bit more closely, I see that the poll signature has a receiver of type pin mutable reference to self.
Methods always have receivers. They can be probably self, or and self, or and mute self.
And this is just a fourth kind of receiver that you might need.
But I've never seen that before. So let's learn about what pin actually is.
I thought pin was really complicated when I first started this.
And after the last couple of days of trying to really grapple with it to be able to talk about it to all of you, pin's actually simpler than I thought.
The first thing you know about pin is what problem is it solving?
And the problem is self-referential types.
Structs that have pointers to other parts of the struct. These are kind of hard to work with.
Because say you have some struct, right? And you have a field in that struct.
And you have a pointer. It's also a field in that struct.
But the pointer is pointing to this field. It's pointing to itself. That's all well and good.
That's legal. That's valid. You're allowed to. It's no crime.
The problem is if we then move this struct, we moved somewhere else in memory, this field here was still pointing to the old location, right?
If you move them, the pointer that was pointing to some field of the struct, you didn't change the pointer.
The pointer is still pointing to memory.
But now it's invalid, right? You have this kind of dangling pointer.
Now if you change the pointer as well, then everything's fine.
But if you don't, you have undefined behavior. And Rust has a saying, which is we don't like undefined behavior.
Please don't make undefined behavior happen.
We'll be very sad if there's undefined behavior. It's a little bit of a Rust saying that I made up right now.
So the solution is actually pretty simple.
There's nothing inherently wrong with self-reference. The only problem is self-reference and moving values around.
So there's a simple solution. Just don't move the value.
And you know, in Rust, we try not to make programmers remember all these little rules in their head.
If you can enforce it in the compiler, we should just let the compiler catch it for you.
So really, the problem pin is solving is self -reference.
And it solves it by stopping you from moving self-referential things. So from the Rux docs say, it's useful to have objects that are guaranteed not to move.
Their placement of memory does not change. So self-reference is one of those examples where it's useful.
And self -reference is, it hasn't come up in my Rust coding, at least.
But the thing that really helps with is that futures are inherently self-referential.
They do have this self-reference in them. So I'm not going to explain why in this talk.
It's a bit out of scope. But I will have a link at the end that explains it.
So if you want to pull a future, it has to be pinned into place.
It cannot move from that place in memory. So diving a little bit more into the standard library.
Inside the pin module, there's a struct called pin. And remember, we spoke about how we want to keep this, we want to keep pointers to memory that can't be moved.
So say you have some data and you have a pointer that's pointing at that data.
You want to make sure the point is always valid and so that the data never moves.
All we need to do is wrap that pointer in pin. Now the Rust compiler will make sure that this data does not move around.
It's been pinned in place.
So as it says, the wrapper makes the pointer pin its value in place.
And now we can safely do self -reference because we know that the value is not going to move.
Except that sometimes it can. There's a little exception built in here.
Cannot be moved unless it implements unpin. So let's talk about unpin for a second.
You know what?
Let's not talk about unpin because it's actually not the slide that I'm on right now.
We'll talk about it in just a second. We'll get there, I promise. So the problem we had before was that we have this pinned reference to self and we want to get a reference to one of the fields in the struct, right?
And this field is the future and we want a reference that we can poll it.
So we have self wrapped up in this pin, but we also want to be able to access its fields.
And that's not going to happen by itself.
We need to write some code to do that. This is called projection.
Projection is when you think all the problems that you have, you actually tell your therapist that she's the one who has them.
But in Rust, it's got a different meaning.
Sorry, my wife is a therapist. We talk about this. My Rust code, when it projects, is doing something different.
It is taking a pinned struct and just giving you access to one of the fields of it.
So you can take a pinned struct and you can get a reference to the fields.
And if you want, this reference can be pinned or it can just be a normal reference.
You can choose whichever one is going to be useful for you.
Generally, unless you really need it to be pinned, you should just choose a regular reference because they're easy to work with.
You can do more things with them. But if you really need a pinned reference, like if the field is a future and you need to call poll in the future, then calling poll requires something to be pinned, then you can get a pinned reference.
So projection, the problem here that projection solves is you have a pinned thing and you need to get some field of it.
And projection is just code, just some code to get the field.
But to know how to write the projection code, we have to talk about the unpinned trait.
When I first read about unpinned, I was like, God, I barely understand what pinned means.
Now I have to learn what things are unpinned.
And this kind of dualist thing is not working out for me. But I'm going to try and make it easy because it's actually much easier than I thought.
The key is that unpinned is normal.
Almost everything you do in Rust is unpinned. It's an auto trait.
So you don't even have to implement it yourself. The Rust compiler will implement it for you when it should be implemented.
Unpinned is normal. Unpinned is the default.
Almost every standard library type is unpinned. So all of your favorite types, I8, I16, I32, other types, they're all probably just unpinned.
References to unpinned types are unpinned, and types made of unpinned types are unpinned.
So most of the structs that you build will actually also be unpinned. So I've told you what implements unpinned, but what does it actually mean?
Why is there an unpinned trait?
The unpinned trait is for types which are safe to move, even if they're pinned.
I know we said you can't move things that are pinned, but you're actually allowed to move things if they're pinned if the pinning doesn't do anything.
Like, pinning really only matters if there's some kind of pointer bullshit going on there, if there's some pointer that's pointing to itself and it's doing that kind of thing where you're like, ah, I would rather not do this.
But if you have an I32 in memory and you pin it, okay, whatever, nothing's changed.
Pinning doesn't actually change its behavior at all because it wasn't pointing anywhere in the first place.
So if something implements unpinned, it's the Rust compiler saying, I know the pinning doesn't do anything.
Or to put it another way, if you have a pinned reference to something and a regular reference to something, if that something is unpinned, it's the same thing.
Like, pinning something that has no self-reference and is therefore unpinned, it's a no-op.
Again, this is an auto trait.
This isn't something you have to really think about. It's something the Rust compiler will automatically derive, just like send or sync or size, I guess.
So now that we know that, we can talk about projection. Because it turns out that the way to project is pretty different depending on whether things are unpinned or not.
You know, as you may have seen, as you may have gotten an intuition for before, if things are unpinned, they're kind of easier to work with.
There's fewer ways for it to go wrong. And you can see this because when we are writing projections, really all we're doing is we're data out of a pin and then maybe moving it into a pin if you want a pin reference to it.
So if we look at the standard library and we actually go to the docs for pin, pin usually has pairs of methods.
And some of them are safe if the target is unpinned. And usually they're unsafe otherwise.
So if you're putting something into a pin, as long as it's unpinned, totally fine, all safe, do what you want.
You really can't break anything because, you know, it's unpinned.
There's no references going on. It's whatever.
But if you're using something that doesn't implement unpinned, like a future, for example, then you have to actually pay attention.
And in Rust, unsafe just means like pay attention.
There are rules here you have to follow. The compiler can't enforce these rules for you.
Unsafe isn't bad. Unsafe doesn't mean you're a bad programmer.
Unsafe doesn't mean you're doing something dangerous and you shouldn't be writing it.
Unsafe really just means like, hey, the Rust compiler can't follow these rules.
You have to follow them for you. The compiler is like tagging out, handing you the baton, you're going to run this lap.
So you can see here that there's pairs of similar methods.
The only difference is that if the target requires pinning, then it's unsafe.
There's some rules you have to follow around, you know, how to do this.
They're kind of explained in the docs. I'll link to them after.
So if you are like me, you're like, I know that unsafe code is okay to write, but I don't really want to.
You know, if I have a choice, I'd rather not write it.
I was part of a research survey where a PhD student was researching security of different programming languages, and we spoke for an hour or so.
And one of her questions was, you know, how often do you write unsafe Rust code and what do you write it for?
And I said, never. And she was kind of surprised. And she said, oh, you're the first person who's never written unsafe Rust code that I've talked to, which I don't know if that's a good or a bad thing.
But, you know, generally I'm writing, I like using libraries to handle that stuff for me.
You know, what's the point of having the world's best package manager in Cargo if I can't just safely reuse people's code?
So rather than writing the unsafe code myself and having to learn more about this, like I know if I was like, if I would like have the time to like go and do this myself, sure.
But we all have tickets we want to work on, right?
So there's a crate that does it all for you. It's called pin project, or maybe pin project.
I don't know if project is like a verb or a noun there.
Maybe someone can clarify with detone sometime, but he's a busy guy. I don't want to bug him with my questions.
Long story short, it's a crate that gives you a macro, and this macro will automatically generate code that'll do all the projection for you.
So even though you have a pinned reference, you can still use all the fields, and it'll do it in a way that's really super safe.
Let's take a look.
So this is what I ended up using when I was doing my self-referential future.
Really what happened is I asked in the Rust Discord about it, and Chefmaster, the kind of god emperor of answering new people's questions on Stack Overflow and Discord, linked me towards this really useful crate.
So on the left, we have the code that I started off with.
On the right, we have almost identical code. Is this big enough?
I'm just going to try to... We've reached a point where... Yeah, bigger.
Yeah. Better? Cool. So the really big difference, sorry about the shitty contrast, is that we've used this pin project annotation at the top here.
And remember I said when you project a field, you've got to choose, do you want a regular reference or a pinned reference?
So all of these fields here, by default, they're just going to have a regular reference.
If you really want a pinned reference, you can use the pin annotation here.
And so it's going to generate code to give you references to all these things.
Let's take a look at how you actually use it.
So in my poll method, the first thing I'm going to do is call this automatically generated project method.
It gets generated by pin project. I'm going to assign this projection to be called this.
Or it could just be called self projected.
But it's going to have all the same fields as my original struct, but just be projected out.
And now I can call this.future is going to be a pinned reference.
So I can call poll. And all the other things are just going to be regular references.
So I have this.start is going to be a mutable reference to an optional timestamp.
So I can just use it like normal. So yeah, when I first started doing this, I was just using pin project because I was told that's the solution.
I didn't really understand the problem it was solving.
But I hope that in walking through this, you now understand why things need to be pinned and what we can do about them.
I read a lot of stuff to try and wrap my head around this. I've always been a big believer in you can't really understand something until you can explain it to someone else.
When I was a TA in college, I really just stayed one step ahead, like one week ahead of the class.
But I think that's a totally valid approach to take.
So the code that I was writing, this is on Crates.io. You can go and take a look at it.
You can use it if you want to, you can just read the source code to understand how it works and how you can build something similar.
The docs for pin are really comprehensive.
Although I think I had some trouble reading them because they jump around a fair amount.
Sometimes we need to really be jumping between the page for pin and unpin and the pin module.
The pin docs don't mention async at all.
Async is a feature built on top of pin, kind of treats pin as a library.
So pin has no results for async if you search it. But the async book talks about pin a lot and that's where you can figure out, okay, why does async require pin?
Obligatory link to the Amos post about this. Amos is a Rust programmer and he writes really good in-depth comprehensive articles about how features work under the hood.
So, you know, if you really want to learn more about what is pin project doing?
How do you actually project fields? What does that mean? What codes are generating?
If you read this article, you'll have a really good idea of what concretely it's doing.
Yeah. And if you liked, no, the joke is ruined. If you like listening to me talk about Rust and you don't like my accent, so you want to read it instead in text form.
I do have a Twitter where I sometimes talk about Rust. I have a blog.
I'm trying to write more about Rust. I'm going to turn this talk into a blog in the next couple of days.
And if you really like talking to me about Rust, my coworkers get to talk to me about Rust every day.
My team is hiring right now.
We're hiring Rust people specifically. So please email me if you want to come work on writing Rust code with me sometime.
Yeah. Hopefully pin is less scary.
Maybe even you think it's good to have around now. And yeah. That's all I've really got to say.
Thank you. Love it. Thank you, Adam. That was deep and very enlightening.
Appreciate it. We do have a couple of viewer questions, which if you can stop the screen share.
And we'll also welcome Jane to the call, who made it.
Hi, Jane. Welcome. We'll move on to your talk shortly. A couple of questions and a comment.
So written in from a viewer. Not a question, but a thank you.
Hi, Manish, Joshua. Thank you for your intro docs links. Also for being humble about your months and months of work, says Peter K from Vancouver, Canada.
I'm going to open the floor on that one. I think the best way is always reading the book.
You go to doc.rustling.org. And there you go.
I think Chet Master has put a lot of time into that. If you want to read that, it's always an introduction.
Cool. And then I would add also joining a project and finding a mentor, because working with people is always speeding up your learning tremendously.
Yeah. I would also add if you want just really like, hey, I know how to program in some other language.
How do I start writing Rust? The same blog I linked before, Faster Than Lime, has a really good article called A Half Hour to Learn Rust.
If you just Google A Half Hour to Learn Rust, you'll find just a really quick like, boom, boom, boom, boom.
Here's the thing you know how to do in the other language.
Here's the Rust version. You reminded me there's another blog post called I am a Java or C++ programmer.
I want to learn Rust. And it's like all the difficulties you run into, things that are similar, things that are just slightly different.
It's a very excellent walkthrough. Jan, you're going to give a whole talk, I guess.
But maybe, is your talk going to be aimed at beginners or more sort of intermediate and advanced folks?
This talk is, I think, more aimed at intermediate to advanced.
I did do a talk. It was actually my very first talk was about getting involved in the Rust community.
And it's very much aimed at beginners.
And I gave that at a previous, like two years ago almost, at a previous Bay Area Rust meetup.
And I also gave it at Rust Colorado Gold Rust. So I can recommend, you know, looking that up on YouTube.
If you're interested in getting involved in like kind of how it worked for me, you know, it's basically just like, you know, find some projects to work on.
And then I met Maneesh. He got a mentor and got involved.
Cool. Thank you for that. A couple questions, actually, from Josh.
Josh, please. Oh, right. Right. So, Adam, when you were talking about self -referential structs, it reminded me of standard string in C++, actually.
The way GCC does standard string is it, like, has a pointer to itself so that I can do, like, stack string optimization.
And the reason I thought of it is because it's sort of similar to pin.
The way C++ solves this is with move constructors. So, in Rust, moves are controlled by the compiler.
You don't know whether or not things move in memory.
But in C++, you can actually run arbitrary code when things are moved.
So, it doesn't need pin. Instead of having pin, you, like, run that code to update the pointers.
And that actually helped me understand unpin when I thought about that.
Because unpin is not having that move constructor. It doesn't matter whether it's moved or not.
But if you do have that move constructor, it's the same as not implementing unpin.
You need to do something when it's moved. Also, just to piggyback on that, a friend of mine is giving a RustConf talk that takes the insight you just had and puts it backwards in that move constructors, the analog of move constructors in Rust is pin.
We can use pin to get move constructors for Rust.
But that's interesting. I'll have to see that talk. Yeah.
I think you had another one. Oh, no, that was that, Josh. Yeah, that was it. Yeah.
Adam, I loved your metaphor of passing the baton from the compiler to a library.
Yeah, that's the robot compiler telling you, okay, take this one. I'll be back in a sec.
You follow the rules this time. Don't do anything I wouldn't do. And then, once you're done with the unsafe code, you just pass it back on.
Yes. Very cool.
Okay. That's the end of the questions. I'm gonna bring up our agenda just quickly.
And then we'll be on to you, Jane. So, ah, slide again. Rustjobs .Cloudflare.com.
You've now got two options. You can email Adam or you can email Rustjobs.Cloudflare.com or just go to that careers page.
Rustjobs is actually just an alias to my email.
It's just my nickname from the office. It's about to be.
At the moment, it's an alias to my email, but it'll be more direct to just send it straight to you.
Add me to the list. Add me to the list, too. Good. Yes. Everyone, all are welcome.
We are taking live questions. We've had a few already. So, livestudio.Cloudflare.tv.
If you go to the Cloudflare.tv page, you can actually record a question as well, which is fun.
It'll be cool if somebody wants to do that.
I'm showing the wrong thing here, aren't I? So, we're gonna move on to the next talk of the night and the final talk of the night.
And then we'll have a bit of Q&A at the end, again, if we have some questions and time permitting.
This show was scheduled for two hours.
I don't think we'll make that. So, we'll finish a little early.
That's all good. So, we're gonna move to you, Jane. Just before, we talked a bit about GitHub handles through this.
I was saying I always wondered if Andre was logic or llogic, and we had confirmed it was logic.
And Manish, I'd always read yours as Manish Harth until I met you and realized that Manish Earth was probably more accurate.
Can we confirm it's Manish Earth? Yeah, it's Manish Earth. Now, I have to take away this picture of you by a warm hearth every time that I think of you.
But that's okay. My mind is... Oh, Manish Hearth is so much better than... Right?
Maybe you should rethink it, Manish. I, too, always thought of it as Manish Hearth until I realized it was obviously Manish Earth, rather than Earth's name.
This has been a thing for as long as I've been on the Internets.
I got your name wrong the first time we were in a call together because of your username.
I was like, okay, well, because of that username, it must be Manish.
I sometimes capitalize the E to avoid this, but I actually don't like how that looks.
And I'm like, this is against the Manish Earth branding guidelines, so I don't do it all the time.
I think you just need to embrace it and just build a huge hearth in your living room.
Yeah. Just keep all the little pangolins warm, you know?
Build the hearth for manises. And then, Jane, I think I'd seen...
You have a slight different one on GitHub and Twitter, right?
Is it Yar or Yazi? I wasn't sure. Yazi. Yeah. It's mostly because of having to pick a new display name late in the Internet cycle when all the good ones are gone.
And so you got to try and find what's the minimum characters you can add at the end to make it work.
I was able to get Yazi on GitHub, but I had to get Yazi with an underscore at the end on Twitter.
Okay. So Yazi is how we're pronouncing Yazi.
It's Yar. The C is also just to get the name. Good. This is good clarification.
I'm glad we're doing this. So over to you, Jane. Share away. One thing for folks who maybe aren't familiar, if you are open to it, give maybe even a little intro as to the structural changes that happened to actually lead to the sort of teams that you're talking about here.
Because probably a lot of folks aren't familiar with that.
Yes. That is essentially all that I'm going to be talking about.
All right. Awesome. So it's going to be 70% quick background of chartering and what we've done, and then a little bit of some of the content of the charter and encouragement for people to dig deeper.
But should I just get going on the talk?
Yeah. All right. So I'm going to be talking about the new Libs team structure and how to get involved.
And can everyone see is everything working correctly?
It's all like shared right now, I'm guessing. Looks good. Okay. So jumping right into it, the Libs team is now multiple teams, and we have a charter.
So for the last couple months, the Libs team has been working with the chartering working group, which is under the core team, as part of the 2021 roadmap, which is to, the core team's roadmap for this year was to create charters for all the teams.
And these charters are intended to basically just document how all the teams work, the roles and responsibilities of the members, how team membership works, and any sort of specific processes within the team, like where they hold meetings, where their calendar is, and just kind of make it easy to navigate.
Because right now, the way the Rust project is structured is kind of like free form.
Each team gets to pick what works for them.
But the end result of that is that it's kind of all different and random and very confusing.
And especially as like Rust involvement has been like growing, there's like been a lot of how the heck do I join a compiler meeting or something?
And not necessarily just a compiler group, but it's the first one that came to mind.
They're actually very well organized, I would say.
But trying to get all these teams documented is what we've been doing. And the Libs team was one of the first teams.
And in this effort, we ended up basically more documenting how things were actually working, but like nominally, there are new teams.
So the new structure is that we took the library team and renamed it to library API.
And then we made a new library team, which is taking over some of the responsibilities that were previously the responsibility library team, but that they hadn't been doing recently because of like lack of capacity.
And there's also a new library contributors team.
So get into the details of why.
I just kind of mentioned it a little bit early, but the main point and issue was kind of a lack of capacity and availability for like the last year or two.
The library team has not had like basically enough people to keep up with all the work that is nominally the responsibility.
And so they've been doing the work that was most important, which was reviewing the like RFCs and making sure FCPs move forward and like stable changes can land.
But a lot of the work kind of like the general maintenance work, like implementation details of the library and critical bug fixes have been handled by the compiler team for a little while now.
And so recently, thanks to the work of Ashley Mannix and more recently Mara Boss, the library team's capacity has grown substantially.
I also, you know, hope that I am part of the reason I've joined the library team in that time.
And so we have now, we have like started meeting regularly again.
We have Mara set up an agenda generator.
So we like automatically pull in all the issues that are tagged for attention every week and we review them and we are keeping up and catching up.
And like we've gone through our backlog. If you look at the agendas for the past few weeks for the libs team, it's like 20 regressions and then 15 and five and 10, like some of them were like three or four years old.
Now they're all like responded to and moved along.
And so that's, I guess, kind of the main thing I wanted to talk about for like what we've done.
We like, we worked with the, sorry, no, I missed the thing.
Let me go back. So we ended up working with the chartering working group and documenting kind of the changes that had happened that Mara and Ashley Maggs had done, where we now had these new team members that were doing this general maintenance.
And we had these older team members who were still really focused on the API and like we're very like experts on that, but didn't necessarily still have the time to do this additional maintenance work.
And so we ended up like making the old team, the API team, so they can focus on this element of the library.
And then we made the new team for tracking the like the general maintenance work.
And so moving forward. So I want to just go next into just a little bit of the content of the charter.
Probably, I think the question that is like most interesting, though, there's a lot more information in the charter.
I don't have enough time in this lightning talk to go over all of it.
But first question that I imagine is on everyone's mind is how do I make changes to the standard library?
If I have like an idea that I want to land, do I have to write an RFC?
What do I do can be really intimidating. And it really depends on the type of change.
But we've made some efforts to make this easier. And we've also documented it in the charter.
So if you don't get everything here, you can go and read it there.
But if you're just changing implementation details, just make the PR, tag it for the LIBS team, not the LIBS API team.
And we'll review it and merge it.
And that's like there's no fuss. If you are changing unstable APIs, like you want to add a new feature with a new unstable interface to the library.
Once again, we usually don't require an RFC, depending on how big the feature is.
If it's a big one, we'll ask for an RFC.
But you shouldn't be assuming that's the first step unless you think you need like feedback and design assistance to get going on it.
So like the recommendation is just create the PR, create a tracking issue to associate with the PR so that once the PR merges, we can then like continue discussion around the feature and the tracking issue.
And tag TLIBS API. And someone will review it, assuming there are no objections and one of the team members is happy with it.
It'll get merged. Then finally, if you need to make changes to the stable API, like there's a feature that you like that's been around for a while that you think should be stabilized, make the PR, associate it with its associated tracking issue.
There are some changes that don't have tracking issues, that can't have tracking issues.
If you add a new trait implementation for a stable trait, those are instantly stable.
There's no way to make that unstable. So those will go immediately through the FCP process.
But you tag it for TLIBS API. And then the API team will run an FCP.
They will all review it and vote on it. And then it'll go into the final comment period, assuming it's approved.
Now, if you have more questions, there is a lot more on the libstein repo and in the governance repo.
We have the agenda generator that Mara wrote that gives a very detailed written in Rust explanation of exactly how things get in our agenda.
So you can know exactly which labels to tag issues with if you want them to get discussed in our weekly meetings.
And our weekly meetings, I should probably, I'll put a link to the HackMD in the libstein repo if it's not already there.
But all of our notes and links to how to join those meetings are there and in the Zlib.
And that is all.
Thank you, Jane, for the lightning talk. Appreciate it. You can, I am sharing screen.
So looking, we don't have any other live questions. We have about three and a half minutes, and I'll take about a minute to finish up.
So any comments, questions to from Jane or from anyone?
Jane, you reminded me that I still need to write the charter for the Rustdoc team.
I have not gotten around to that in a while.
So thank you. My pleasure. Yeah, for once all the teams have charters, it's going to be great.
Like in my mind, because I'm not as close to it as you guys, but I think of sort of compiler, libs, docs, like what are the other big teams?
Because we've talked a bit about community today. And DevTools is a big one.
There's release, there's core as well. The infra team. Infra.
Is Clippy the DevTools team? It's a sub-team, I think. Yeah, the DevTools team is weird.
And like, it has a bunch of sub -teams. It's like a whole deep thing. DevTools is like a group.
Yeah, I don't know anyone who's on the DevTools. Like a consortium.
Right. Jane and I are on the DevTools. Or maybe Jane? I don't think, I think I'm like, yeah, currently alumni for Clippy.
Because it's just focusing on the library stuff and foundation.
Okay. Good. How's the foundation doing? Good. We just had a board meeting.
That's why I was late. So it went well. So we heard. Even though you gave me warning, Jane, I hadn't actually updated the agenda.
So I was having to explain why.
Oh, yes. But thank you for making it. Appreciate it. It's my pleasure.
Yeah, you're probably a bit fried after that. So I appreciate you made it.
Good morning of preparation for lots of stuff. It was good. It's been a good day, actually.
Not too fried at all. Cool. All right. Well, we have about one last thing, which is the community thing that hasn't been mentioned here is Rust by Example.
It's a little community ebook project website for giving like short examples of how to do something in Rust.
And you can also contribute to that if you're looking for something to contribute to.
I've written a couple of pages here and there, and it's really easy.
So take a look at it. Good tip. I can also plug something.
Yep. There's an Awesome Rust Mentors is a project that I run, which is just like a listing of Rustations who are like by their areas of interest and languages they speak and who are like willing to mentor anyone.
So if someone's like looking for like a contact within the community that can help kind of guide them, check out Awesome Rust Mentors.
Jane, it's such a well-known resource. I already mentioned it in my talk.
Yep, Andre plugged it. Okay, fine. Sorry. That's cool.
All right. I think we're about out of time. So thank you very much, especially to our presenters.
I know you've all taken time out of your busy days and middle of the nights and everything else.
So appreciate that a lot. Thanks, Manish, for sharing around the ability to host the Bay Area Rust Meetup.
Anyone who wants to give a talk, like email me.
There was a few extra folks who were keen to talk today, actually.
So I think we have enough for another meetup. And I'm also open to other time zones.
We can sort of share the love around. So email me there if you're interested.
And yeah, rustjobs.Cloudflare.com. Anyone who's looking to code Rust at Cloudflare or anything else, we are hiring.
Thank you everyone for listening.
Thanks to our presenters again. Have a great day, afternoon, evening.