Planet Mozilla
https://planet.mozilla.org/
Planet Mozilla - https://planet.mozilla.org/The Mozilla Blog: Dr. J. Nathan Matias on leading technology research for better digital rights
https://blog.mozilla.org/en/internet-culture/dr-j-nathan-matias-digital-rights-science-cornell-university/
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<p><em>At Mozilla, we know we can’t create a better future alone, that is why each year we will be highlighting the work of 25 digital leaders using technology to amplify voices, effect change, and build new technologies globally through our <a href="https://rise25.mozilla.org/?_gl=1*585km0*_ga*MTY1MDQ4MTg2NC4xNjk5NDc0NTE5*_ga_X4N05QV93S*MTcwNzE4MDk3Ny40NC4wLjE3MDcxODA5NzcuMC4wLjA." rel="noreferrer noopener" target="_blank">Rise 25 Awards.</a> These storytellers, innovators, activists, advocates. builders and artists are helping make the internet more diverse, ethical, responsible and inclusive.</em></p>
<p><em>This week, we chatted with winner Dr. J. Nathan Matias, a professor at Cornell University leading technology research to create change and impact digital rights. He leads the school’s Citizen and Technology Lab (CAT) and is the co-founder of the <a href="https://independenttechresearch.org/">Coalition for Independent Technology Research, </a>a nonprofit defending the right to ethically study the impact of tech on society. We talk with Matias about his start in citizen science, his work advocating for researchers’ rights and more.</em></p>
<p><strong>As a professor at Cornell, how would you gauge where students and Gen Z are at in terms of knowing the dangers of the internet?</strong></p>
<p>As a researcher, I am very aware that my students are one narrow slice of Americans. I teach communication and technology. I teach this 500 student class and I think the students I teach hear about people’s concerns, about technology, through media, through what they see online. And they’re really curious about what if that is true and what we can do about it. That’s one of the great joys of being a professor, that I can introduce students to what we know, thanks to research and to all the advocacy and journalism, and also to what we don’t know and encourage students to help create the answers for themselves, their communities and future generations.</p>
<p><strong>To kind of go a little bit even further, as a professor, what are the things that you try to instill with them, or what are core concepts that you think are really important for them to know and try to hammer down to them about the internet and the social impacts of all of these platforms?</strong></p>
<p>If I’m known for one thing, it’s the idea that knowledge and power about digital technologies shouldn’t be constrained to just within the walls of the universities and tech companies. Throughout my classes and throughout my work, I actively collaborate with and engage with the general public to understand what people’s fears are to collect evidence and to inform accountability. And so, my students had the opportunity to see how that works and participate in it themselves. And I think that’s especially important, because yeah, people come to a university to learn and grow and learn from what scholars have said before, but also, if we come out of our degrees without an appreciation for the deeply held knowledge that people have outside of universities, I think that’s a missed opportunity. </p>
<p><strong>Beyond the data you collect in your field, what other types of data collection out there creates change and inspires you to continue the work that you do?</strong></p>
<p>I’m often inspired by people who do environmental citizen science because many of them live in context. We all live in contexts where our lives and our health and our futures are shaped by systems and infrastructures that are invisible, and that we might not appear to have much power over, right? It could be air or water, or any number of other environmental issues. And it’s similar for our digital environments. I’m often inspired by people who do work for data collection and advocacy and science on the environment when thinking about what we could do for our digital worlds. Last summer, I spent a week with a friend traveling throughout the California Central Valley, talking to educators, activists, organizers and farmworkers and communities working to understand and use data to improve their physical environment. We spent a day with <a href="https://ccejn.org/author/cesar/">Cesar Aguirre</a> at the Central California Justice Network. You have neighborhoods in central California that are surrounded by oil wells and people are affected by the pollution that comes out of those wells — some of them have long been abandoned and are just leaking. And it’s hard to convince people sometimes that you’re experiencing a problem and to document the problem in a way that can get things to change. Cesar talked about ways that people used air sensors and told their stories and created media and worked in their local council and at a state level to document the health impacts of these oil wells and actually get laws changed at the state level to improve safety across the state. Whenever I encounter a story like that, whether it’s people in Central California or folks documenting oil spills in Louisiana or people just around the corner from Cornell — indigenous groups advocating for safe water and water rights in Onondaga Lake — I’m inspired by the work that people have to do and do to make their concerns and experiences legible to powerful institutions to create change. Sometimes it’s through the courts, sometimes it’s through basic science that finds new solutions. Sometimes it’s mutual aid, and often at the heart of these efforts, is some creative work to collect and share data that makes a difference.</p>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" class="wp-image-74412" height="1024" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2024/03/Mozilla_rise25_Dr.J-Nathan-Matias_2-683x1024.jpg" width="683" /><figcaption class="wp-element-caption">Dr.J Nathan Matias at Mozilla’s Rise25 award ceremony in October 2023.</figcaption></figure></div>
<p><strong>When it pertains to citizen science and the work that you do, what do you think is the biggest challenge you and other researchers face? And by that I mean, is it kind of the inaction of tech companies and a lot of these institutions? Or is it maybe just the very cold online climate of the world today?</strong></p>
<p>It’s always hard to point to one. I think the largest one is just that we have a lot more work to do to help people realize that they can participate in documenting problems and imagining solutions. We’re so used to the idea that tech companies will take care of things for us, that when things go wrong, we might complain, but we don’t necessarily know how to organize or what to do next. And I think there’s a lot that we as people who are involved in these issues and more involved in them can do to make people aware and create pathways — and I know Mozilla has done a lot of work around awareness raising. Beyond that, we’ve kind of reached a point where I wish companies were indifferent, but the reality is that they’re actively working to hinder independent research and accountability. If you talk to anyone who’s behind the <a href="https://independenttechresearch.org/">Coalition for Independent Tech Research,</a> I think we would all say we kind of wish it we didn’t have to create it, because spending years building a network to support and defend researchers when they come under attack by governments or tech companies for accountability and transparency work for actually trying to solve problems, like, that’s not how you prefer to spend your time. But, I think that on the whole, the more people realize that we can do something, and that our perspective and experience matters, and that it can be part of the solution, the better off we are with our ability to document issues and imagine a better future. And as a result, when it involves organizing in the face of opposition, the more people we’ll have on that journey</p>
<p><strong>Just looking at this year in general with so much going on, what do you think is the biggest challenge that we face this year and in the world? How do we combat it?</strong></p>
<p>Here’s the one I’ve been thinking about. Wherever you live, we don’t live in a world where a person who has experienced a very real harm from a digital technology — whether it’s social media or some kind of AI system — can record that information and seek some kind of redress, or even know who to turn to, to address or fix the problem or harm. And we see this problem in so many levels, right? If someone’s worried about discrimination from an algorithm in hiring, who do you turn to? If you’re worried about the performance of your self-driving car, or you have a concern about mental health and social media this year? We haven’t had those cases in court yet. We’re seeing some efforts by governments to create standards and we’re seeing new laws proposed. But it’s still not possible, right? If you get a jar of food from the supermarket that has harmful bacteria, we kind of know what to do. There’s a way you can report it, and that problem can be solved for lots of people. But that doesn’t yet exist in these spaces. My hope for 2024 is that on whatever issue people are worried about or focused on, we’ll be able to make some progress towards knowing how to create those pathways. Whether it’s going to be work so that courts know how to make sense of evidence about digital technologies —and I think they’re going to be some big debates there — whether it’s going to involve these standards conversations that are happening in Europe and the U.S., around how to report AI incidents and how to determine whether an AI system is safe or not, or safe for certain purposes and any number of other issues. Will that happen and be solved this year? No, it’s a longer term effort. But how could we possibly say that we have a tech ecosystem that respects people’s rights and treats them well and is safe if we don’t even have basic ways for people to be heard when things go wrong, whether it’s by courts or companies, or elsewhere. And so I think that’s the big question that I’m thinking about both in our citizen science work and our broader policy work at Cat Lab.</p>
<p><strong>There’s also a bigger problem that so many of these apps and platforms are very much dependent upon us having to doing something compared to them. </strong></p>
<p>Absolutely. I think a lot of people have lost trust in companies to do things about those reports. Because companies have a history of ignoring them. In fact, my very first community participatory science project in this space, which started back in 2014, we pulled information from hundreds of women who faced online harassment. And we looked at the kinds of things they experienced. And then whether Twitter back then was responding to people’s reports. It revealed a bunch of systemic problems and how the company has handled it. I think we’ve reached the point where there’s some value in that reporting, and sometimes for good and sometimes those things are exploited for censorship purposes as well — people report things they disagree with to try to get it taken down. But even more deeply, those reports don’t get at the deeper systemic issues. They don’t address how to prevent problems in the first place, or how to create or how to change the underlying logics of those platforms, or how to incentivize companies differently, so that they don’t create the conditions for those problems in the first place. I think we’re all looking for what are the right entities? Some currently exist, some we’re going to have to create that will be able to take on what people experience and actually create change that matters.</p>
<p><strong>We started Rise25 to celebrate Mozilla’s 25th anniversary, what do you hope people are celebrating in the next 25 years?</strong></p>
<p>I love that question because my first true encounter with Mozilla would have been in 2012 at the Mozilla festival, and I was so inspired to be surrounded by a room of people who cared about making the Internet and our digital worlds better for people. And it was such a powerful statement that Mozilla convened people. Other tech institutions have these big events where the CEO stands on a stage and tells everyone why what they’re doing is revolutionary. And Mozilla did something radically different, which was to create a community and a space for people to envision the future together. I don’t know what the tech innovations or questions are going to be 25 years from now — there will probably be some enduring ones about access and equity and inclusion and safety for whatever the technologies are. My hope is that 25 years from now, Mozilla will continue to be an organization and a movement that listens and amplifies and supports a broad and diverse community to envision that together. It’s one of the things that makes Mozilla so special, and I think is one of the things that makes it so powerful.</p>
<p><strong>What is one action you think that everybody can take to make the world and their lives online better?</strong></p>
<p>I think the action to believe yourself when you notice something unusual, or have a question. And then to find other people who can corroborate and build a collective picture. Whether it’s by participating in the study at Cat Lab or something else. I have a respiratory disability, and it’s so easy to doubt your own experience and so hard to convince other people sometimes that what you’re experiencing is real. And so I think the biggest step we can do is to believe ourselves and to like, believe others when they talk about things they’ve experienced and are worried about but use that experience as the beginning of something larger, because it can be so powerful, and make such a huge difference when people believe in each other and take each other seriously.</p>
<p><strong>What gives you hope about the future of our world?</strong></p>
<p>So many things. I think every time I meet someone who is making things work under whatever circumstances they have — unsurprising as someone who does citizen and community science. I think about our conversations with Jasmine Walker, who is a community organizer who organizes these large spaces for Black communities online and has been doing it for ages and across many versions of technology and eras of time. And just to see the care and commitment that people have to their communities and families as it relates to technology — it could be our collaborators who are investigating hiring algorithms or communities we’ve talked to. We did a study that involved understanding the impact of smartphone design on people’s time use, and we met a bunch of people who are colorblind and advocates for accessibility. In each of those cases, there are people who care deeply about those around them and so much that they’re willing to do science to make a difference. I’m always inspired when we talk, and we find ways to support the work that they’re doing by creating evidence together that could make a difference. As scientists and researchers, we are sometimes along for the ride for just part of the journey. And so I’m always inspired when I see the commitment and dedication people have for a better world.</p>
<a class="ft-c-inline-cta" href="https://www.mozilla.org/en-US/firefox/new?utm_medium=mozilla-websites&utm_source=blog.mozilla.org&utm_content=inline-cta">
<div class="ft-c-inline-cta__media">
<img alt="" class="attachment-1x1 size-1x1" height="512" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2020/12/Fx-Browser-icon-fullColor-512-512x512.png" width="512" /> </div>
<div class="ft-c-inline-cta__content">
<h3>Get Firefox</h3> <span>Get the browser that protects what’s important</span> </div>
</a>
<p>The post <a href="https://blog.mozilla.org/en/internet-culture/dr-j-nathan-matias-digital-rights-science-cornell-university/">Dr. J. Nathan Matias on leading technology research for better digital rights</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-03-18T14:00:00+00:00Aron YohannesThe Mozilla Blog: Introducing Didthis: A New App For Hobbyists
https://blog.mozilla.org/en/internet-culture/introducing-didthis-a-new-app-for-hobbyists/
<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img alt="Logo for didthis - a hand snapping over a yellow background " class="wp-image-74487" height="510" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2024/03/Didthis-Logo.png" style="width: 245px; height: auto;" width="417" /></figure></div>
<p>Everyone has a hobby. More generally, everyone has things they’re interested in or passionate about. And pursuing those interests is one of the big reasons that we use the Web. The online world is a great place to connect with our fellow hobbyists and enthusiasts, to learn from them, and to share our own knowledge and accomplishments.</p>
<p>But so much of this happens today in online spaces where things can quickly turn sour. Big social media platforms increasingly expose us to toxic behavior. Interests groups and forums can be unwelcoming or intimidating to newcomers. These bad experiences are driving more and more people off of the open Web and into the protected enclaves of the so-called “<a href="https://maggieappleton.com/cozy-web">cozy web</a>.” Additionally, social media distractions and the pressure to keep up with posting can more often stall your progress rather than accelerating it.</p>
<p>Over the past year we’ve been actively exploring the idea of <a href="https://links.email.mozilla.org/els/v2/KAWzCy~4~6QY/SmxpcWVTSUcxK0pUZ0RnbWlqSlhtdDZqTlRCWGxCNDBYVXc4VG5SK3JCSHlLYXQ2SGUyeVIvS05sK3NOMjFwclZhdCtnaEk5OHBSc1JUQmU3UThHczB3ZWZFNi9qNk5WUms4cGp6OURmSmM9S0/">healthy alternatives to today’s social media</a>. Today we’re sharing our latest experiment on the topic.</p>
<p><a href="https://didthis.app/?utm_medium=mozilla-websites&utm_source=blog.mozilla.org&utm_campaign=didthis_ios_launch&utm_content=distilled-na"><strong>Didthis</strong></a><strong>, a Mozilla innovation project, is a new app for anyone with a project-oriented hobby or personal interest.</strong> Whether you’re learning to knit a sweater, crafting a side table, or practicing a new recipe, Didthis makes it easy to keep track of your passion projects, capturing photos, links, and notes along the way and assembling your updates into a timeline that tells the story of your project. It’s a personal record of your progress, an acknowledgement of what you learned from your setbacks, and a celebration of your growth as a hobbyist. </p>
<figure class="wp-block-image size-large"><img alt="" class="wp-image-74477" height="520" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2024/03/Didthis-Tryptich-Marketing-asset-1-1024x520.png" width="1024" /></figure>
<p>Didthis isn’t really “social media,” at least not yet. Didthis is about being useful to <em>you</em> as you pursue your personal interests. We’re not following the typical social media playbook, here, and that’s intentional. <strong>Everything you post on Didthis is private by default.</strong> If you want, you can choose to share a link to your project with anyone you want: friends, family, or fellow hobbyists on social media or the “cozy web.” If people like Didthis, we’ll add social and community functionality over time, but our focus will always be on healthy interactions over virality.</p>
<p>For now, we’ve set up our own Discord server where Didthis users can connect with us to share feedback. We’ve also got a dedicated “show and tell” channel where Didthis users can optionally share their project updates with fellow hobbyists in our small but growing community. </p>
<p>You can try Didthis on the Web by visiting <a href="https://didthis.app/?utm_medium=mozilla-websites&utm_source=blog.mozilla.org&utm_campaign=didthis_ios_launch&utm_content=distilled-na">https://didthis.app</a>. Our Web app works on both desktop and mobile devices. We also have an early iOS app that is available in the App Store for US and Canada (with Android to follow).</p>
<p>As this is still an experiment, we are eager for you to share your feedback at any time in the Didthis Discord channel. If you prefer to share more privately, you can email our entire team directly at didthis@mozilla.com.</p>
<p>The post <a href="https://blog.mozilla.org/en/internet-culture/introducing-didthis-a-new-app-for-hobbyists/">Introducing Didthis: A New App For Hobbyists</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-03-15T15:00:00+00:00Rebecca SmithThe Mozilla Blog: Larissa May reflects on empowering the next generation’s relationship with technology
https://blog.mozilla.org/en/internet-culture/larissa-may-rise25-social-media-technology-mozilla/
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<p><em>At Mozilla, we know we can’t create a better future alone, that is why each year we will be highlighting the work of 25 digital leaders using technology to amplify voices, effect change, and build new technologies globally through our <a href="https://rise25.mozilla.org/?_gl=1*585km0*_ga*MTY1MDQ4MTg2NC4xNjk5NDc0NTE5*_ga_X4N05QV93S*MTcwNzE4MDk3Ny40NC4wLjE3MDcxODA5NzcuMC4wLjA." rel="noreferrer noopener" target="_blank">Rise 25 Awards.</a> These storytellers, innovators, activists, advocates, builders and artists are helping make the internet more diverse, ethical, responsible and inclusive.</em></p>
<p><em>This week, we chatted with activist Larissa May, the founder of <a href="https://www.halfthestoryproject.com/our-team">#HalfTheStory, </a>a nonprofit dedicated to empowering the next generation’s relationship with technology. With talked with May about the role technology played in her mental health, how #HalfTheStory evolved from a project in her college dorm room to what it is today, and her work in policy advocating for tech companies to build solutions to help youth thrive.</em></p>
<p><strong>You know firsthand how toxic social media can be for kids. It has changed a lot in recent years, for the good and the bad. What do you think is the biggest danger kids face in 2024, and what can we do to combat it?<br /></strong><br />The average American teenager will spend approximately 30 years of their life behind screens. The greatest danger children, and indeed all of us, face lies in the uncertainties surrounding social media and its technologies. Technology evolves rapidly, outpacing both human understanding and legislative frameworks.</p>
<p>In 2024, we are witnessing the emergence of AI, with its potential for positive innovation, while also getting glimpses of its perilous side, whose full extent eludes us. Formerly innocuous interactions, such as a mere comment now hold the potential to morph into deceptive deep fakes, amplifying the challenges posed by social media. The velocity of AI’s advancement often outpaces our comprehension, leading to profound emotional ramifications, not only for our children but also for our societal fabric and economy. </p>
<p><strong>Watching the growth of the #HalfTheStory movement has certainly had a big impact on you. Has anything surprised you along the way that you weren’t expecting?</strong></p>
<p>What surprised me most along the way was realizing that most adults grapple with their relationship with technology just as much as children do. Now, as an adult who was once a child with a dream and an idea – which became #HalfTheStory – I’ve come to understand that while our focus may be on safeguarding children, we must also provide support to the adults who guide them. Demonstrating and modeling healthy relationships with technology is a crucial piece of this puzzle.</p>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" class="wp-image-74320" height="1024" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2024/02/Mozilla_rise25_Larissa-May-and-Guest_1-683x1024.jpg" width="683" /><figcaption class="wp-element-caption">Larissa May and her husband at Mozilla’s Rise25 award ceremony in October 2023.</figcaption></figure></div>
<p><strong>From the spotlight you’ve received in recent years – Good Morning America, your Ted Talk, TIME, Forbes, NBC, etc. — which experience made you stop and reflect on the magnitude of the work you do?</strong></p>
<p>There is no destination or pot of gold. In fact, the goalpost is always moving. There isn’t a day that I don’t wake up without wonder and awe for the journey and where it’s taken me. Sometimes I struggle to fully understand the magnitude and the impact of this nonprofit. There are moments every week that surprise me, whether it be the people who slide into my DMs, full circle moments, or people that I meet on the street who’ve known about #HalfTheStory or shared their own story with HTS many years ago.</p>
<p>Although the big accolades and TV segments are meaningful, I think the moments that are the most striking for me are the ones that happen behind closed doors, the messages that I receive, the one-off text messages with young people, and the aha moments that help me better understand the realities that young people are facing so that I can create a voice in every room where a decision is being made about them.</p>
<p><strong>What do you think is the biggest challenge we face in the world this year on and offline?</strong></p>
<p>Social media has perpetuated so many of the inequalities we see in the world. The online “realities” we see are not the whole story and make it more difficult for us to be able to see people from where they come from and to walk in their shoes. </p>
<p>During this year, especially when an election is happening in America, this is especially dangerous as social media often can keep us in our own ecosystems and eco chambers. It’s up to us to break through those so that we can understand multiple perspectives and have empathy for what other people are going through.</p>
<p>Social media feeds on emotions and combative behavior – that’s just how the algorithm works. We have to step outside of our algorithm and into our humanity.</p>
<p><strong>Where do you draw inspiration from to continue your work as an activist today?</strong></p>
<p>Teen work makes the dream work. I draw my inspiration from the future and the heartbeat of #HalfTheStory, our community. </p>
<p><strong>What is one action that you think everyone should take to make the world and our lives a little better?</strong></p>
<p>One simple action you can take is to put your phone down and engage in eye contact, genuinely seeking to understand someone’s story and background. Often, we become ensnared in our own egos, identities, and digital distractions, overlooking those right in front of us who may need our support the most.</p>
<p>To create more room for the present moment, I employ a few strategies. I set away messages for my text messages, switch my phone to grayscale mode, and strive to make my technology less addictive by hacking my algorithm. These practices help me liberate my mind and savor the moments between the hustle and bustle of daily life.</p>
<p><strong>We started Rise25 to celebrate Mozilla’s 25th anniversary, what do you hope people are celebrating in the next 25 years?</strong></p>
<p>In the next 25 years, I hope that humanity is celebrating humanity. I think for many years we’ve celebrated tech and innovation and as we’ve done that we lost touch with ourselves, our souls, and the things that make us human. I do believe that we will see a pendulum swing – we are even seeing it with some of our teens now.</p>
<p>Being human and accessing screen-free experiences really is a luxury, and connection that is not simulated is one of the most precious things that we have. Time is a non-renewable resource, so I hope we don’t spend the next 25 years behind our screens. What gives me hope for the future is our teens.</p>
<p><strong>What gives you hope about the future of our world?</strong></p>
<p>Our society loves to paint a story of darkness and digital sickness, but I get to witness the digital wellness revolution unfold every day before my eyes.</p>
<p>Our teens are paving the path forward. They are the heart and soul of #HalfTheStory and I’m the lucky leader that gets to sail alongside them into a brighter horizon. </p>
<p>The future is BRIGHT (with less blue light). </p>
<a class="ft-c-inline-cta" href="https://www.mozilla.org/en-US/firefox/new?utm_medium=mozilla-websites&utm_source=blog.mozilla.org&utm_content=inline-cta">
<div class="ft-c-inline-cta__media">
<img alt="" class="attachment-1x1 size-1x1" height="512" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2020/12/Fx-Browser-icon-fullColor-512-512x512.png" width="512" /> </div>
<div class="ft-c-inline-cta__content">
<h3>Get Firefox</h3> <span>Get the browser that protects what’s important</span> </div>
</a>
<p>The post <a href="https://blog.mozilla.org/en/internet-culture/larissa-may-rise25-social-media-technology-mozilla/">Larissa May reflects on empowering the next generation’s relationship with technology</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-03-15T15:00:00+00:00Aron YohannesFirefox Developer Experience: Firefox DevTools Newsletter — 123
https://fxdx.dev/firefox-devtools-newsletter-123/
<p id="block-660521a7-b7f1-4009-9ba0-e51d24c1c3bb"><em>Developer Tools help developers write and debug websites on Firefox. This newsletter gives an overview of the work we’ve done as part of the Firefox 123 Nightly release cycle.</em></p>
<p id="block-0cf4b3d9-690f-481f-8115-a35a2ee4f80d">Firefox being an open source project, we are grateful to get contributions from people outside of Mozilla. Many thanks to <a href="https://fxdx.dev/feed/aa1ronham@gmail.com">Aaron</a> who added a “Save as File” context menu entry in the Network panel so (mostly) all responses can be saved to disk (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1221964">#1221964</a>)</p>
<p id="block-f6fddf3c-3ebb-46d8-81e6-94a2caf64a22">Want to help? DevTools are written in HTML, CSS and JS so any web developer can contribute! Read <a href="https://firefox-source-docs.mozilla.org/devtools/getting-started/README.html">how to setup the work environment</a> and check <a href="https://codetribute.mozilla.org/projects/devtools">the list of mentored issues</a></p>
<h3>Debugger</h3>
<p>A <a href="https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/">source map</a> is a file that maps from a generated source, i.e. the actual Javascript source the browser runs, to the original source, which could be typescript, jsx, or even regular JS file that was compressed. This enables DevTools to display code to the developers in the way they wrote it.</p>
<p>It can happen that a referenced source map file can’t be retrieved by the Debugger, or that it’s invalid, and in such case, we’ll now show a warning message in the editor to indicate why we can only show the generated source (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1834725">#1834725</a>).</p>
<p></p>
<figure class="wp-block-image aligncenter size-large"><img alt="Firefox DevTools debugger with a file name xhr_bundle.js being open. At the end of the file, we can see that it references a sourcemap file. Below the editor, a warning notice is displayed, containing the following text: "Source Map Error: JSON.parse: unexpected non-whitespace character after JSON data at line 2 column 2 of the JSON data"" class="wp-image-252" height="445" src="https://fxdx.dev/files/2024/02/CleanShot-2024-02-28-at-10.49.49-600x445.png" width="600" /></figure>
<p>Still related to source map, a link to the original source is now displayed in the footer when selecting a location in a generated source (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1834729">#1834729</a>).</p>
<p>We some time fixing common issues that were affecting the Preview Popup, which is displayed when hovering variables (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873147">#1873147</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1872715">#1872715</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873149">#1873149</a>). It should now be more solid and reliable, but less us know if you’re still having problem with it!</p>
<p>Finally, we fixed a nasty bug that could crash the Debugger (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874382">#1874382</a>).</p>
<h3>Misc</h3>
<p>We vastly improved console performance when there is <strong>a lot</strong> of messages being displayed (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873066">#1873066</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874696">#1874696</a>) and fixed logging of cross-origin iframe’s <code>contentWindow</code> (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867726">#1867726</a>) and arrays in workers (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874695">#1874695</a>).</p>
<p>The Network panel timing markers for Service Worker interception are now displayed correctly (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1353798">#1353798</a>).</p>
<p>We fixed a couple regressions in the Inspector. The first one was preventing using double click edit attribute with URLs in the markup view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870214">#1870214</a>), and the second was adding extra line when copy/pasting rule from the Rules view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876220">#1876220</a>).</p>
<p class="has-text-align-center has-background-secondary-background-color has-background"><strong>Thank you for reading this and using our tools, see you next <s>month</s> week for a new round of updates <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" style="height: 1em;" /></strong></p>2024-03-15T14:10:34+00:00Nicolas ChevobbeMozilla Addons Blog: Manifest V3 & Manifest V2 (March 2024 update)
https://blog.mozilla.org/addons/2024/03/13/manifest-v3-manifest-v2-march-2024-update/
<p>Calling all extension developers! With Manifest V3 picking up steam again, we wanted to provide some visibility into our current plans as a lot has happened since we published our <a href="https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-firefox-recap-next-steps/" rel="noopener" target="_blank">last update</a>.</p>
<p>Back in 2022 we released our initial implementation of MV3, the latest version of the extensions platform, in Firefox. Since then, we have been hard at work collaborating with other browser vendors and community members in the W3C WebExtensions Community Group (<a href="https://www.w3.org/groups/cg/webextensions/" rel="noopener" target="_blank">WECG</a>). Our shared goals were to improve extension APIs while addressing cross browser compatibility. That collaboration has yielded some great results to date and we’re proud to say our participation has been instrumental in shaping and designing those APIs to ensure broader applicability across browsers.</p>
<p>We continue to support DOM-based background scripts in the form of Event pages, and the blocking webRequest feature, as explained in <a href="https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-firefox-recap-next-steps/" rel="noopener" target="_blank">our previous blog post</a>. Chrome’s version of MV3 requires service worker-based background scripts, which we do not support yet. However, an extension <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background#browser_support" rel="noopener" target="_blank">can specify both</a> and have it work in Chrome 121+ and Firefox 121+. Support for Event pages, along with support for blocking webRequest, is a divergence from Chrome that enables use cases that are not covered by Chrome’s MV3 implementation.</p>
<p>Well what’s happening with MV2 you ask? Great question – in case you missed it, <a href="https://developer.chrome.com/blog/resuming-the-transition-to-mv3" rel="noopener" target="_blank">Google announced</a> late last year their plans to resume <a href="https://developer.chrome.com/docs/extensions/develop/migrate/mv2-deprecation-timeline" rel="noopener" target="_blank">their MV2 deprecation schedule</a>. Firefox, however, has no plans to deprecate MV2 and will continue to support MV2 extensions for the foreseeable future. And even if we re-evaluate this decision at some point down the road, we anticipate providing a notice of at least 12 months for developers to adjust accordingly and not feel rushed.</p>
<p>As our plans solidify, future updates around our MV3 efforts will be shared via this blog. We are loosely targeting our next update after the conclusion of the upcoming <a href="https://github.com/w3c/webextensions/issues/525" rel="noopener" target="_blank">WECG meeting</a> at the Apple offices in San Diego. For more information on adopting MV3, please refer to our <a href="https://extensionworkshop.com/documentation/develop/manifest-v3-migration-guide/" rel="noopener" target="_blank">migration guide</a>. Another great resource worth checking out is the recent FOSDEM presentation a couple team members delivered, <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2412-firefox-android-and-cross-browser-webextensions-in-2024/" rel="noopener" target="_blank">Firefox, Android, and Cross-browser WebExtensions in 2024</a>.</p>
<p>If you have questions, concerns or feedback on Manifest V3 we would love to hear from you in the comments section below or if you prefer, drop us an <a href="mailto:mozilla-add-ons-community@mozilla.com">email</a>.</p>
<p>The post <a href="https://blog.mozilla.org/addons/2024/03/13/manifest-v3-manifest-v2-march-2024-update/">Manifest V3 & Manifest V2 (March 2024 update)</a> appeared first on <a href="https://blog.mozilla.org/addons">Mozilla Add-ons Community Blog</a>.</p>2024-03-13T22:40:34+00:00Edward SullivanThe Mozilla Blog: Creator Nyamekye Wilson is uplifting Black women in STEM and creating a talent pipeline for the next generation
https://blog.mozilla.org/en/internet-culture/nyamekye-wilson-black-sisters-in-stem-google/
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<p><em>At Mozilla, we know we can’t create a better future alone, that is why each year we will be highlighting the work of 25 digital leaders using technology to amplify voices, effect change, and build new technologies globally through our <a href="https://rise25.mozilla.org/?_gl=1*585km0*_ga*MTY1MDQ4MTg2NC4xNjk5NDc0NTE5*_ga_X4N05QV93S*MTcwNzE4MDk3Ny40NC4wLjE3MDcxODA5NzcuMC4wLjA." rel="noreferrer noopener" target="_blank">Rise 25 Awards.</a> These storytellers, innovators, activists, advocates. builders and artists are helping make the internet more diverse, ethical, responsible and inclusive.</em></p>
<p><em>This week, we chatted with Nyamekye Wilson, a creator that is the founder and CEO of <a href="https://www.blacksis.org/">Black Sisters in STEM,</a> a group building one of the largest talent pipelines of Black college women in STEM. Her passion for global STEM and bridging the gender gap gave birth to a six-figure tech company while she was working at Google. We talk with Nyamekye about the challenges she’s faced in her career, starting a Black nonprofit, where she draws inspiration from and more.</em></p>
<p><strong>OK, first off, where did the phrase “the Moses of STEM” originate from for you?</strong></p>
<p>It came to me at church, and it was something that I just knew and I just heard and my brain is like “the Moses of them.” And then it was something that I spoke over to the team like a fellow — like that is really perfect, that’s exactly who you are. </p>
<p>The historical figure of Moses, he was someone who led people out of activity. And so really with Black Sisters in STEM, it’s not just a workplace organization, it’s so much more than that. It is really that we are taking Black women out of a lot of the activity that they’ve learned over time from a very young age of things that we cannot be, things that we cannot do, places we cannot go. Who we cannot be. And so, when it comes to the Moses of STEM, it’s really about unearthing and bringing people out of a lot of bondage and most of that bondage is always in the mind. </p>
<p><strong>You mentioned a lot of the different experiences and labels you’ve dealt with in your career — racism, sexism, classism — that we face in schooling and in the workforce in general. Which issue would you say was the one that really ignited the fire for you and the work that you do right now the most?</strong></p>
<p>I would say it was really the concept of intersectionality. When I did leave my finance major in college, I went into sociology and women, gender and sexuality studies, that’s when I got introduced to Kimberlé Crenshaw and her concept of intersectionality. And that was the first time in life that I actually heard a philosophy that actually spoke to my experience. </p>
<p><strong>What are the biggest challenges that you’ve had to face starting a Black nonprofit that most people might not be aware of?</strong></p>
<p>We are not the ones in the world of philanthropy, typically, when it comes to running systems and running things at a large level. Even when you look at places like Africa or places like the Caribbean, or even Black American communities in the U.S., a lot of organizations aren’t run by us, aren’t founded by us in our community to support us. So that’s one thing, the funding structure and really understanding that some of the relationships are doing a lot of funding with the people that are running them. </p>
<p>Number two is that it can be very difficult to fight for something that you also share the identity of. This is something that we notice in the civil rights movement — it’s a lot of fatigue to fight for the rights of your people when you are also the people that are inclusive of those fights, right? It’s a constant mental war, I would say, because it’s like, I’m not just talking about Black women from afar, I am the Black woman who’s been through that. I am the Black woman who did not have the support. I am the Black woman who, you know, went through the question and anxiety trying to get to the place where I’m trying to get to my girl’s to. I am the Black woman who gained over 60 pounds trying to take my family out of poverty and be the first person in my family to have a six-figure career right out of college. That is a mental battle that you constantly have to do. And so you really have to have a lot of mental attitude. You really have to work with the best interactions and best relationships that maybe other populations more likely have — they don’t have to do half the work because if they came from a very wealthy area, they’re likely to have that and some people in those areas have a foundation, it’s very likely. And they likely have those people to be family friends or family connections — it makes it so much easier when you can just go to their house, or you can just call them and say, “hey, I have this idea.” That’s how money moves by relationship. Essentially, it always moves by relationship because money is a trust factor. And when you have the relationship, someone who has known you since you were five, and they’ve been friends with your mom and dad for 20 years, that trust factor is already there. Versus, a young Black girl coming to the phone with her story and her narrative and you’ve never met her in your life. You don’t know anything about her. You don’t know anything about the organization. Now, I have to do 10 times the work. And plead to you who I am, plead to you what we’re doing at Black Sisters to get that trust, compared to someone with less information because that’s someone who you’ve known your whole life. And that’s just human nature. But that human nature is now, again, back to the systems of racism. That effect of racism is now causing more work for me.</p>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" class="wp-image-74287" height="1024" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2024/02/Mozilla_rise25_Nyamekye-Wilson_1-683x1024.jpg" width="683" /><figcaption class="wp-element-caption">Nyamekye Wilson at Mozilla’s Rise25 award ceremony in October 2023.</figcaption></figure></div>
<p><strong>Where do you draw inspiration from in continuing the work that you do today? </strong></p>
<p>I would say what inspired me really is my faith. I’m a very faith-based person, very spiritual person, and my faith in Christ is what keeps me going. Because if not, it would be very hard to do this work. Number two of what keeps me going is knowing that where I come from had even less access, even less opportunity and seeing what they were able to create and what they were able to be so inspiring. </p>
<p>I’ve always loved learning about civilized movements, learning about things that MLK was a part of. All of these people — Sojourner Truth, Harriet Tubman, — when you read and watch, we just learn about the level of resilience and the level of fortitude and the level to feel and see a better world completely at the expense of themselves. As much as there is a need for a better world, the world I’m seeing is way better than the world they had. And if they could affect that global change, I can, too. </p>
<p>And then I would also say, in alignment with that, my own mother. She is a perfect example. Single mother. She really held the weight of my entire family on her shoulders. And she never gave up. One of the most consistent, one of the most brilliant, one of the most hardworking — if not the most hardworking — brilliant person I know. Through all that she’s given, that I already have, it inspires me to do more.</p>
<p><strong>What is one action that everybody can take to make our world a little bit better?</strong></p>
<p>I would say take the time to learn. After going through sociology, women, gender and sexuality studies, I just realized that was a wealth of knowledge that everyone in this world should have. Unfortunately, that’s not how most of the education systems are. … Being a viable part of the society, it is really important to understand what has to be reading and what has to do with where the society is right now. I don’t think a lot of people do enough research.</p>
<p> And then, number two, after you do that research, have some sort of goals around supporting people who are putting their efforts in changing that society and changing that world. And be very intentional about it. Look at who is running those companies. Look at the impact of their companies. Look at who they’re supporting — and everyone at every level. </p>
<p>Whether you give your time, whether you give your money, whether you give whatever, I don’t think there’s ever enough people to give. You can even give your amplification, right? Amplifying something on social media. Amplifying and making sure you forward a newsletter. Making sure you promise on something. You don’t understand what that could potentially do, especially if you have a certain network. You have a certain network and if you’re on LinkedIn and you have the time to comment on a Black Sisters post, you are doing a lot for us. Because now your entire network is going to be seeing that consistently. And that is something that’s completely free and didn’t take many minutes to do. </p>
<p>And then also, if you have the capacity, make sure you’re also giving on a yearly basis as much as you can budget for. </p>
<p><strong>We started Rise 25 to celebrate Mozilla’s 25th anniversary. What do you hope that people are celebrating in the next 25 years?</strong></p>
<p>I hope people are celebrating a society that provides opportunities based off of potential and not race, color, gender, etc. I hope that potential means opportunities and that people are celebrating the fact that they are in a city, space, etc. that allows for potential and opportunities to always be on equal footing. And not be based off of things that you cannot control. </p>
<p><strong>What gives you hope for the future of our world?</strong></p>
<p>What gives me hope is hope (laughs). What gives me hope is the ability to know that human beings have and will always have the luxury of bringing stories of seeing things progress, of moving and changing the world. And it’s going to be something that has been done throughout. So many people have different stories. It’s everything. And so, I really believe that if there’s a force that keeps me going, I think it’s a way that people can hold onto that.</p>
<a class="ft-c-inline-cta" href="https://vpn.mozilla.org/">
<div class="ft-c-inline-cta__media">
<img alt="" class="attachment-1x1 size-1x1" height="800" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2020/08/moz_web_vpn_hero_05_2x-800x800.png" width="800" /> </div>
<div class="ft-c-inline-cta__content">
<h3>Device-level encryption from a name you can trust</h3> <span>Try Mozilla VPN</span> </div>
</a>
<p>The post <a href="https://blog.mozilla.org/en/internet-culture/nyamekye-wilson-black-sisters-in-stem-google/">Creator Nyamekye Wilson is uplifting Black women in STEM and creating a talent pipeline for the next generation</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-03-13T18:39:41+00:00Aron YohannesThis Week In Rust: This Week in Rust 538
https://this-week-in-rust.org/blog/2024/03/13/this-week-in-rust-538/
<p>Hello and welcome to another issue of <em>This Week in Rust</em>!
<a href="https://www.rust-lang.org/">Rust</a> is a programming language empowering everyone to build reliable and efficient software.
This is a weekly summary of its progress and community.
Want something mentioned? Tag us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> on Twitter or <a href="https://mastodon.social/@thisweekinrust">@ThisWeekinRust</a> on mastodon.social, or <a href="https://github.com/rust-lang/this-week-in-rust">send us a pull request</a>.
Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p>
<p><em>This Week in Rust</em> is openly developed <a href="https://github.com/rust-lang/this-week-in-rust">on GitHub</a> and archives can be viewed at <a href="https://this-week-in-rust.org/">this-week-in-rust.org</a>.
If you find any errors in this week's issue, <a href="https://github.com/rust-lang/this-week-in-rust/pulls">please submit a PR</a>.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-rust-community">Updates from Rust Community</a></h4>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#official">Official</a></h5>
<ul>
<li><a href="https://blog.rust-lang.org/2024/03/11/Rustup-1.27.0.html">Announcing Rustup 1.27.0</a></li>
<li><a href="https://blog.rust-lang.org/2024/03/11/crates-io-download-changes.html">crates.io: Download changes</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#newsletters">Newsletters</a></h5>
<ul>
<li><a href="https://rust-osdev.com/this-month/2024-02/">This Month in Rust OSDev: February 2024</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#projecttooling-updates">Project/Tooling Updates</a></h5>
<ul>
<li><a href="https://bevyengine.org/news/bevy-foundation/">Bevy Foundation</a></li>
<li><a href="https://github.com/ad-si/Rust-Flashcards">Rust Flashcards - 557 cards to learn Rust from first principles</a></li>
<li><a href="https://users.rust-lang.org/t/lib-rs-website-improvements/108218">Lib.rs website improvements</a></li>
<li><a href="https://www.memorysafety.org/blog/reducing-dependencies-in-sudo/">Sudo-rs dependencies: when less is better</a></li>
<li><a href="https://rust-analyzer.github.io/thisweek/2024/03/11/changelog-224.html">rust-analyzer changelog #224</a></li>
<li><a href="https://www.lpalmieri.com/posts/biscotti-http-cookies-in-rust/">biscotti, a new crate for HTTP cookies</a></li>
<li><a href="https://boajs.dev/blog/2024/03/07/boa-release-18">Boa release v0.18</a></li>
<li><a href="https://relm4.org/blog/posts/announcing_relm4_v0.7/">Announcing Relm4 0.7 and 0.8</a></li>
<li><a href="https://blog.meilisearch.com/meilisearch-1-7/">Meilisearch 1.7 — New OpenAI models & GPU support for Hugging Face embeddings</a></li>
<li><a href="https://kobzol.github.io/rust/cargo/2024/03/10/rust-cargo-wizard.html">Cargo wizard: automate Cargo project configuration</a></li>
<li><a href="https://greptime.com/blogs/2024-03-07-greptimedb-v0.7">GreptimeDB v0.7 is ready for cloud-native monitoring</a></li>
<li>[video] <a href="https://www.youtube.com/watch?list=PL85XCvVPmGQipj690WrVgsnU4K4x7qFGy&v=N7GMHcX-WdA">Project Syn - Simon Gerber - Rust Zürisee March 2024</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#observationsthoughts">Observations/Thoughts</a></h5>
<ul>
<li><a href="https://blog.sdf.com/p/fast-development-in-rust-part-one">Fast Development In Rust, Part One</a></li>
<li><a href="https://ia0.github.io/unsafe-mental-model/">Mental model for unsafe (complete rewrite)</a></li>
<li><a href="https://ochagavia.nl/blog/10-years-in-open-source/">10 years in Open Source</a></li>
<li>[audio] <a href="https://corrode.dev/podcast/s01e07-season-finale/">Season Finale - Rust in Production Podcast</a></li>
<li>[video] <a href="https://www.youtube.com/watch?v=VArNQtYBC6Y">SemVer in Rust: Breakage, Tooling, and Edge Cases</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-walkthroughs">Rust Walkthroughs</a></h5>
<ul>
<li><a href="https://www.infoq.com/articles/rust-procedural-macros-replace-panic/">How to Use Rust Procedural Macros to Replace Panic with syn’s Fold</a></li>
<li><a href="https://blog.jetbrains.com/rust/2024/03/12/rust-iterators-beyond-the-basics-part-i-building-blocks/">Rust Iterators Beyond the Basics - part 1</a></li>
<li><a href="https://rust.code-maven.com/multi-crate-project">Rust Multi-crate project in a monorepo</a></li>
<li><a href="https://www.shuttle.rs/blog/2024/03/07/stripe-payments-rust">Using Stripe Payments with Rust</a></li>
<li><a href="https://blog.weiznich.de/blog/async-transaction-problem/">Problems around modelling an asynchronous API for database transaction in Rust</a></li>
<li><a href="https://apollolabsblog.hashnode.dev/embedded-rust-bluetooth-on-esp-ble-scanner">Embedded Rust Bluetooth on ESP: BLE Scanner</a></li>
<li>[video] <a href="https://www.youtube.com/watch?v=u0VotuGzD_w">Implementing (parts of) git from scratch in Rust</a></li>
<li>[video] <a href="https://www.youtube.com/watch?v=-1VGwmFKKf8">The Billion Rows Challenge in Rust - an intro to Rust for data engineering</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#miscellaneous">Miscellaneous</a></h5>
<ul>
<li><a href="https://bastienvigneron.medium.com/rust-impact-on-engineering-management-59647e5d0265">Rust impact on engineering management</a></li>
<li><a href="https://surrealdb.com/blog/from-medical-doctor-to-rust-developer--interview-with-our-new-senior-clinical-research-fellow">From medical doctor to rust developer</a></li>
<li><a href="https://filtra.io/rust-feb-24">February 2024 Rust Jobs Report</a></li>
</ul>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#crate-of-the-week">Crate of the Week</a></h4>
<p>This week's crate is <a href="https://github.com/LukeMathWalker/biscotti">biscotti</a>, an opinionated library to deal with HTTP cookies on the server side.</p>
<p>We saw a lamentable lack of suggestions this week. Nevertheless, llogiq is pleased with his selection.</p>
<p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Please submit your suggestions and votes for next week</a>!</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-testing"></a><a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">Call for Testing</a></h4>
<p>An important step for RFC implementation is for people to experiment with the
implementation and give feedback, especially before stabilization. The following
RFCs would benefit from user testing before moving forward:</p>
<ul>
<li><a href="https://github.com/rust-lang/rust/issues/119612">Tracking Issue for <code>min_exhaustive_patterns</code></a><ul>
<li><a href="https://github.com/rust-lang/rust/issues/119612#issuecomment-1967092452">Testing Steps</a></li>
</ul>
</li>
</ul>
<p>If you are a feature implementer and would like your RFC to appear on the above list, add the new <code>call-for-testing</code>
label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the feature
need testing.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-participation-projects-and-speakers">Call for Participation; projects and speakers</a></h4>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-projects">CFP - Projects</a></h5>
<p>Always wanted to contribute to open-source projects but did not know where to start?
Every week we highlight some tasks from the Rust community for you to pick and get started!</p>
<p>Some of these tasks may also have mentors available, visit the task page for more information.</p>
<ul>
<li><a href="https://github.com/juspay/hyperswitch/issues/4054">Hyperswitch - [REFACTOR]: Remove Default Case Handling - Bambora</a></li>
<li><a href="https://github.com/juspay/hyperswitch/issues/4055">Hyperswitch - [REFACTOR]: Remove Default Case Handling - Mollie</a></li>
<li><a href="https://github.com/juspay/hyperswitch/issues/4058">Hyperswitch - [REFACTOR]: Remove Default Case Handling - Braintree</a></li>
<li><a href="https://github.com/GreptimeTeam/greptimedb/issues/3492">GreptimeDB - Painless integrating with Grafana via Prometheus plugin</a></li>
<li><a href="https://github.com/GreptimeTeam/greptimedb/issues/3435">GreptimeDB - Add strict mode to validate protocol strings</a></li>
<li><a href="https://github.com/infinyon/fluvio/issues/3765">Fluvio - fvm switch fails on some systems with running local cluster</a></li>
<li><a href="https://github.com/infinyon/fluvio/issues/3810">Fluvio - Add new command fluvio cluster resume</a></li>
<li><a href="https://github.com/quinn-rs/quinn/issues/1778">quinn - Add CI for mobile platforms (iOS & Android)</a></li>
</ul>
<p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://users.rust-lang.org/t/twir-call-for-participation/4821">here</a>.</p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-speakers">CFP - Speakers</a></h5>
<p>Are you a new or experienced speaker looking for a place to share something cool? This section highlights events that are being planned and are accepting submissions to join their event as a speaker. They are ordered below by when the CFP closes.</p>
<ul>
<li><a href="https://rustfest.ch/cfp/">RustFest Zürich 2024</a> | Closes 2024-03-31 | Zürich, Switzerland | Event date: 2024-06-19 - 2024-06-24</li>
<li><a href="https://pretalx.com/oxidize-berlin-2024/cfp">Oxidize 2024</a> | Closes 2024-03-24 | Berlin, Germany | Event date: 2024-05-28 - 2024-05-30</li>
<li><a href="https://foundation.rust-lang.org/news/the-rustconf-2024-call-for-talk-proposals-is-open/">RustConf 2024</a> | Closes 2024-04-25 | Montreal, Canada | Event date: 2024-09-10</li>
<li><a href="https://www.papercall.io/eurorust-2024">EuroRust 2024</a>| Closes 2024-06-03 | Vienna, Austria & online | Event on 2024-10-10</li>
<li><a href="https://scientificcomputing.rs/">Scientific Computing in Rust 2024</a>| Closes 2024-06-14 | online | Event date: 2024-07-17 - 2024-07-19</li>
</ul>
<p>If you are an event organizer hoping to expand the reach of your event, please submit a link to the submission website through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a>.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-the-rust-project">Updates from the Rust Project</a></h4>
<p>506 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2024-03-05..2024-03-12">merged in the last week</a></p>
<ul>
<li><a href="https://github.com/rust-lang/rust/pull/121832">add new Tier-3 target: <code>loongarch64-unknown-linux-musl</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119199">add arm64ec-pc-windows-msvc target</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/117458">LLVM Bitcode Linker: A self contained linker for nvptx and other targets</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122004">AST validation: Improve handling of inherent impls nested within functions and anon consts</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121894"><code>const_eval_select</code>: make it safe but be careful with what we expose on stable for now</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121975"><code>hir_analysis</code>: enums return <code>None</code> in <code>find_field</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121905">add a <code>description</code> field to target definitions</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121976">add an option to have an external download/bootstrap cache</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119365">add asm goto support to <code>asm!</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122305">add metadata to targets</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122066">add proper cfgs for <code>struct</code> HirIdValidator used only with debug-assert</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122157">add the new description field to <code>Target::to_json,</code> and add descriptions for some MSVC targets</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/116791">allow codegen backends to opt-out of parallel codegen</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122315">allow multiple <code>impl Into<{D,Subd}iagMessage></code> parameters in a function</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/116793">allow targets to override default codegen backend</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122043">apply <code>EarlyBinder</code> only to <code>TraitRef</code> in <code>ImplTraitHeader</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122010">avoid invoking the <code>intrinsic</code> query for DefKinds other than <code>Fn</code> or <code>AssocFn</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121190">avoid overlapping privacy suggestion for single nested imports</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122014">change some attributes to <code>only_local</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122078">check that return type is WF in typeck</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121752">detect unused <code>struct</code> impls pub trait</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122293">diagnostics: do not suggest using <code>#[unix_sigpipe]</code> without a value</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121662">distinguish between library and lang UB in <code>assert_unsafe_precondition</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122026">do not try to format removed files</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122172">don't ICE if we collect no RPITITs unless there are no unification errors</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122173">don't ICE in CTFE if raw/fn-ptr types differ</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122137">don't pass a break scope to <code>Builder::break_for_else</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122123">don't require specifying unrelated assoc types when trait alias is in <code>dyn</code> type</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/113525">dynamically size sigaltstk in std</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121301">errors: share <code>SilentEmitter</code> between rustc and rustfmt</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122181">fix crash in internal late lint checking</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122271">fix legacy numeric constant diag items</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122038">fix linting paths with qself in <code>unused_qualifications</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122304">fix metadata for dyn-star in new solver</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122164">fix misaligned loads when loading UEFI arg pointers</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121958">fix redundant import errors for preload extern crate</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119385">fix type resolution of associated const equality bounds (take 2)</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122244">fix: localWaker memory leak and some stability attributes</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121857">implement async closure signature deduction</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122152">improve diagnostics for parenthesized type arguments</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122249">interpret: do not call machine read hooks during validation</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121202">limit the number of names and values in check-cfg diagnostics</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/118879">lint singleton gaps after exclusive ranges</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122022">loongarch: add frecipe and relax target feature</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121282">lower transmutes from int to pointer type as gep on null</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122103">make TAITs and ATPITs capture late-bound lifetimes in scope</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121796">make <code>DefiningAnchor::Bind</code> only store the opaque types that may be constrained, instead of the current infcx root item</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122147">make <code>std::os::unix::ucred</code> module private</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122114">make not finding core a fatal error</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122063">make the lowering of <code>thir::ExprKind::If</code> easier to follow</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122221">match lowering: define a convenient <code>struct</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121846">only compare ambiguity item that have hard error</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122018">only set noalias on Box with the global allocator</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122138">record mtime in bootstrap's LLVM linker script</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121194">refactor pre-getopts command line argument handling</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122072">refer to "slice" instead of "vector" in Ord and PartialOrd trait impl of slices</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121089">remove <code>feed_local_def_id</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121959">removing absolute path in proc-macro</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121382">rework <code>untranslatable_diagnostic</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122140">run a single huge <code>par_body_owners</code> instead of many small ones after each other</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121863">silence mismatched types errors for implied projections</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119888">stabilize the <code>#[diagnostic]</code> namespace and <code>#[diagnostic::on_unimplemented]</code> attribute</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121438">std support for wasm32 panic=unwind</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122299">store backtrace for <code>must_produce_diag</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122107">temporarily make allow-by-default the <code>non_local_definitions</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122076">tweak the way we protect in-place function arguments in interpreters</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122027">uplift some feeding out of <code>associated_type_for_impl_trait_in_impl</code> and into queries</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122048">use GEP inbounds for ZST and DST field offsets</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122320">use ptradd for vtable indexing</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122290">MIR printing: print the path of uneval'd const</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122233">miri: do not apply aliasing restrictions to <code>Box</code> with custom allocator</a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3340">miri: remove the ability to disable ABI checking</a></li>
<li>perf: build <code>rustc</code> with 1CGU on <a href="https://github.com/rust-lang/rust/pull/112268"><code>x86_64-apple-darwin</code></a> and <a href="https://github.com/rust-lang/rust/pull/112267"><code>x86_64-pc-windows-msvc</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120268">replace the default branch with an unreachable branch If it is the last variant</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122059">optimize write with <code>as_const_str</code> for shorter code</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121938">fix quadratic behavior of repeated vectored writes</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121428">net: don't use checked arithmetic when parsing numbers with known max digits</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121201"><code>align_offset, align_to</code>: no longer allow implementations to spuriously fail to align</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121403">impl <code>From<TryReserveError></code> for <code>io::Error</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/114655">make <code>impl<Fd: AsFd></code> impl take <code>?Sized</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/99153">add <code>Read</code> impl for <code>&Stdin</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121942"><code>std::rand</code>: enable getrandom for dragonflybsd too</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122002"><code>std::threads</code>: revisit stack address calculation on netbsd</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121633">win10: use <code>GetSystemTimePreciseAsFileTime</code> directly</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121956">windows: implement condvar, mutex and rwlock using futex</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121148">add <code>slice::try_range</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121280">implement <code>MaybeUninit::fill{,_with,_from}</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122298"><code>RawVec::into_box</code>: avoid unnecessary intermediate reference</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120504"><code>Vec::try_with_capacity</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/122099">add <code>#[inline]</code> to <code>BTreeMap::new</code> constructor</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/112136">add <code>std::ffi::c_str</code> module</a></li>
<li><a href="https://github.com/rust-lang/futures-rs/pull/2825">futures: add a helper for always ready futures</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13399">cargo: cli: allow logging to chrome traces</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13557">cargo: doc: collapse down generated statuses without --verbose</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13538">cargo: log: trace parameters to align with profile</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13564">cargo: lockfile: make diffing/printing more reusable</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13537">cargo: consistently compare MSRVs</a></li>
<li><a href="https://github.com/rust-lang/rustfmt/pull/6092">rustfmt: fix failure with <code>=></code> in comment after match <code>=></code></a></li>
<li>clippy: new lints: <a href="https://github.com/rust-lang/rust-clippy/pull/12378"><code>duplicated_attributes</code></a>, <a href="https://github.com/rust-lang/rust-clippy/pull/12440"><code>manual_unwrap_or_default</code></a>, <a href="https://github.com/rust-lang/rust-clippy/pull/12401"><code>nonminimal_bool</code></a>, <a href="https://github.com/rust-lang/rust-clippy/pull/12449"><code>zero_repeat_side_effects</code></a> and <a href="https://github.com/rust-lang/rust-clippy/pull/12310"><code>const_is_empty</code></a></li>
<li>clippy: fix duplicate diagnostics in <a href="https://github.com/rust-lang/rust-clippy/pull/12452"><code>manual_retain</code></a>, <a href="https://github.com/rust-lang/rust-clippy/pull/12442"><code>mut_mut</code></a>, <a href="https://github.com/rust-lang/rust-clippy/pull/12443"><code>no_effect_replace</code></a> and <a href="https://github.com/rust-lang/rust-clippy/pull/12448"><code>single_match</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12429">clippy: don't lint <code>redundant_field_names</code> across macro boundaries</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12447">clippy: fix <code>std_instead_of_core</code> false positive</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12433">clippy: fix <code>missing_docs_in_private_items</code> on some proc macros</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12446">clippy: have more lints respect <code>#[allow]</code> on exprs</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16762">rust-analyzer: add QuickFix for unresolved field</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16810">rust-analyzer: add fix for <code>unused_variables</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16808">rust-analyzer: add proc macro semantic token type</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16773">rust-analyzer: add config and capability for test explorer</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16781">rust-analyzer: don't escape <code>\</code> and <code>$</code> in "Extract format expressions" assist</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16776">rust-analyzer: don't force draw a dependency edge to the <code>real_span_map</code> query</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16777">rust-analyzer: don't invalid body query results when generating desugared names</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16811">rust-analyzer: fix method resolution snapshotting <code>receiver_ty</code> too early</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16769">rust-analyzer: function argument type inference with associated type impl trait</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16766">rust-analyzer: keep attributes in assist <code>'generate_delegate_trait'</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16770">rust-analyzer: panic when using float numbers without dots in chain calls</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16782">rust-analyzer: preserve $ and \ in postfix format completions</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16775">rust-analyzer: remove accidental dependency between <code>parse_macro_expansion</code> and <code>parse</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16779">rust-analyzer: skip match diagnostics for partially unknown types</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16755">rust-analyzer: for toolchain binaries use the full path found in $PATH</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16473">rust-analyzer: stop eagerly resolving inlay hint text edits for VSCode</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-compiler-performance-triage">Rust Compiler Performance Triage</a></h5>
<p>A mixed week, with a vast number of improvements (in large part due to PR</p>
<h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#122010-which-undoes-a-prior-regression-pr-120985-a-host-llvm-update">122010, which undoes a prior regression; PR #120985, a host LLVM update).</a></h3>
<p>But also three admittedly small-ish regressions which seemed unanticipated and
were still large enough that I did not feel comfortable rubber-stamping them
with a perf-regression-triaged marking.</p>
<p>Triage done by <strong>@pnkfelix</strong>.
Revision range: <a href="https://perf.rust-lang.org/?start=41d97c8a5dea2731b0e56fe97cd7cb79e21cff79&end=e919669d42dfb8950866d4cb268c5359eb3f7c54&absolute=false&stat=instructions%3Au">41d97c8a..e919669d</a></p>
<p>2 Regressions, 5 Improvements, 9 Mixed; 5 of them in rollups
54 artifact comparisons made in total</p>
<p><a href="https://github.com/rust-lang/rustc-perf/blob/69fb50d19f3d9bb28a903ddcee7326eef6a11518/triage/2024-03-11.md">Full report here</a></p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#approved-rfcs"></a><a href="https://github.com/rust-lang/rfcs/commits/master">Approved RFCs</a></h5>
<p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments) process</a>. These
are the RFCs that were approved for implementation this week:</p>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/3243">RFC: Packages as (optional) namespaces</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#final-comment-period">Final Comment Period</a></h5>
<p>Every week, <a href="https://www.rust-lang.org/team.html">the team</a> announces the 'final comment period' for RFCs and key PRs
which are reaching a decision. Express your opinions now.</p>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rfcs"></a><a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">RFCs</a></h6>
<ul>
<li><em>No RFCs entered Final Comment Period this week.</em></li>
</ul>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#tracking-issues-prs">Tracking Issues & PRs</a></h6>
<a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust"></a><a href="https://github.com/rust-lang/rust/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Rust</a>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/117164">Normalize trait ref before orphan check & consider ty params in alias types to be uncovered</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/121720">Split refining_impl_trait lint into _reachable, _internal variants</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/120845">debuginfo: Stabilize <code>-Z debug-macros</code>, <code>-Z collapse-macro-debuginfo</code> and <code>#[collapse_debuginfo]</code></a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/122055">Stabilize associated type bounds (RFC 2289)</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/issues/115285"><code>c_unwind</code> full stabilization request: change in <code>extern "C"</code> behavior</a></li>
<li>[disposition: postpone] <a href="https://github.com/rust-lang/rust/issues/120797">Consider linting against 00B7 aka interpunct aka middle dot</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/116935">Prevent opaque types being instantiated twice with different regions within the same function</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/119820">instantiate higher ranked goals outside of candidate selection</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/117918">Add <code>wasm_c_abi</code> <code>future-incompat</code> lint</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/121948">stabilize ptr.is_aligned, move ptr.is_aligned_to to a new feature gate </a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/121952">feat: <code>implement {Div,Rem}Assign<NonZero<X>></code> on <code>X</code></a></li>
</ul>
<a class="toclink" href="http://this-week-in-rust.org/atom.xml#cargo"></a><a href="https://github.com/rust-lang/cargo/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Cargo</a>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/cargo/pull/12783">cargo: prevent dashes in lib.name</a></li>
</ul>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#new-and-updated-rfcs"></a><a href="https://github.com/rust-lang/rfcs/pulls">New and Updated RFCs</a></h6>
<ul>
<li>[new] <a href="https://github.com/rust-lang/rfcs/pull/3585">Make <code>cargo install</code> respect lockfiles by default</a></li>
</ul>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#upcoming-events">Upcoming Events</a></h4>
<p>Rusty Events between 2024-03-13 - 2024-04-10 🦀</p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#virtual">Virtual</a></h5>
<ul>
<li>2024-03-14 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/opentechschool-berlin/">OpenTechSchool Berlin</a><ul>
<li><a href="https://www.meetup.com/opentechschool-berlin/events/298406445/"><strong>Web Frontend Co-Learning (online)</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Berlin, DE) | <a href="https://berline.rs/">OpenTechSchool Berlin</a> + <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://meet.jit.si/RustHackAndLearnBerlin"><strong>Rust Hack and Learn</strong></a> | <a href="https://www.meetup.com/rust-berlin/events/298457903/"><strong>Mirror: Rust Hack n Learn Meetup</strong></a> | <a href="https://berline.rs/2024/03/14/rust-hack-and-learn.html"><strong>Mirror: Berline.rs page</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Nürnberg, DE) | <a href="https://www.meetup.com/rust-noris/">Rust Nüremberg</a><ul>
<li><a href="https://www.meetup.com/rust-noris/events/297945252/"><strong>Rust Nürnberg online</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (San Diego, CA, US) | <a href="https://www.meetup.com/san-diego-rust/">San Diego Rust</a><ul>
<li><a href="https://www.meetup.com/san-diego-rust/events/299743034/"><strong>San Diego Rust March 2024 Tele-Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Virtual | <a href="https://github.com/formal-land/">Formal Land</a><ul>
<li><a href="https://lecture.senfcall.de/hay-gmh-wox-mru"><strong>Rust for Lunch: Formal verification for Rust with coq-of-rust. Speaker: Guillaume Claret</strong></a> | <a href="https://github.com/formal-land/coq-of-rust">Docs</a></li>
</ul>
</li>
<li>2024-03-19 | Virtual (Washinigton, DC, US) | <a href="https://www.meetup.com/rustdc/">Rust DC</a><ul>
<li><a href="https://www.meetup.com/rustdc/events/299335006/"><strong>Mid-month Rustful</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Virtual (Cardiff, UK) | <a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/">Rust and C++ Cardiff</a><ul>
<li><a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/events/299505703/"><strong>Rust for Rustaceans Book Club: Chapter 3 - Designing Interfaces</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Virtual (Vancouver, BC, CA)| <a href="https://www.meetup.com/vancouver-rust/">Vancouver Rust</a><ul>
<li><a href="https://www.meetup.com/vancouver-rust/events/292763494/"><strong>Rust Study/Hack/Hang-out</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Virtual (Charlottesville, NC, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/">Charlottesville Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/298368793/"><strong>Crafting Interpreters in Rust Collaboratively</strong></a></li>
</ul>
</li>
<li>2024-03-26 | Virtual + In Person (Barcelona, ES) | <a href="https://www.meetup.com/es-ES/bcnrust/">BcnRust</a><ul>
<li><a href="https://www.meetup.com/es-ES/bcnrust/events/299223178/"><strong>13th BcnRust Meetup</strong></a> - <a href="https://www.youtube.com/@bcnrust">Stream</a></li>
</ul>
</li>
<li>2024-03-26 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/">Dallas Rust</a><ul>
<li><a href="https://www.meetup.com/dallasrust/events/299644917/"><strong>Last Tuesday</strong></a></li>
</ul>
</li>
<li>2024-03-28 | Virtual + In Person (Berlin, DE) | <a href="https://berline.rs/">OpenTechSchool Berlin</a> + <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://meet.jit.si/RustHackAndLearnBerlin"><strong>Rust Hack and Learn</strong></a> | <a href="https://www.meetup.com/rust-berlin/events/298457904/"><strong>Mirror: Rust Hack n Learn Meetup</strong></a></li>
</ul>
</li>
<li>2024-04-02 | Virtual (Buffalo, NY, US) | <a href="https://www.meetup.com/buffalo-rust-meetup/">Buffalo Rust</a><ul>
<li><a href="https://www.meetup.com/buffalo-rust-meetup/events/mrnrktygcgbdb/"><strong>Buffalo Rust User Group</strong></a></li>
</ul>
</li>
<li>2024-04-03 | Virtual (Cardiff, UK) | <a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/">Rust and C++ Cardiff</a><ul>
<li><a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/events/299507234/"><strong>Rust for Rustaceans Book Club: Chapter 4 - Error Handling</strong></a></li>
</ul>
</li>
<li>2024-04-03 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs/">Indy Rust</a><ul>
<li><a href="https://www.meetup.com/indyrs/events/299047892/"><strong>Indy.rs - with Social Distancing</strong></a></li>
</ul>
</li>
<li>2024-04-09 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/">Dallas Rust</a><ul>
<li><a href="https://www.meetup.com/dallasrust/events/298341660/"><strong>Second Tuesday</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#africa">Africa</a></h5>
<ul>
<li>2024-04-05 | Kampala, UG | <a href="https://www.eventbrite.com/o/rust-circle-kampala-65249289033">Rust Circle Kampala</a><ul>
<li><a href="https://www.eventbrite.com/e/rust-circle-meetup-tickets-628763176587"><strong>Rust Circle Meetup</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#asia">Asia</a></h5>
<ul>
<li>2024-03-30 | New Delhi, IN | <a href="https://www.meetup.com/rustdelhi/">Rust Delhi</a><ul>
<li><a href="https://www.meetup.com/rustdelhi/events/299771772/"><strong>Rust Delhi Meetup #6</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#europe">Europe</a></h5>
<ul>
<li>2024-03-13 | Paris, FR | <a href="https://www.eventbrite.com/o/paris-rustaceans-74289178383">Paris Rustaceans</a><ul>
<li><a href="https://www.eventbrite.fr/e/rust-meetup-in-paris-tickets-830340830777"><strong>Rust Meetup in Paris</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Reading, UK | <a href="https://www.meetup.com/reading-rust-workshop/">Reading Rust Workshop</a><ul>
<li><a href="https://www.meetup.com/reading-rust-workshop/events/298533419/"><strong>Reading Rust Meetup at Browns</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Aarhus, DK | <a href="https://www.meetup.com/rust-aarhus/">Rust Aarhus</a><ul>
<li><a href="https://www.meetup.com/rust-aarhus/events/299028814/"><strong>Hack Night</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Leipzig, DE | <a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/">Rust - Modern Systems Programming in Leipzig</a><ul>
<li><a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/299309224/"><strong>Rust Interactive Session</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Prague, CZ | <a href="https://www.meetup.com/rust-prague/events/299515169/">Rust Prague</a><ul>
<li><a href="https://www.meetup.com/rust-prague/events/299515169/"><strong>Rust Meetup @ Charles University</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Girona, ES | <a href="https://www.meetup.com/rust-girona/">Rust Girona</a><ul>
<li><a href="https://www.meetup.com/rust-girona/events/299172343/"><strong>Introduction to programming Microcontrollers with Rust</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Lyon, FR | <a href="https://www.meetup.com/fr-FR/rust-lyon/">Rust Lyon</a><ul>
<li><a href="https://www.meetup.com/fr-FR/rust-lyon/events/299527560/"><strong>Rust Lyon Meetup #9</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Augsburg, DE | <a href="https://www.meetup.com/de-DE/rust-meetup-augsburg/">Rust Meetup Augsburg</a><ul>
<li><a href="https://www.meetup.com/de-DE/rust-meetup-augsburg/events/299354449/"><strong>Augsburg Rust Meetup #6</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Lille, FR | <a href="https://www.meetup.com/meetup-group-zgphbyet/">Rust Lille</a><ul>
<li><a href="https://www.meetup.com/meetup-group-zgphbyet/events/299295547/"><strong>Rust Lille #6: Du RSS et de L'ECS !</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Vienna, AT | <a href="https://www.meetup.com/rust-vienna/">Rust Vienna</a><ul>
<li><a href="https://www.meetup.com/rust-vienna/events/299682390/"><strong>Rust Vienna Meetup - March - Unsafe Rust</strong></a></li>
</ul>
</li>
<li>2024-03-23 | Stockholm, SE | <a href="https://www.google.com/calendar/event?eid=NWMzaDNqZDZjcG5oZXNwYzJycHRzMXI5djUgYXBkOXZtYmMyMmVnZW5tdHU1bDZjNWpiZmNAZw&ctz=America/Los_Angeles">Ferris' Fika Forum</a><ul>
<li><a href="https://www.google.com/calendar/event?eid=NWMzaDNqZDZjcG5oZXNwYzJycHRzMXI5djUgYXBkOXZtYmMyMmVnZW5tdHU1bDZjNWpiZmNAZw&ctz=America/Los_Angeles"><strong>Ferris' Fika Forum</strong></a> | <a href="https://maps.google.com/maps?hl=en&q=Starbucks%2C%20Hamngatan%2033%2C%20111%2047%20Stockholm%2C%20Sweden">Map</a></li>
</ul>
</li>
<li>2024-03-26 | Barcelona, ES + Virtual | <a href="https://www.meetup.com/es-ES/bcnrust/">BcnRust</a><ul>
<li><a href="https://www.meetup.com/es-ES/bcnrust/events/299223178/"><strong>13th BcnRust Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-26 - 2024-03-28 | London, UK | <a href="https://www.rustnationuk.com/">Rust Nation UK</a><ul>
<li><a href="https://www.rustnationuk.com/"><strong>Rust Nation 2024 - Conference</strong></a></li>
</ul>
</li>
<li>2024-03-28 | Berlin, DE | <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://www.meetup.com/rust-berlin/events/299288961/"><strong>Rust and Tell</strong></a></li>
</ul>
</li>
<li>2024-04-10 | Cambridge, UK | <a href="https://www.meetup.com/cambridge-rust-meetup/">Cambridge Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/cambridge-rust-meetup/events/299730322/"><strong>Rust Meetup Reboot 3</strong></a></li>
</ul>
</li>
<li>2024-04-10 | Oslo, NO | <a href="https://www.meetup.com/rust-oslo/">Rust Oslo</a><ul>
<li><a href="https://www.meetup.com/rust-oslo/events/299488225/"><strong>Rust Hack'n'Learn at Kampen Bistro</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#north-america">North America</a></h5>
<ul>
<li>2024-03-13 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/">Boston Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/bostonrust/events/299262009/"><strong>Northeastern Rust Lunch</strong></a></li>
</ul>
</li>
<li>2024-03-19 | San Francisco, CA, US | <a href="https://www.meetup.com/san-francisco-rust-study-group/">San Francisco Rust Study Group</a><ul>
<li><a href="https://www.meetup.com/san-francisco-rust-study-group/events/299186823/"><strong>Rust Hacking in Person</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Seattle, WA, US | <a href="https://www.meetup.com/seattle-rust-user-group/">Seattle Rust User Group</a><ul>
<li><a href="https://www.meetup.com/seattle-rust-user-group/events/298631832/"><strong>Seattle Rust User Group Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-22 | Somerville, MA, US | <a href="https://www.meetup.com/bostonrust/">Boston Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/bostonrust/events/299262036/"><strong>Somerville Union Square Rust Lunch, Mar 22</strong></a></li>
</ul>
</li>
<li>2024-03-26 | Minneapolis, MN, US | <a href="https://www.meetup.com/minneapolis-rust-meetup/">Minneapolis Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/minneapolis-rust-meetup/events/299489274/"><strong>Minneapolis Rust: Getting started with Rust!</strong></a></li>
</ul>
</li>
<li>2024-03-27 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx/">Rust ATX</a><ul>
<li><a href="https://www.meetup.com/rust-atx/events/299220136/"><strong>Rust Lunch - Fareground</strong></a></li>
</ul>
</li>
<li>2024-03-27 | Hawthorne, CA, US | <a href="https://freeform.co/">Freeform</a><ul>
<li><a href="https://freeformxrust.rsvpify.com/"><strong>Rust in the Physical World 🦀 Tech Talk Event at Freeform</strong></a></li>
</ul>
</li>
<li>2024-03-31 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/">Boston Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/bostonrust/events/299262047/"><strong>Beacon Hill Rust Lunch, Mar 31</strong></a></li>
</ul>
</li>
</ul>
<p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to get
it mentioned here. Please remember to add a link to the event too.
Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#jobs">Jobs</a></h4>
<p>Please see the latest <a href="https://www.reddit.com/r/rust/comments/1arr8xi/official_rrust_whos_hiring_thread_for_jobseekers/">Who's Hiring thread on r/rust</a></p>
<h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#quote-of-the-week">Quote of the Week</a></h3>
<blockquote>
<p>In 10 years we went from “Rust will never replace C and C++” to “New C/C++ should not be written anymore, and you should use Rust”. Good job.</p>
</blockquote>
<p>– <a href="https://lobste.rs/s/dbwn98/secure_by_design_google_s_perspective_on#c_f6j9ok">dpc_pw on lobste.rs</a></p>
<p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/1547">Dennis Luxen</a> for the suggestion!</p>
<p><a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328">Please submit quotes and vote for next week!</a></p>
<p><em>This Week in Rust is edited by: <a href="https://github.com/nellshamrell">nellshamrell</a>, <a href="https://github.com/llogiq">llogiq</a>, <a href="https://github.com/cdmistman">cdmistman</a>, <a href="https://github.com/ericseppanen">ericseppanen</a>, <a href="https://github.com/extrawurst">extrawurst</a>, <a href="https://github.com/andrewpollack">andrewpollack</a>, <a href="https://github.com/U007D">U007D</a>, <a href="https://github.com/kolharsam">kolharsam</a>, <a href="https://github.com/joelmarcey">joelmarcey</a>, <a href="https://github.com/mariannegoldin">mariannegoldin</a>, <a href="https://github.com/bennyvasquez">bennyvasquez</a>.</em></p>
<p><em>Email list hosting is sponsored by <a href="https://foundation.rust-lang.org/">The Rust Foundation</a></em></p>
<p><small><a href="https://www.reddit.com/r/rust/comments/1bec9sy/this_week_in_rust_538/">Discuss on r/rust</a></small></p>2024-03-13T04:00:00+00:00TWiR ContributorsMozilla Open Policy & Advocacy Blog: Mozilla joins allies to co-sign an amicus brief in State of Nevada vs. Meta Platforms defending end-to-end encryption
https://blog.mozilla.org/netpolicy/2024/03/12/nevada-e2ee-amicus/
<p>Mozilla recently signed onto an <a href="https://blog.mozilla.org/netpolicy/files/2024/03/nevada-v-meta-amicus-brief.pdf">amicus brief</a> – alongside the <a href="https://www.eff.org/press/releases/reject-nevadas-attack-encrypted-messaging-eff-tells-court">Electronic Frontier Foundation</a> , the <a href="https://www.internetsociety.org/blog/2024/03/nevada-wants-to-reduce-online-protections-for-children/">Internet Society</a>, <a href="https://signal.org/">Signal</a>, and a broad coalition of other allies – on the Nevada Attorney General’s recent attempt to limit encryption. The amicus brief signals a collective commitment from these organizations on the importance of encryption in safeguarding digital privacy and security as fundamental rights.</p>
<p>The core of this dispute is the Nevada Attorney General’s proposition to limit the application of end-to-end encryption (E2EE) for children’s online communications. It is a move that ostensibly aims to aid law enforcement but, in practice, could significantly weaken the privacy and security of all internet users, including children. Nevada argues that end-to-end encryption might impede some criminal investigations. However, as the amicus brief explains, encryption does not prevent either the sender or recipient from reporting concerning content to police, nor does it prevent police from accessing other metadata about communications via lawful requests. Blocking the rollout of end-to-end encryption would undermine privacy and security for everyone for a marginal benefit that would be far outweighed by the harms such a draconian limitation could create.</p>
<p>The case, set for a hearing in Clark County, Nevada, encapsulates a broader debate on the balance between enabling law enforcement to combat online crimes and preserving robust online protections for all users – especially vulnerable populations like children. Mozilla’s involvement in this amicus brief is founded on its long standing <a href="https://www.cbc.ca/news/science/mozilla-campaign-encourages-people-to-understand-encryption-1.3460109">belief</a> that encryption is an essential component of its core <a href="https://www.mozilla.org/en-GB/about/manifesto/">Manifesto</a> tenet – privacy and security are fundamental online and should not be treated as optional.</p>
<p>The post <a href="https://blog.mozilla.org/netpolicy/2024/03/12/nevada-e2ee-amicus/">Mozilla joins allies to co-sign an amicus brief in State of Nevada vs. Meta Platforms defending end-to-end encryption</a> appeared first on <a href="https://blog.mozilla.org/netpolicy">Open Policy & Advocacy</a>.</p>2024-03-12T23:23:24+00:00Udbhav TiwariJan-Erik Rediger: Six-year Moziversary
https://fnordig.de/2024/03/12/six-year-moziversary
<p>Another year went by, so that it's now been 6 years since I <a href="https://fnordig.de/2018/02/18/a-new-job/">joined Mozilla as a Telemetry engineer</a>,
I blogged every year since then: <a href="https://fnordig.de/2019/03/01/one-year-moziversary/">2019</a>, <a href="https://fnordig.de/2020/03/02/two-year-moziversary/">2020</a>, <a href="https://fnordig.de/2021/03/01/three-year-moziversary/">2021</a>, <a href="https://fnordig.de/2022/03/04/four-year-moziversary/">2022</a>, <a href="https://fnordig.de/2023/03/01/five-year-moziversary/">2023</a></p>
<p>Looking back at the past year it sure was different than the years before, again.
Obviously we left most of the pandemic isolation behind us and I got to meet more of my coworkers in person:
At the Mozilla All-Hands in Montreal, Canada, though that was cut short for me due to ... of course: Covid.
At PyCon DE and PyData here in Berlin.
And at another workweek with my extended team also here in Berlin.</p>
<p>My work also changed.
As predicted a year ago I branched out beyond the Glean SDK, took a <a href="https://youtu.be/nZupfJy6I0A">look at our data pipeline</a>,
worked on features across the stack and wrote a ton of stuff that is not code.
Most of that work spanned months and months and some is still not 100% finished.</p>
<p>For this year I'm focusing a bit more on the SDK and client-side world again.
With Glean used just about everywhere it's time we look into some optimizations.
In the past we made it correct first and paid less attention to optimize resource usage (CPU & memory for example).
Now that we have more and more usage in Firefox Desktop (Use Counters!) we need to look into making data collection more efficient.
The first step is to get better insights where and how much memory we use.
Then we can optimize.
Firefox comes with some of its own tooling for that with which we need to integrate, see <a href="https://fnordig.de/tagged/mozilla.xml">about:memory</a> for example.</p>
<p>I'm also noticing some parts in our codebase where in hindsight I wish we had made different implementation decisions.
At the time though we did make the right choices, now we need to deal with that (memory usage might be one of these, storage sure is another one).</p>
<p>And Mozilla more broadly?
It's changing. All the time.
We just had layoffs and reprioritization of projects.
That certainly dampens the mood.
Focus shifts and work changes.
But underneath there's still the need to use data to drive our decisions and so I'm rather confident that there's work for me to do.</p>
<h3>Thank you</h3>
<p>None of my work would happen if it weren't for my manager <a href="https://www.a2p.it/">Alessio</a> and team mates <a href="https://chuttenblog.wordpress.com/">Chris</a>, <a href="https://blogoftravis.wordpress.com/">Travis</a>, <a href="https://github.com/perrymcmanis144/">Perry</a>, <a href="https://rosahbruno.github.io/">Bruno</a> and <a href="https://github.com/abhi-agg">Abhishek</a>.
They make it fun to work here, always have some interesting things to share and they still endure my bad jokes all the time.
Thank you!<br />
Thanks also goes out to the bigger data engineering team within Mozilla, and all the other people at Mozilla I work or chat with.</p>
<hr />
<p><em>This post was planned to be published more than a week ago. It's still perfectly in time. I wasn't able to focus on it earlier.</em></p>2024-03-12T10:30:00+00:00Mozilla Open Policy & Advocacy Blog: Mozilla Joins Amicus Brief Supporting Software Interoperability
https://blog.mozilla.org/netpolicy/2024/03/11/mozilla-joins-amicus-brief-supporting-software-interoperability/
<p>In modern technology, interoperability between programs is crucial to the usability of applications, user choice, and healthy competition. Today Mozilla has joined an <a href="https://www.eff.org/files/2024/03/11/eff_et_al_amicus_brief28.pdf">amicus brief</a> at the Ninth Circuit, to ensure that copyright law does not undermine the ability of developers to build interoperable software.</p>
<p>This amicus brief comes in the latest appeal in a multi-year courtroom saga between Oracle and Rimini Street. The sprawling litigation has lasted more than a decade and has already been up to the Supreme Court on a <a href="https://supreme.justia.com/cases/federal/us/586/17-1625/">procedural question</a> about court costs. Our amicus brief addresses a single issue: should the fact that a software program is built to be interoperable with another program be treated, <i>on its own</i>, as establishing copyright infringement?</p>
<p>We believe that most software developers would answer this question with: “Of course not!” But the district court found otherwise. The lower court concluded that even if Rimini’s software does not include any Oracle code, Rimini’s programs could be infringing <a href="https://en.wikipedia.org/wiki/Derivative_work">derivative works</a> simply “because they do not work with any other programs.” This is a mistake.</p>
<p>The classic example of a derivative work is something like a sequel to a book or movie. For example, The Empire Strikes Back is a derivative work of the original Star Wars movie. Our amicus brief explains that it makes no sense to apply this concept to software that is built to interoperate with another program. Not only that, interoperability of software <a href="https://blog.mozilla.org/netpolicy/files/2019/09/Mozilla-Competition-Working-Paper.pdf">promotes competition and user choice</a>. It should be celebrated, not punished.</p>
<p>This case raises similar themes to another high profile software copyright case, <a href="https://www.eff.org/cases/oracle-v-google">Google v. Oracle</a>, which considered whether it was copyright infringement to re-implement an API. Mozilla submitted an <a href="https://blog.mozilla.org/netpolicy/files/2019/02/Mozilla-Google-v-Oracle-Amicus-Brief.pdf">amicus brief</a> there also, where we argued that copyright law should support interoperability. Fortunately, the Supreme Court <a href="https://blog.mozilla.org/en/mozilla/software-innovation-prevails-in-landmark-supreme-court-ruling-in-google-v-oracle/">reached the right conclusion</a> and ruled that re-implementing an API was fair use. That ruling and <a href="https://en.wikipedia.org/wiki/Sega_v._Accolade">other important fair use decisions</a> would be undermined if a copyright plaintiff could use interoperability as evidence that software is an infringing derivative work.</p>
<p>In today’s brief Mozilla joins a broad coalition of advocates for openness and competition, including the <a href="https://www.eff.org/">Electronic Frontier Foundation</a>, <a href="https://creativecommons.org/">Creative Commons</a>, <a href="https://publicknowledge.org/">Public Knowledge</a>, <a href="https://www.ifixit.com/">iFixit</a>, and the <a href="https://www.repair.org/">Digital Right to Repair Coalition</a>. We hope the Ninth Circuit will fix the lower court’s mistake and hold that interoperability is not evidence of infringement.</p>
<p>The post <a href="https://blog.mozilla.org/netpolicy/2024/03/11/mozilla-joins-amicus-brief-supporting-software-interoperability/">Mozilla Joins Amicus Brief Supporting Software Interoperability</a> appeared first on <a href="https://blog.mozilla.org/netpolicy">Open Policy & Advocacy</a>.</p>2024-03-12T03:10:46+00:00Daniel NazerThe Servo Blog: You can now sponsor Servo on GitHub and Open Collective!
https://servo.org/blog/2024/03/12/sponsoring-servo/
<figure class="_figr"><a href="https://github.com/sponsors/servo"><img alt="Servo’s donation page on GitHub Sponsors" src="https://servo.org/img/blog/sponsor-on-github.png" /></a>
<br /><a href="https://opencollective.com/servo"><img alt="Servo’s donation page on Open Collective" src="https://servo.org/img/blog/sponsor-on-open-collective.png" /></a></figure>
<p><span class="_floatmin"></span>Over the past year, Servo has <a href="https://servo.org/blog/2023/12/18/this-year-in-servo/">gone a long way</a> towards reigniting the dream of a web rendering engine in Rust. This comes with a lot of potential, and not just towards becoming a viable alternative to WebKit and Chromium for embedded webviews. If we can make the web platform more modular and easily reusable in both familiar and novel ways, and help build web-platform-grade libraries in underlying areas like networking, graphics, and typography, we could really change the Rust ecosystem.</p>
<p>In theory, anything is possible in a free and open source project like ours, and we think projects like Servo and <a href="https://ladybird.dev/">Ladybird</a> have shown that building a web browser with limited resources is more achievable than many have assumed. But doing those things well does take time and money, and we can only achieve Servo’s full potential with your help.</p>
<p>You can now help fund the Servo project by <a href="https://github.com/sponsors/servo"><strong>sponsoring us on GitHub</strong></a> or <a href="https://opencollective.com/servo"><strong>Open Collective</strong></a>.</p>
<aside class="_note">
<p>In both cases, donations are handled by <a href="https://opencollective.com/opensource">Open Source Collective</a>. We are not affected by the <a href="https://blog.opencollective.com/open-collective-official-statement-ocf-dissolution/">dissolution</a> of <a href="https://opencollective.com/foundation">Open Collective Foundation</a>, who are a separate organisation with a similar name.</p>
</aside>
<p><strong>We will stop accepting donations <a href="https://crowdfunding.lfx.linuxfoundation.org/projects/servo">on LFX</a> soon.</strong> Any funds left over will also be transferred to the Servo project, but recurring donations will be cancelled, so if you would like to continue your recurring donation, please do so on GitHub or Open Collective.</p>
<p>Both one-time and monthly donations are appreciated, and <strong>over 94%</strong> of the amount will go directly towards improving Servo, with the remaining 6% going to processing fees. The way the funds are used is decided in public via the <a href="https://servo.org/governance/">Technical Steering Committee</a>, but to give you a sense of scale…</p>
<ul>
<li>at <strong>100 USD/month</strong>, we can cover the costs of our website and other core infrastructure
</li><li>at <strong>1,000 USD/month</strong>, we can set up dedicated servers for faster Windows and macOS builds, better test coverage and reliability, and new techniques like fuzzing and performance testing
</li><li>at <strong>10,000 USD/month</strong>, we can sponsor a developer to make Servo their top priority
</li></ul>
<p>If you or your company are interested in making a bigger donation or funding specific work that would make Servo more useful to your needs, you can also reach out to us at <a href="mailto:join@servo.org">join@servo.org</a>.</p>2024-03-12T00:00:00+00:00Firefox Nightly: A Better Screenshots Tool and More – These Weeks in Firefox: Issue 156
https://blog.nightly.mozilla.org/2024/03/11/a-better-screenshots-tool-and-more-these-weeks-in-firefox-issue-156/
<h3 dir="ltr">Highlights</h3>
<ul>
<li>The new Screenshots component (which replaces the Screenshots built-in extension) is now enabled by default on Nightly (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1789727" rel="noopener" target="_blank">bug 1789727</a>)! This improves upon the extension version of the feature in a number of ways:
<ul>
<li>You can capture screenshots of about: pages and other pages that extensions cannot normally manipulate</li>
</ul>
</li>
</ul>
<p><img alt="The Screenshots feature in Firefox functioning within the about:config page" class="aligncenter wp-image-1577 size-full" height="498" src="https://blog.nightly.mozilla.org/files/2024/03/image4.png" width="854" /></p>
<ul>
<li>
<ul>
<li>Improved performance!</li>
<li>Greatly improved keyboard and visual accessibility</li>
<li>You can ensure it’s on by default by checking if screenshots.browser.component.enabled is set to true in about:config</li>
<li>Found issues with the new component? <a href="https://bugzilla.mozilla.org/enter_bug.cgi?assigned_to=nobody%40mozilla.org&bug_ignored=0&bug_severity=--&bug_status=NEW&cf_a11y_review_project_flag=---&cf_accessibility_severity=---&cf_fx_iteration=---&cf_fx_points=---&cf_has_str=---&cf_install_update_workflow=---&cf_performance_impact=---&cf_status_firefox123=---&cf_status_firefox124=---&cf_status_firefox125=---&cf_status_firefox_esr115=---&cf_tracking_firefox123=---&cf_tracking_firefox124=---&cf_tracking_firefox125=---&cf_tracking_firefox_esr115=---&cf_tracking_firefox_relnote=---&cf_webcompat_priority=---&component=Screenshots&contenttypemethod=list&contenttypeselection=text%2Fplain&defined_groups=1&filed_via=standard_form&flag_type-203=X&flag_type-37=X&flag_type-41=X&flag_type-607=X&flag_type-708=X&flag_type-721=X&flag_type-737=X&flag_type-748=X&flag_type-787=X&flag_type-799=X&flag_type-803=X&flag_type-846=X&flag_type-855=X&flag_type-864=X&flag_type-930=X&flag_type-936=X&flag_type-937=X&flag_type-963=X&needinfo_role=other&needinfo_type=needinfo_from&op_sys=Unspecified&priority=--&product=Firefox&rep_platform=Unspecified&target_milestone=---&version=unspecified" rel="noopener" target="_blank">File them here!</a></li>
<li>You can access the Screenshot feature via the keyboard shortcut (<span id="m_-8907795050043134525gmail-docs-internal-guid-9dbc5e50-7fff-f8a1-a930-35f5bf3cac3f">ctrl + shift + s</span> or <span id="m_-8907795050043134525gmail-docs-internal-guid-fdd5f994-7fff-7a6f-1245-ed0f2225479e">cmd + shift + s</span> for macos), the context menu, or by adding the Screenshot button to your toolbar <a href="https://support.mozilla.org/en-US/kb/customize-firefox-controls-buttons-and-toolbars" rel="noopener" target="_blank">via toolbar customization</a></li>
</ul>
</li>
<li>The Firefox Profiler has a new “Network Bandwidth” feature to record the network bandwidth used between every profiler sample. <a href="https://share.firefox.dev/3InOB8N" rel="noopener" target="_blank">Example profile</a></li>
<li><img alt="Two different timelines - one for Network and one for Bandwidth - in Firefox Profiler." class="aligncenter size-full wp-image-1572" height="554" src="https://blog.nightly.mozilla.org/files/2024/03/image9.png" width="1780" /></li>
<li><a href="https://www.youtube.com/watch?v=Ly7ve5ftRnU" rel="noopener" target="_blank">Florian gave a FOSDEM talk about the Firefox power profiling</a></li>
<li>Nicolas added support for incoming input[type=range]::slider-* pseudo elements (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881940" rel="noopener" target="_blank">bug</a>)
<ul>
<li>behind layout.css.modern-range-pseudos.enabled</li>
</ul>
</li>
</ul>
<p><img alt="The devTools inspector showing CSS rules for several input slider pseudo elements" class="aligncenter size-full wp-image-1576" height="1087" src="https://blog.nightly.mozilla.org/files/2024/03/image5.png" width="1999" /></p>
<ul>
<li>Karandeep <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1882478" rel="noopener" target="_blank">made a clipboard feature for the address bar</a>. Currently, we plan to ship this enabled by default in Firefox 125!</li>
</ul>
<p><img alt="The Firefox address bar with a "Visit from clipboard" button" class="aligncenter size-full wp-image-1578" height="178" src="https://blog.nightly.mozilla.org/files/2024/03/image3.png" width="1290" /></p>
<h3 dir="ltr">Friends of the Firefox team</h3>
<h3 dir="ltr"><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20(excluding%20employees)&quicksearch=1878635%2C1862253%2C1881979%2C1677823%2C1839845%2C1882981%2C1619201" rel="noopener" target="_blank">Resolved bugs (excluding employees)</a></h3>
<p dir="ltr"><a href="https://github.com/niklasbaumgardner/NewContributorScraper" rel="noopener" target="_blank">Script to find new contributors from bug list</a></p>
<h4 dir="ltr">Volunteers that fixed more than one bug</h4>
<ul>
<li dir="ltr">Bojidar Marinov [:bojidar-bg]</li>
<li dir="ltr">Nikki Bernobic [:echrs]</li>
</ul>
<h4 dir="ltr">New contributors (🌟 = first patch)</h4>
<ul>
<li dir="ltr">🌟 Artem Manushenkov <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1619201" rel="noopener" target="_blank">changed Watch expressions</a> input field placeholder from “Add watch expression” to “Add expression”</li>
<li dir="ltr">🌟 Bojidar Marinov [:bojidar-bg] <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1677823" rel="noopener" target="_blank">updated about: pages</a> to use OTHER_LOCAL instead of HISTORY and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1839845" rel="noopener" target="_blank">added about:settings</a> as alias of about:preferences</li>
<li dir="ltr">🌟 Patrycja Rosa [:ptrcnull] (she/her) to use <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881979" rel="noopener" target="_blank">c_int as ptrace request type</a> on musl libc</li>
<li dir="ltr">Nikki Bernobic [:echrs] <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1862253" rel="noopener" target="_blank">added a storybook story</a> that shows an example of Moz Message Bar with a Heading plus Message and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878635" rel="noopener" target="_blank">removed Deprecated.sys.mjs</a></li>
</ul>
<h3 dir="ltr">Project Updates</h3>
<h4 dir="ltr">Developer Tools</h4>
<h5 dir="ltr">DevTools</h5>
<ul>
<li>Arai fixed an issue where ReadableStream.values() was eagerly evaluated (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881359" rel="noopener" target="_blank">bug</a>)</li>
<li>Alex added a button dedicated to source map settings in the editor footer (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1853899" rel="noopener" target="_blank">bug</a>)</li>
</ul>
<p><img alt="Tooltip at the bottom of the devTools editor displaying available Source Map settings and which of those settings are enabled." class="aligncenter wp-image-1570 size-full" height="898" src="https://blog.nightly.mozilla.org/files/2024/03/image11.png" width="1182" /></p>
<ul>
<li>By popular demand, Alex added back the preference to control the Debugger Pause Overlay (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1865439" rel="noopener" target="_blank">bug</a>)
<ul>
<li>set devtools.debugger.features.overlay to false if you want to disable it</li>
</ul>
</li>
<li>Alex fixed performance issues in the debugger when a page had a lot of sources (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1880809" rel="noopener" target="_blank">bug</a>)</li>
<li>Hubert fixed an issue in the debugger where the Outline view wouldn’t populate (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879322" rel="noopener" target="_blank">bug</a>)</li>
<li>Julian fixed opening relative URL of <img> on pages with a <base> (<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base" rel="noopener" target="_blank">MDN</a>) tag (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1871391" rel="noopener" target="_blank">bug</a>)</li>
<li>Alex added an option in the tracer to track all DOM Mutations (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879087" rel="noopener" target="_blank">bug</a>)</li>
<li>from the console :trace –dom-mutations</li>
<li>(Set devtools.debugger.features.javascript-tracing to true to enable the tracer)</li>
</ul>
<p><img alt="The Tracer in Firefox devTools notifying when and at what time a DOM mutation occurs" class="aligncenter size-full wp-image-1579" height="290" src="https://blog.nightly.mozilla.org/files/2024/03/image2.png" width="1260" /></p>
<h5 dir="ltr">WebDriver BiDi</h5>
<ul>
<li dir="ltr">Thanks to Kagami who implemented set_permission for marionette driver (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881515" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Sasha implemented the storage.deleteCookies command for WebDriver BiDi. (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1854581" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Sasha added support for the userContext field of the partition parameter for storage.getCookie and storage.setCookie commands. (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875255" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Julian implemented a basic version of the network.provideResponse command. (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1880477" rel="noopener" target="_blank">bug</a>)</li>
</ul>
<h4 dir="ltr">ESMification status</h4>
<ul>
<li>ESMified status:
<ul>
<li>browser: 100%</li>
<li>toolkit: 99.83%
<ul>
<li>This one is <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1779629" rel="noopener" target="_blank">being fixed here</a></li>
</ul>
</li>
<li>devtools: 89.29%</li>
<li>dom: 96%
<ul>
<li>This one is <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1770944" rel="noopener" target="_blank">being fixed here</a></li>
</ul>
</li>
<li dir="ltr">services: 98.94%</li>
<li dir="ltr">Only 10 JSMs left in the tree!</li>
<li dir="ltr">Total: 99.35% (+0.00% from last time)</li>
</ul>
</li>
<li dir="ltr">
<p dir="ltr">#esmification on Matrix</p>
</li>
</ul>
<h4 dir="ltr">Lint, Docs and Workflow</h4>
<ul>
<li dir="ltr">:Mossop, :Gijs and Standard8 met and discussed the remaining rules (and a few others) that are recommended by ESLint but that we haven’t enabled yet.
<ul>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881262" rel="noopener" target="_blank">no-useless-escape has been turned off</a>, as the work to enable it would have been significant, and it doesn’t catch any real errors.</li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881265" rel="noopener" target="_blank">getter-return</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881266" rel="noopener" target="_blank">no-constant-condition and no-case-declarations</a> have all been turned on.</li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881497" rel="noopener" target="_blank">object-shorthand</a> has been enabled on the debugger code.</li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1883371" rel="noopener" target="_blank">no-console</a> is to be enabled soon for production code.</li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1881496" rel="noopener" target="_blank">no-shadow</a> is also on the list to enable for production code (with various exceptions)</li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870205" rel="noopener" target="_blank">no-use-before-define</a> is also likely to be enabled with a limited set of options</li>
</ul>
</li>
<li dir="ltr">:Mossop is working on <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1864896" rel="noopener" target="_blank">enabling argument linting from no-unused-vars</a>. 47 patches have already landed, 11 to go!</li>
<li dir="ltr">:Gijs has enabled a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1780071" rel="noopener" target="_blank">new rule</a> to prevent comparison or assignments within ok() assertions in tests.</li>
<li dir="ltr">The ESLint configuration has been changed so that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878553" rel="noopener" target="_blank">all .jsx files are now assumed to be ES modules</a>.</li>
<li dir="ltr">Pocket’s files that are modules have been <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1778106" rel="noopener" target="_blank">renamed to use .mjs extensions</a></li>
</ul>
<h4 dir="ltr">Migration Improvements</h4>
<ul>
<li dir="ltr">We’ve started early investigations on a profile backup feature. This feature will, in theory, allow users to create backups of their user profile in an archive on the local file system. We’re still very early days here, but <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1883052" rel="noopener" target="_blank">we have a meta bug here</a> that people can follow along with.
<ul>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1882171" rel="noopener" target="_blank">We’ve got some basic infrastructure landed</a>, and we’re <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1883503" rel="noopener" target="_blank">starting with some measurements to see how big these archive files might end up being.</a></li>
</ul>
</li>
</ul>
<h4 dir="ltr">New Tab Page</h4>
<ul>
<li dir="ltr">
<p dir="ltr">We’re in the early phases of building out an experiment that lets people set wallpapers on about:home/about:newtab. Stay tuned!</p>
</li>
</ul>
<h4 dir="ltr">Performance Tools (aka <a href="https://profiler.firefox.com/" rel="noopener" target="_blank">Firefox Profiler</a>)</h4>
<ul>
<li>Made the call tree sidebar localizable.</li>
</ul>
<p><img alt="Call tree sidebar in Firefox Profiler displaying various characters and letters to demonstrate that it can be localized into different languages." class="aligncenter size-full wp-image-1574" height="1341" src="https://blog.nightly.mozilla.org/files/2024/03/image7.png" width="1999" /></p>
<ul>
<li>Marker count is shown next to the marker name in the marker chart when a marker is hovered.</li>
</ul>
<p><img alt="A table in Firefox Profiler showing DOMEvent as a listed event that was counted up to 410 times." class="aligncenter size-full wp-image-1571" height="468" src="https://blog.nightly.mozilla.org/files/2024/03/image10.png" width="424" /></p>
<ul>
<li>Improved performance of the marker chart when there are so many overlapping markers.</li>
<li>
<p>Improved the power graph and made it easier to see very small values in the graph by hiding the zero values.</p>
</li>
<li>Before:</li>
</ul>
<p><img alt="The power graph in Firefox Profiler before implementing changes that make it easier to see small values" class="aligncenter size-full wp-image-1580" height="198" src="https://blog.nightly.mozilla.org/files/2024/03/image1.png" width="1268" /></p>
<ul>
<li>After:</li>
</ul>
<p><img alt="The power graph in Firefox Profiler after implementing changes that make it easier to see small values" class="aligncenter size-full wp-image-1575" height="214" src="https://blog.nightly.mozilla.org/files/2024/03/image6.png" width="1268" /></p>
<ul>
<li>Fixed the hittesting on the activity graph.</li>
</ul>
<p><img alt="Activity graph for a sample Firefox Profiler profile that ran for 686ms." class="aligncenter size-full wp-image-1573" height="981" src="https://blog.nightly.mozilla.org/files/2024/03/image8.png" width="1999" /></p>
<ul>
<li>Fixed the marker stacks that were broken because of a symbolication issue.</li>
</ul>
<p><span> </span></p>
<h4 dir="ltr">Search and Navigation</h4>
<ul>
<li dir="ltr">Work continues on Consolidated Search Configuration and improvements from mcheang and standard8)
<ul>
<li dir="ltr">Mandy landed a bunch of patches to get tests ready for the roll out of new search configuration – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870684" rel="noopener" target="_blank">1870684</a></li>
<li dir="ltr">Standard8 refactored some code for search settings. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879625" rel="noopener" target="_blank">1879625 </a></li>
</ul>
</li>
<li dir="ltr">General Improvements
<ul>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1677823" rel="noopener" target="_blank">Bug 1677823 – Autocomplete about: URLs</a></li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1882043" rel="noopener" target="_blank">Bug 1882043 – Recent searches section is mispositioned in the Address Bar</a></li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878519" rel="noopener" target="_blank">Bug 1878519 – Prefer recent searches over trending</a></li>
</ul>
</li>
<li dir="ltr">Switch-to-tab container improvements (marc & mak)
<ul>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1880066" rel="noopener" target="_blank">Bug 1880066 – Switch-to-tab container icons are blurry on Windows/Ubuntu</a></li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1880069" rel="noopener" target="_blank">Bug 1880069 – Switch-to-tab in a regular tab loads the url already opened in container tabs</a></li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1880078" rel="noopener" target="_blank">Bug 1880078 – Previously opened container tabs are still shown in the Tabs/Firefox suggest section after a browser restart</a></li>
<li dir="ltr">Last week was Marc Seibert’s (Berlin Student) last week at Mozilla. Thanks Marc for all your contributions to Firefox throughout the year. 🎉</li>
</ul>
</li>
<li dir="ltr">Work continues on Cross-Platform Suggest from adw, daisuke, and karandeep. These fixes include:
<ul>
<li>Yelp suggestions, improving the suggestion feedback button, fixes to weather suggestion</li>
<li>Urlbar.impression telemetry removed that is no longer needed</li>
</ul>
</li>
<li dir="ltr">Work continues on Search and SERP telemetry categorization from scunnane and jteow</li>
</ul>
<h4 dir="ltr">Storybook/Reusable Components</h4>
<ul>
<li dir="ltr">Thanks to :echrs for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1862253" rel="noopener" target="_blank">adding a story to moz-message-bar</a></li>
<li dir="ltr">Thanks to :kcochrane for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1850591" rel="noopener" target="_blank">creating the moz-page-nav component</a></li>
<li dir="ltr">:mstriemer landed the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1791816" rel="noopener" target="_blank">moz-button component</a></li>
</ul>2024-03-11T17:03:22+00:00Katherine PatenioHacks.Mozilla.Org: Improving Performance in Firefox and Across the Web with Speedometer 3
https://hacks.mozilla.org/2024/03/improving-performance-in-firefox-and-across-the-web-with-speedometer-3/
<p>In collaboration with the other major browser engine developers, Mozilla is thrilled to <a href="https://browserbench.org/announcements/speedometer3">announce Speedometer 3</a> today. Like previous versions of Speedometer, this benchmark measures <a href="https://www.mozilla.org/en-US/about/webvision/full/#performance">what we think matters most</a> for performance online: responsiveness. But today’s release is more open and more challenging than before, and is the best tool for driving browser performance improvements that we’ve ever seen.</p>
<p>This fulfills the <a href="https://twitter.com/mozhacks/status/1603435347190419456">vision set out in December 2022</a> to bring experts across the industry together in order to rethink how we measure browser performance, guided by a shared goal to reflect the real-world Web as much as possible. This is the first time the Speedometer benchmark, or any major browser benchmark, has been developed through a cross-industry collaboration supported by each major browser engine: Blink, Gecko, and WebKit. Working together means we can build a shared understanding of what matters to optimize, and facilitates broad review of the benchmark itself: both of which make it a stronger lever for improving the Web as a whole.</p>
<p>And we’re seeing results: <a href="https://hacks.mozilla.org/2023/10/down-and-to-the-right-firefox-got-faster-for-real-users-in-2023/">Firefox got faster for real users in 2023</a> as a direct result of <a href="https://hacks.mozilla.org/2023/09/faster-vue-js-execution-in-firefox/">optimizing</a> <a href="https://spidermonkey.dev/blog/2023/11/27/newsletter-firefox-118-121.html">for</a> Speedometer 3. This took a coordinated effort from many teams: understanding real-world websites, building new tools to drive optimizations, and making a huge number of improvements inside Gecko to make web pages run more smoothly for Firefox users. In the process, we’ve shipped <a href="https://mzl.la/4bYLwtn">hundreds of bug fixes</a> across JS, DOM, Layout, CSS, Graphics, frontend, memory allocation, profile-guided optimization, and more.</p>
<p>We’re happy to see core optimizations in all the major browser engines turning into improved responsiveness for real users, and are looking forward to continuing to work together to build performance tests that improve the Web.</p>
<p>The post <a href="https://hacks.mozilla.org/2024/03/improving-performance-in-firefox-and-across-the-web-with-speedometer-3/">Improving Performance in Firefox and Across the Web with Speedometer 3</a> appeared first on <a href="https://hacks.mozilla.org">Mozilla Hacks - the Web developer blog</a>.</p>2024-03-11T16:00:36+00:00Brian GrinsteadMozilla Thunderbird: Thunderbird for Android / K-9 Mail: February 2024 Progress Report
https://blog.thunderbird.net/2024/03/thunderbird-for-android-k-9-mail-february-2024-progress-report/
<p><img alt="a dark background with Thunderbird and K-9 Mail logos centered, with the text "Thunderbird for Android, February 2024 Progress Report"" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2024/03/K9-February-2024-768x432.jpg" width="640" /></p>
<p>Welcome to a new report on the progress of transforming K-9 Mail into Thunderbird for Android. I hope you’ve enjoyed the <a href="https://en.wikipedia.org/wiki/Leap_year">extra day</a> in February. We certainly did and used this opportunity to release <a href="https://blog.thunderbird.net/2024/03/towards-thunderbird-for-android-k-9-mail-6-800-simplifies-adding-email-accounts/">a new stable version</a> on February 29.</p>
<p>If you’re new to this <a href="https://blog.thunderbird.net/category/thunderbird-mobile/">series</a> or the unusually long February made you forget what happened the previous month, you might want to check out <a href="https://blog.thunderbird.net/2024/02/thunderbird-for-android-k-9-mail-january-2024-progress-report/">January’s progress report</a>.</p>
<h3>New stable release</h3>
<p>We spent most of our time in February getting ready for a new stable release – K-9 Mail 6.800. That mostly meant fixing bugs and usability issues reported by beta testers. Thanks to everyone who tested the app and reported bugs <img alt="❤" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/2764.png" style="height: 1em;" /></p>
<p>Read all about the new release in our blog post <a href="https://blog.thunderbird.net/2024/03/towards-thunderbird-for-android-k-9-mail-6-800-simplifies-adding-email-accounts/">Towards Thunderbird for Android – K-9 Mail 6.800 Simplifies Adding Email Accounts</a>.</p>
<h3>What’s next?</h3>
<p>With the new account setup being mostly done, we’ll concentrate on the following two areas.</p>
<h4>Material 3</h4>
<p>The question of whether to update the user interface to match the design used by the latest Android version seems to have always split the K-9 Mail user base. One group prefers that we work on adding new features instead. The other group wants their email app of choice to look similar to the apps that ship with Android.</p>
<p>Never updating the user interface to the latest design is not really an option. At some point all third-party libraries we’re using will only support the latest platform design. Not updating those libraries is also not an option because Android itself is constantly changing and requires app/library updates just to keep existing functionality working.</p>
<p>I think we found a good balance by not being the first ones to update to <a href="https://m3.material.io/">Material 3</a>. By now a lot of other app developers have done so and countless bugs related to Material 3 have been found and fixed. So it’s a good time for us to start switching to Android’s latest design system now.</p>
<p>We’re currently still in a research phase to figure out what parts of the app need changing. Once that’s done, we’ll change the base theme and fix up the app screen by screen. You will be able to follow along by <a href="https://forum.k9mail.app/t/how-do-i-become-a-beta-tester/68">becoming a beta tester</a> and installing K-9 Mail 6.9xx beta versions once those become available.</p>
<h4>Android 14 compatibility</h4>
<p>K-9 Mail is affected by a couple of changes that were introduced with Android 14. We’ve started to look into which parts of the app need to be updated to be able to target Android 14.</p>
<p>We’ve already identified these:</p>
<ul>
<li><a href="https://developer.android.com/about/versions/14/changes/schedule-exact-alarms">Schedule exact alarms are denied by default</a> – For some reason Google decided to also apply this change to apps targeting Android 13. We already mentioned this in our <a href="https://blog.thunderbird.net/2023/12/thunderbird-for-android-k-9-mail-november-december-2023-progress-report/">November/December 2023 progress report</a> in the section “Push Not Working On Android 14”.</li>
<li><a href="https://developer.android.com/about/versions/14/behavior-changes-14#safer-intents">Restrictions to implicit and pending intents</a> – This affects the way we communicate with the crypto provider app (<a href="https://www.openkeychain.org/">OpenKeychain</a>) when using OpenPGP.</li>
</ul>
<p>Our current plan is to include the necessary changes in updates to the K-9 Mail 6.8xx line.</p>
<h3>Community Contributions</h3>
<ul>
<li><a href="https://github.com/tanoDxyz">S Tanveer Hussain</a> submitted a pull request to update the information about third-party libraries in K-9 Mail’s <em>About</em> screen (<a href="https://github.com/thunderbird/thunderbird-android/pull/7601">#7601</a>)</li>
<li>GitHub user <a href="https://github.com/LorenzHo">LorenzHo</a> provided a patch to not focus the recipient input field when the <em>Compose</em> screen was opened using a mailto: URI (<a href="https://github.com/thunderbird/thunderbird-android/pull/7623">#7623</a>). Unfortunately, this change had to be backed out later because of unintended side effects. But we’re hopeful a modified version of this change will make it into the app soon.</li>
</ul>
<p>Thank you for your contributions!</p>
<h3>Releases</h3>
<p>In February 2024 we published a new stable release:</p>
<ul>
<li><a href="https://github.com/thunderbird/thunderbird-android/releases/tag/6.800">K-9 Mail v6.800</a> (2024-02-29)</li>
</ul>
<p>… and the following beta versions:</p>
<ul>
<li><a href="https://github.com/thunderbird/thunderbird-android/releases/tag/6.715">K-9 Mail v6.715 (beta)</a> (2024-02-01)</li>
<li><a href="https://github.com/thunderbird/thunderbird-android/releases/tag/6.716">K-9 Mail v6.716 (beta)</a> (2024-02-13)</li>
<li><a href="https://github.com/thunderbird/thunderbird-android/releases/tag/6.717">K-9 Mail v6.717 (beta)</a> (2024-02-16)</li>
</ul>
<p>The post <a href="https://blog.thunderbird.net/2024/03/thunderbird-for-android-k-9-mail-february-2024-progress-report/">Thunderbird for Android / K-9 Mail: February 2024 Progress Report</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p>2024-03-11T13:00:00+00:00ckettiAdrian Gaudebert: Killing two birds with one deck in Dawnmaker
http://adrian.gaudebert.fr/blog/post/Killing-two-birds-with-one-deck-in-Dawnmaker
<p>Let's face it: Dawnmaker still has some important flaws. We're aware of that, and we are working on those flaws. One of the biggest remaining problem with the game was that one of its core mechanics, the oppression of the Smog, was… well, not explained at all. If you didn't have a developer behind your back to tell you, there was almost no way you could understand it.</p> <p>What's the oppression of the Smog, you ask? It is the fact that the Smog gets stronger the more the game progresses, and thus makes you consume luminoil faster. It's a simple formula that grows every time you shuffle your deck of cards: when that happens, your luminoil consumption increases by the level of your aerostation. We tried a few, small things to explain that mechanism: we added an animation to the Smog, making it grow darker and closer to your city, when the oppression increases. We also had a line in the luminoil tooltip showing how much luminoil is consumed by this oppression. But that was not nearly enough, and I started thinking about how to solve this with a complex UI inspired by Frostpunk. I am glad I did not go with that, as it would have been a nightmare to implement, and I now believe it would not have helped much.</p>
<figure style="margin: 0 auto; display: table;"><img alt="An attempt at explaining the Smog's oppression in Dawnmaker" class="media" src="http://adrian.gaudebert.fr/blog/public/icones-billets/dawnmaker-oppression-ui-fail.jpg" />
<figcaption>
<p style="text-align: center;"><em>I sure am glad I did not try to implement this…</em></p>
</figcaption>
</figure>
<p>So, while I was busy not solving this problem, another one got to the front: the progression issue. You see, we have been struggling a lot with the meta progression we offer in Dawnmaker. We've made attempts at doing it Slay the Spire-like, with a map of limited paths and rewards after each stop. That doesn't work very well, the roguelike structure (the progression on the world map) around an already roguelike structure (a single region / city) was weird and sometimes frustrating. So we started thinking about doing it differently, more like Hades does it with its mirror. There would be a new resource that you'd gain after securing each region, and that resource could be spent in order to improve your starting party, making each new region a tad easier to secure.</p>
<p>We like this idea, but it causes another problem: if the game gets easier and easier, there will come a point when it will become boring, as the challenge will be lost. We thus need to have a progression in the difficulty just as we have one in the player's strength. Hades does that with the Heat system, where you can choose how you increase the challenge each time you play. We cannot easily do something similar, so I once again started thinking about a complex question: how can we increase the difficulty of the game? What levers to we have to do that in a way that is challenging and doesn't feel too artificial or frustrating? There's an easy answer to that: the length of the game and the number of lighthouses, which we use in the currently called "Discovery" game, where we increase both the level to reach and the number of lighthouses to repair in order to win a game as you progress on the map. But that is not enough for a long-term progression, as it would quickly feel completely artificial. Luckily, there was another feature we could use, and did not: the oppression of the Smog. That is were those two problems converged, and led me to a single solution solving both: turning the Smog's behavior into a deck of cards.</p>
<p><img alt="Current representation of the Smog's behavior in Dawnmaker" class="media" src="http://adrian.gaudebert.fr/blog/public/icones-billets/dawnmaker-smog-deck.jpg" style="float: right; margin: 0 0 1em 1em;" /></p>
<p>Using cards to represent the Smog's behavior increases the affordance of the game: Smog cards look like buildings cards, and they sort of work like them. It's a card that has an effect, that you can read at any time, and because it uses the same wording, abilities and display as the buildings, it's easy to interpret it. Changing the behavior simply means changing the card, and we can do a whole bunch of animations there to show that happening. We can also add tooltips around those elements to explain them further. That's a first big win! Now the second one is that we create and handle those decks in our content editor, and we can create as many cards and decks as we want. There we have it: near infinite difficulty progression, simply by making different Smog cards, and assembling them differently in various decks!</p>
<p>Note that we haven't done anything like that yet. So far we have only reproduced the previous system with cards. But the potential is here: when we start working on the meta progression, we can be confident that we'll have the tools to make the difficulty progress as well.</p>
<p>We definitely killed two nasty, vicious flying creatures with one deck. Neat!</p>
<hr />
<p>This piece was initially sent out to the readers of our newsletter. Wanna join in on the fun? Head out to <a href="https://arpentor.studio/games/dawnmaker/" hreflang="en">Dawnmaker's presentation page</a> and fill the form. You'll receive regular stories about how we're making this game, the latest news of its development, as well as an exclusive access to Dawnmaker's alpha version!</p>
<p style="text-align: center;"><a href="https://arpentor.studio/games/dawnmaker/" hreflang="en" style="display: inline-block; border-radius: 1em; background-color: #C8D6AF; padding: 1em 2em; font-weight: bold; font-size: 1.1em;">Join our community!</a></p>2024-03-11T10:02:06+00:00AdrianThe Rust Programming Language Blog: Announcing Rustup 1.27.0
https://blog.rust-lang.org/2024/03/11/Rustup-1.27.0.html
<p>The rustup team is happy to announce the release of rustup version 1.27.0.
<a href="https://rustup.rs">Rustup</a> is the recommended tool to install <a href="https://www.rust-lang.org">Rust</a>, a programming language that is empowering everyone to build reliable and efficient software.</p>
<p>If you have a previous version of rustup installed, getting rustup 1.27.0 is as easy as stopping any programs which may be using Rustup (e.g. closing your IDE) and running:</p>
<pre><code class="language-console">$ rustup self update
</code></pre>
<p>Rustup will also automatically update itself at the end of a normal toolchain update:</p>
<pre><code class="language-console">$ rustup update
</code></pre>
<p>If you don't have it already, you can <a href="https://rustup.rs">get rustup</a> from the appropriate page on our website.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/03/11/Rustup-1.27.0.html#whats-new-in-rustup-1270" id="whats-new-in-rustup-1270"></a>What's new in rustup 1.27.0</h3>
<p>This long-awaited Rustup release has gathered all the new features and fixes since April 2023. These changes include improvements in Rustup's maintainability, user experience, compatibility and documentation quality.</p>
<p>Also, it's worth mentioning that Dirkjan Ochtman (djc) and rami3l (rami3l) have joined the team and are coordinating this new release.</p>
<p>At the same time, we have granted Daniel Silverstone (kinnison) and <span lang="zh">二手掉包工程师</span> (hi-rustin) their well-deserved alumni status in this release cycle.
Kudos for your contributions over the years and your continuous guidance on maintaining the project!</p>
<p>The headlines for this release are:</p>
<ol>
<li>
<p>Basic support for the fish shell has been added.
If you're using <code>fish</code>, PATH configs for your Rustup installation will be added automatically from now on.</p>
<p><em>Please note that this will only take effect on installation, so if you have already installed Rustup on your machine, you will need to reinstall it.
For example, if you have installed Rustup via <a href="https://rustup.rs">rustup.rs</a>, simply follow <a href="https://rustup.rs">rustup.rs</a>'s instructions again;
if you have installed Rustup using <a href="https://rust-lang.github.io/rustup/installation/other.html">some other method</a>, you might want to reinstall it using that same method.</em></p>
</li>
<li>
<p>Rustup support for <code>loongarch64-unknown-linux-gnu</code> as a <em>host platform</em> has been added.
This means you should be able to install Rustup via <a href="https://rustup.rs">rustup.rs</a> and no longer have to rely on <a href="https://rust-lang.loongnix.cn">loongnix.cn</a> or self-compiled installations.</p>
<p><em>Please note that as of March 2024, <code>loongarch64-unknown-linux-gnu</code> is a <a href="https://doc.rust-lang.org/nightly/rustc/platform-support.html#tier-2-with-host-tools">"tier 2 platform with host tools"</a>, so Rustup is guaranteed to build for this platform.
According to Rust's <a href="https://doc.rust-lang.org/nightly/rustc/target-tier-policy.html">target tier policy</a>, this does not imply that these builds are also guaranteed to work, but they often work to quite a good degree and patches are always welcome!</em></p>
</li>
</ol>
<p>Full details are available in the <a href="https://github.com/rust-lang/rustup/blob/stable/CHANGELOG.md">changelog</a>!</p>
<p>Rustup's documentation is also available in <a href="https://rust-lang.github.io/rustup/">the rustup book</a>.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/03/11/Rustup-1.27.0.html#thanks" id="thanks"></a>Thanks</h3>
<p>Thanks again to all the contributors who made rustup 1.27.0 possible!</p>
<ul>
<li>Anthony Perkins (acperkins)</li>
<li>Tianqi (airstone42)</li>
<li>Alex Gaynor (alex)</li>
<li>Alex Hudspith (alexhudspith)</li>
<li>Alan Somers (asomers)</li>
<li>Brett (brettearle)</li>
<li>Burak Emir (burakemir)</li>
<li>Chris Denton (ChrisDenton)</li>
<li>cui fliter (cuishuang)</li>
<li>Dirkjan Ochtman (djc)</li>
<li>Dezhi Wu (dzvon)</li>
<li>Eric Swanson (ericswanson-dfinity)</li>
<li>Prikshit Gautam (gautamprikshit1)</li>
<li>hev (heiher)</li>
<li><span lang="zh">二手掉包工程师</span> (hi-rustin)</li>
<li>Kamila Borowska (KamilaBorowska)</li>
<li>klensy (klensy)</li>
<li>Jakub Beránek (Kobzol)</li>
<li>Kornel (kornelski)</li>
<li>Matt Harding (majaha)</li>
<li>Mathias Brossard (mbrossard)</li>
<li>Christian Thackston (nan60)</li>
<li>Ruohui Wang (noirgif)</li>
<li>Olivier Lemasle (olivierlemasle)</li>
<li>Chih Wang (ongchi)</li>
<li>Pavel Roskin (proski)</li>
<li>rami3l (rami3l)</li>
<li>Robert Collins (rbtcollins)</li>
<li>Sandesh Pyakurel (Sandesh-Pyakurel)</li>
<li>Waffle Maybe (WaffleLapkin)</li>
<li>Jubilee (workingjubilee)</li>
<li>WÁNG Xuěruì (xen0n)</li>
<li>Yerkebulan Tulibergenov (yerke)</li>
<li>Renovate Bot (renovate)</li>
</ul>2024-03-11T00:00:01+00:00The Rustup TeamThe Rust Programming Language Blog: crates.io: Download changes
https://blog.rust-lang.org/2024/03/11/crates-io-download-changes.html
<p>Like the rest of the Rust community, <a href="https://crates.io">crates.io</a> has been growing rapidly, with download and package counts increasing 2-3x year-on-year. This growth doesn't come without problems, and we have made some changes to download handling on crates.io to ensure we can keep providing crates for a long time to come.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/03/11/crates-io-download-changes.html#the-problem" id="the-problem"></a>The Problem</h3>
<p>This growth has brought with it some challenges. The most significant of these is that all download requests currently go through the crates.io API, occasionally causing scaling issues. If the API is down or slow, it affects all download requests too. In fact, the number one cause of waking up our crates.io on-call team is "slow downloads" due to the API having performance issues.</p>
<p>Additionally, this setup is also problematic for users outside of North America, where download requests are slow due to the distance to the crates.io API servers.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/03/11/crates-io-download-changes.html#the-solution" id="the-solution"></a>The Solution</h3>
<p>To address these issues, over the last year we have decided to make some changes:</p>
<p><strong>Starting from 2024-03-12, <code>cargo</code> will begin to download crates directly from our static.crates.io <a href="https://en.wikipedia.org/wiki/Content_delivery_network">CDN</a> servers.</strong></p>
<p>This change will be facilitated by modifying the <a href="https://github.com/rust-lang/crates.io-index/blob/master/config.json"><code>config.json</code></a> file on the package index. In other words: no changes to <code>cargo</code> or your own system are needed for the changes to take effect. The <code>config.json</code> file is used by <code>cargo</code> to determine the download URLs for crates, and we will update it to point directly to the CDN servers, instead of the crates.io API.</p>
<p>Over the past few months, we have made several changes to the crates.io backend to enable this:</p>
<ul>
<li>
<p>We <a href="https://blog.rust-lang.org/2023/10/27/crates-io-non-canonical-downloads.html">announced the deprecation of "non-canonical" downloads</a>, which would be harder to support when downloading directly from the CDN.</p>
</li>
<li>
<p>We changed how downloads are counted. Previously, downloads were counted directly on the crates.io API servers. Now, we analyze the log files from the CDN servers to count the download requests.</p>
</li>
</ul>
<p><img alt="crates.io download graph of an arbitrary crate showing that on 2024-02-16, download numbers increased" src="https://blog.rust-lang.org/images/2024-03-11-crates-io-download-changes/download-graph.png" /></p>
<p>The latter change has caused the download numbers of most crates to increase, as some download requests were not counted before. Specifically, crates.io mirrors were often downloading directly from the CDN servers already, and those downloads had previously not been counted. For crates with a lot of downloads these changes will be barely noticeable, but for smaller crates, the download numbers have increased quite a bit over the past few weeks since we enabled this change.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/03/11/crates-io-download-changes.html#expected-outcomes" id="expected-outcomes"></a>Expected Outcomes</h3>
<p>We expect these changes to significantly improve the reliability and speed of downloads, as the performance of the crates.io API servers will no longer affect the download requests. Over the next few weeks, we will monitor the performance of the system to ensure that the changes have the expected effects.</p>
<p>We have noticed that some non-cargo build systems are not using the <code>config.json</code> file of the index to build the download URLs. We will reach out to the maintainers of those build systems to ensure that they are aware of the change and to help them update their systems to use the new download URLs. The old download URLs will continue to work, but these systems will be missing out on the potential performance improvement.</p>
<p>We are excited about these changes and believe they will greatly improve the reliability of crates.io. We look forward to hearing your feedback!</p>2024-03-11T00:00:00+00:00Tobias BieniekThe Mozilla Blog: Evaluating LLM models at scale
https://blog.mozilla.org/en/mozilla/ai/evaluating-llm-models-at-scale/
<p><em>(To read the complete Mozilla.ai learnings on LLM evaluation, please visit the <a href="https://blog.mozilla.ai/exploring-llm-evaluation-at-scale-with-the-neurips-large-language-model-efficiency-challenge/" rel="noreferrer noopener" target="_blank">Mozilla.ai blog</a>)</em></p>
<p>Large language models (LLMs) have rapidly advanced, but determining their real-world performance remains a complex challenge in AI. <a href="https://www.mozilla.ai/">Mozilla.ai</a> participated in <a href="https://neurips.cc/">NeurIPS 2023</a>, one of the most prominent machine learning conferences, by co-sponsoring a <a href="https://llm-efficiency-challenge.github.io/challenge.html">challenge</a> designed to address evaluating models by focusing on efficient fine-tuning of LLMs and developing robust evaluation techniques. </p>
<p>The competition emphasized fine-tuning LLMs under precise hardware constraints. Fine-tuning involves updating specific parts of an existing LLM with curated datasets to specialize its behavior. The goal was to fine-tune models within 24 hours on a single GPU, making this process more accessible to those without access to high-performance computational clusters.</p>
<p>Mozilla.ai played a key role in evaluating the results of these fine-tuning experiments. We used tools like HELM, a framework developed at Stanford for running various tasks to assess LLM performance. However, evaluating LLMs is hard due to the stochastic nature of the responses of <a href="https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture)">transformer models</a>: a model can give different answers every time it is provided with a given prompt and there are many ways to measure these responses. This complexity makes it challenging to compare models objectively and decide which models are truly “best”.</p>
<p>The competition highlighted the rapidly evolving nature of LLMs. New models, fine-tuning techniques, and evaluation methods are being constantly introduced so reliable and standardized evaluation of LLMs will be crucial for understanding their capabilities and ensuring they are <a href="https://foundation.mozilla.org/en/research/library/accelerating-progress-toward-trustworthy-ai/whitepaper/">trustworthy</a>.</p>
<p>Open source plays a big role in this area <em>because</em> evaluation is such a multifaceted problem. Being able to work in a collaborative manner and with open-source systems is crucial for moving forward toward a better framework that could eventually be used in the field by many people.</p>
<p>At <a href="https://www.mozilla.ai/">Mozilla.ai</a> we believe in the importance of establishing robust and transparent foundations for the entire evaluation landscape. This is why we are working on several tracks of work to support this. On the experimentation side, we are focused on research approaches that allow for a clear definition of metrics and transparency and run repeatable evaluations. On the infrastructure side, we’re developing reliable and replicable infrastructure to evaluate models and store and introspect model results.</p>
<p><br />Read the whole set of learnings in the <a href="https://blog.mozilla.ai/exploring-llm-evaluation-at-scale-with-the-neurips-large-language-model-efficiency-challenge/">Mozilla.ai blog</a>.</p>
<p>The post <a href="https://blog.mozilla.org/en/mozilla/ai/evaluating-llm-models-at-scale/">Evaluating LLM models at scale</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-03-07T15:00:00+00:00MozillaThe Mozilla Blog: Introducing the Columbia Convening on Openness and AI
https://blog.mozilla.org/en/mozilla/ai/introducing-columbia-convening-openness-and-ai/
<h3 class="wp-block-heading"><em>We brought together experts to tackle a critical question: What does openness mean for AI, and how can it best enable trustworthy and beneficial AI?</em></h3>
<figure class="wp-block-image size-large"><img alt="Group photo of the participants at The Columbia Convening on Openness and AI in February" class="wp-image-74387" height="616" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2024/03/conveningai_graylock4824_1_-1024x616.jpg" width="1024" /><figcaption class="wp-element-caption">Participants in the Columbia Convening on Openness and AI.</figcaption></figure>
<p>On February 29, Mozilla and the Columbia Institute of Global Politics brought together over 40 leading scholars and practitioners working on openness and AI. These individuals — spanning prominent open source AI startups and companies, non-profit AI labs, and civil society organizations — focused on exploring what “open” should mean in the AI era. Open source software helped make the internet safer and more robust in earlier eras of the internet — and offered trillions of dollars of value to startups and innovators as they created the digital services we all use today. Our shared hope is that open approaches can have a similar impact in the AI era.</p>
<p>To help unlock this significant potential, the Columbia Convening took an important step toward developing a framework for openness in AI and unifying the openness community around shared understandings and next steps. Participatants noted that: </p>
<ul>
<li>Openness in AI has the potential to advance key societal goals, including making AI safe and effective, unlocking innovation and competition in the AI market, and bringing underserved communities into the AI ecosystem.</li>
<li>Openness is a key characteristic to consider throughout the AI stack, and not just in AI models themselves. In components ranging from data to hardware to user interfaces, there are different types of openness that can be helpful for accomplishing different technical and societal goals. Participants reviewed research mapping dimensions of openness in AI, and noted the need to make it easier for developers of AI systems to understand where and how openness should be central to the technology they build.</li>
<li>Policy conversations need to be more thoughtful about the benefits and risks of openness in AI. For example, comparing the <a href="https://crfm.stanford.edu/open-fms/paper.pdf">marginal risk</a> that open systems pose in relation to closed systems is one promising approach to bringing rigor to this discussion. More work is needed across the board — from policy research on liability distribution, to more submissions to the National Telecommunications and Information Administration’s <a href="https://www.ntia.gov/federal-register-notice/2024/dual-use-foundation-artificial-intelligence-models-widely-available">request for comment</a> on “dual-use foundation models with widely available model weights.”</li>
<li>We need a stronger community and better organization to help build, invest, and advocate for better approaches to openness in AI. This convening showed that the openness community can have collaborative, productive discussions even when there are meaningful differences of opinion between its members. Mozilla committed to continuing to help build and foster community on this topic.</li>
</ul>
<p>Getting “open” right for AI will be hard — but it’s never been more timely or important. Today, while everyone gushes about how generative AI can change the world, only a handful of products dominate the generative AI market. The lack of competition in AI products today is a real problem. It could mean that the new AI products we’ll begin to see in the next several years won’t be as innovative and safe as we need them to be – but instead, be built on the same closed, proprietary model that has defined roughly the last decade of online life. That’s why Mozilla’s recent report on <a href="https://foundation.mozilla.org/en/research/library/accelerating-progress-toward-trustworthy-ai/"><em>Accelerating Progress Toward Trustworthy AI</em></a> doubles down on openness, competition, and accountability as vital to the future of AI.</p>
<p>We know a better future is possible<em>. </em>During earlier eras of the Internet, open source technologies played a <a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4693148">core role</a> in promoting innovation and safety. Open source software made it easier to find and fix bugs in software. Attempts to limit open innovation — such as export controls on encryption in early web browsers — ended up being counterproductive, further exemplifying the value of openness. And, perhaps most importantly, open source technology has provided a core set of building blocks that software developers have used to do everything from create art to design vaccines to develop apps that are used by people all over the world; it is <a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4693148">estimated</a> that open source software is worth over $8 trillion in value. </p>
<p>For years, we saw similar benefits play out for AI. Industry researchers openly published foundational AI <a href="https://papers.nips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf">research</a> and <a href="https://papers.nips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf">frameworks</a>, making it easier for academics and startups to keep pace with AI advances and enabling an ecosystem of external experts who could challenge the big AI players. But, the benefits of this approach are not assured as we enter a new wave of innovation around AI. As training AI systems requires more compute and data, some key players are shifting their attention away from publishing research and toward consolidating competitive advantages and economies of scale to enable foundational models on demand. As AI risks are being portrayed as murkier and more hypothetical, it is becoming easier to argue that locking down AI models is the safest path forward. Today, it feels like the benefits and risks of AI depend on the <a href="https://www.fastcompany.com/90992180/this-is-the-right-lesson-to-take-from-the-openai-debacle">whims of a few tech companies</a> in Silicon Valley.</p>
<p>This can’t be the best approach to AI. If AI is truly so powerful and pervasive, shouldn’t AI be subject to real scrutiny from third-party assessments? If AI is truly so innovative and useful, shouldn’t there be more AI tools and systems that startups and small businesses can use?</p>
<p>We believe openness can and must play a key role in the future of AI — the question is how. Late last year, we and over 1,800 people signed our<a href="https://open.mozilla.org/letter/"> letter</a> that noted that although the signatories represent different perspectives on open source AI, they all agree that open, responsible, and transparent approaches are critical to safety and security in the AI era. Indeed, across the AI ecosystem, some advocate for staged release of AI models, others believe other forms of openness in the AI stack are more important, and yet others believe every part of AI systems should be as open as possible. There are people who believe in openness for openness’ sake, and others who view openness as a means to other societal goals — such as identifying civil rights and privacy harms, promoting innovation and competition in the market, and supporting consumers and workers who want a say about how AI is deployed in their communities. We were thrilled to bring together people with very divergent views and motivations for openness collaborating on strengthening and leveraging openness in support of their missions.</p>
<p>We’re immensely grateful to the participants in the Columbia Convening on Openness and AI:</p>
<ul>
<li><strong>Anthony Annunziata</strong> — Head of AI Open Innovation and AI Alliance, IBM</li>
<li><strong>Mitchell Baker</strong>— Chairwoman, Mozilla Foundation</li>
<li><strong>Kevin Bankston</strong> — Senior Advisor on AI Governance, Center for Democracy and Technology</li>
<li><strong>Adrien Basdevant</strong> — Tech Lawyer, Entropy Law</li>
<li><strong>Ayah Bdeir</strong> — Senior Advisor, Mozilla</li>
<li><strong>Philippe Beaudoin</strong> — Co-Founder and CEO, Waverly</li>
<li><strong>Brian Behlendorf</strong> — Chief AI Strategist, The Linux Foundation</li>
<li><strong>Stella Biderman</strong> — Executive Director, EleutherAI</li>
<li><strong>John Borthwick</strong> — CEO, Betaworks</li>
<li><strong>Zoë Brammer</strong> — Senior Associate for Cybersecurity & Emerging Technologies, Institute for Security and Technology</li>
<li><strong>Glenn Brown</strong> — Principal, GOB Advisory</li>
<li><strong>Kasia Chmielinski</strong> — Practitioner Fellow, Stanford Center on Philanthropy and Civil Society</li>
<li><strong>Peter Cihon</strong> — Senior Policy Manager, Github</li>
<li><strong>Julia Rhodes Davis</strong> — Chief Program Officer, Computer Says Maybe</li>
<li><strong>Merouane Debbah</strong> — Senior Scientific AI Advisor, Technology Innovation Institute</li>
<li><strong>Alix Dunn</strong> — Facilitator, Computer Says Maybe</li>
<li><strong>Michelle Fang </strong>— Strategy, Cerebras Systems</li>
<li><strong>Camille François</strong> — Faculty Affiliate, Institute for Global Politics at Columbia University’s School of Public and International Affairs</li>
<li><strong>Stefan French</strong> — Product Manager, Mozilla.ai</li>
<li><strong>Yacine Jernite</strong> — Machine Learning and Society Lead, Hugging Face</li>
<li><strong>Amba Kak</strong> — Executive Director, AI Now Institute</li>
<li><strong>Sayash Kapoor</strong> — Ph.D. Candidate, Princeton University</li>
<li><strong>Helen King-Turvey</strong> — Managing Partner, Philanthropy Matters</li>
<li><strong>Kevin Klyman</strong> — AI Policy Researcher, Stanford Institute for Human-Centered AI</li>
<li><strong>Nathan Lambert</strong> — ML Scientist, Allen Institute for AI </li>
<li><strong>Yann LeCun</strong> — Vice President and Chief AI Scientist, Meta</li>
<li><strong>Stefano Maffulli</strong> — Executive Director, Open Source Initiative</li>
<li><strong>Nik Marda</strong> — Technical Lead, AI Governance, Mozilla</li>
<li><strong>Ryan Merkley</strong> — CEO, Conscience</li>
<li><strong>Mohamed Nanabhay</strong> — Managing Partner, Mozilla Ventures</li>
<li><strong>Deval Pandya</strong> — Vice President of AI Engineering, Vector Institute</li>
<li><strong>Deb Raji</strong> — Fellow at Mozilla and PhD Student, UC Berkeley</li>
<li><strong>Govind Shivkumar</strong> — Director, Investments, Omidyar Network </li>
<li><strong>Aviya Skowron</strong> — Head of Policy and Ethics, EleutherAI</li>
<li><strong>Irene</strong> <strong>Solaiman</strong> — Head of Global Policy, HuggingFace</li>
<li><strong>Madhulika Srikumar</strong>, Lead for Safety Critical AI, Partnership on AI</li>
<li><strong>Victor Storchan</strong> — Lead AI/ ML Research at Mozilla.ai</li>
<li><strong>Mark Surman</strong> — President, Mozilla Foundation</li>
<li><strong>Nabiha Syed</strong> — CEO, The Markup</li>
<li><strong>Martin Tisne</strong> — CEO, AI Collaborative, The Omidyar Group</li>
<li><strong>Udbhav Tiwari</strong>, Head of Global Product Policy, Mozilla</li>
<li><strong>Justine Tunney</strong> — Founder, Mozilla’s LLaMAfile project</li>
<li><strong>Imo Udom</strong> — SVP of Innovation, Mozilla</li>
<li><strong>Sarah Myers West</strong> — Managing Director, AI Now Institute</li>
</ul>
<p>In the coming weeks, we intend to publish more content related to the convening. We will release resources to help practitioners and policymakers grapple with the opportunities and risks from openness in AI, such as determining how openness can help make AI systems safer and better. We will also continue to bring similar communities together, helping to keep pushing forward on this important work.</p>
<p>The post <a href="https://blog.mozilla.org/en/mozilla/ai/introducing-columbia-convening-openness-and-ai/">Introducing the Columbia Convening on Openness and AI</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-03-06T16:00:00+00:00Rebecca SmithWladimir Palant: Numerous vulnerabilities in Xunlei Accelerator application
https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/
<p>Xunlei Accelerator (迅雷客户端) a.k.a. Xunlei Thunder by the China-based Xunlei Ltd. is a wildly popular application. According to the <a href="https://ir.xunlei.com/static-files/3100b981-4a23-460b-8342-a0446ffff2c4">company’s annual report</a> 51.1 million active users were counted in December 2022. The company’s Google Chrome extension 迅雷下载支持, while not mandatory for using the application, had 28 million users at the time of writing.</p>
<figure><img alt="Screenshot of the application’s main window with Chinese text and two advertising blocks" class="article-image" height="393" src="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/screenshot.png" width="577" /></figure>
<p>I’ve found this application to expose a massive attack surface. This attack surface is largely accessible to arbitrary websites that an application user happens to be visiting. Some of it can also be accessed from other computers in the same network or by attackers with the ability to intercept user’s network connections (<a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">Man-in-the-Middle attack</a>).</p>
<p>It does not appear like security concerns were considered in the design of this application. Extensive internal interfaces were exposed without adequate protection. Some existing security mechanisms were disabled. The application also contains large amounts of third-party code which didn’t appear to receive any security updates whatsoever.</p>
<p>I’ve reported a number of vulnerabilities to Xunlei, most of which allowed remote code execution. Still, given the size of the attack surface it felt like I barely scratched the surface.</p>
<p>Last time Xunlei made security news, it was due to distributing a malicious software component. Back then <a href="https://news.softpedia.com/news/Company-Admits-Its-Employees-Bundled-Malware-with-Xunlei-Download-Manager-390840.shtml">it was an inside job</a>, some employees turned rouge. However, the application’s flaws allowed the same effect to be easily achieved from any website a user of the application happened to be visiting.</p>
<div id="tocBox">
<h5>Contents</h5>
<nav id="TableOfContents">
<ul>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#what-is-xunlei-accelerator">What is Xunlei Accelerator?</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-built-in-web-browser">The built-in web browser</a>
<ul>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-trouble-with-custom-chromium-based-browsers">The trouble with custom Chromium-based browsers</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#protections-disabled">Protections disabled</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#censorship-included">Censorship included</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#native-api">Native API</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#getting-into-the-xunlei-browser">Getting into the Xunlei browser</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-fixes">The fixes</a></li>
</ul>
</li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-main-application">The main application</a>
<ul>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#outdated-electron-framework">Outdated Electron framework</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#cross-site-scripting-vulnerabilities">Cross-site scripting vulnerabilities</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#impact-of-executing-arbitrary-code-in-the-renderer-process">Impact of executing arbitrary code in the renderer process</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-lack-of-fixes">The (lack of) fixes</a></li>
</ul>
</li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-xllite-application">The XLLite application</a>
<ul>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#overview-of-the-application">Overview of the application</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-pan-authentication">The “pan authentication”</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#achieving-code-execution-via-plugin-installation">Achieving code execution via plugin installation</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-fixes-1">The fixes</a></li>
</ul>
</li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#plugin-management">Plugin management</a>
<ul>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-oddities">The oddities</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#example-scenario-xlserviceplatform">Example scenario: XLServicePlatform</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#the-lack-of-fixes-1">The (lack of?) fixes</a></li>
</ul>
</li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#outdated-components">Outdated components</a></li>
<li><a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#reporting-the-issues">Reporting the issues</a></li>
</ul>
</nav>
</div>
<h3>What is Xunlei Accelerator?</h3>
<p>Wikipedia lists Xunlei Limited’s main product as a Bittorrent client, and maybe a decade ago it really was. Today however it’s rather difficult to describe what this application does. Is it a download manager? A web browser? A cloud storage service? A multimedia client? A gaming platform? It appears to be all of these things and more.</p>
<p>It’s probably easier to think of Xunlei as an advertising platform. It’s an application with the goal of maximizing profits through displaying advertising and selling subscriptions. As such, it needs to keep the users on the platform for as long as possible. That’s why it tries to implement every piece of functionality the user might need, while not being particularly good at any of it of course.</p>
<p>So there is a classic download manager that will hijack downloads initiated in the browser, with the promise of speeding them up. There is also a rudimentary web browser (two distinctly different web browsers in fact) so that you don’t need to go back to your regular web browser. You can play whatever you are downloading in the built-in media player, and you can upload it to the built-in storage. And did I mention games? Yes, there are games as well, just to keep you occupied.</p>
<p>Altogether this is a collection of numerous applications, built with a wide variety of different technologies, often implementing competing mechanisms for the same goal, yet trying hard to keep the outward appearance of a single application.</p>
<h3>The built-in web browser</h3>
<h4>The trouble with custom Chromium-based browsers</h4>
<p>Companies love bringing out their own web browsers. The reason is not that their browser is any better than the other 812 browsers already on the market. It’s rather that web browsers can monetize your searches (and, if you are less lucky, also your browsing history) which is a very profitable business.</p>
<p>Obviously, profits from that custom-made browser are higher if the company puts as little effort into maintenance as possible. So they take the open source Chromium, slap their branding on it, maybe also a few half-hearted features, and they call it a day.</p>
<p>Trouble is: a browser has a massive attack surface which is exposed to arbitrary web pages (and ad networks) by definition. Companies like Mozilla or Google invest enormous resources into quickly plugging vulnerabilities and bringing out updates every six weeks. And that custom Chromium-based browser also needs updates every six weeks, or it will expose users to known (and often widely exploited) vulnerabilities.</p>
<p>Even merely keeping up with Chromium development is tough, which is why it almost never happens. In fact, when I looked at the unnamed web browser built into the Xunlei application (internal name: TBC), it was based on Chromium 83.0.4103.106. Being released in May 2020, this particular browser version was already three and a half years old at that point. For reference: Google fixed eight actively exploited zero-day vulnerabilities in Chromium in the year 2023 alone.</p>
<p>Among others, the browser turned out to be vulnerable to CVE-2021-38003. There is <a href="https://medium.com/numen-cyber-labs/from-leaking-thehole-to-chrome-renderer-rce-183dcb6f3078">this article</a> which explains how this vulnerability allows JavaScript code on any website to gain read/write access to raw memory. I could reproduce this issue in the Xunlei browser.</p>
<h4>Protections disabled</h4>
<p>It is hard to tell whether not having a pop-up blocker in this browser was a deliberate choice or merely a consequence of the browser being so basic. Either way, websites are free to open as many tabs as they like. Adding <code>--autoplay-policy=no-user-gesture-required</code> command line flag definitely happened intentionally however, turning off video autoplay protections.</p>
<p>It’s also notable that Xunlei revives Flash Player in their browser. Flash Player support has been disabled in all browsers in December 2020, for various reasons including security. Xunlei didn’t merely decide to ignore this reasoning, they shipped Flash Player 29.0.0.140 (released in April 2018) with their browser. Adobe support website <a href="https://helpx.adobe.com/security/security-bulletin.html#flashplayer">lists numerous Flash Player security fixes</a> published after April 2018 and before end of support.</p>
<h4>Censorship included</h4>
<p>Interestingly, Xunlei browser won’t let users visit the <code>example.com</code> website (as opposed to <code>example.net</code>). When you try, the browser redirects you to a page on <code>static.xbase.cloud</code>. This is an asynchronous process, so chances are good that you will catch a glimpse of the original page first.</p>
<figure><img alt="Screenshot of a page showing a WiFi symbol with an overlaid question mark and some Chinese text." class="article-image" height="206" src="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/censorship.png" width="289" /></figure>
<p>Automated translation of the text: “This webpage contains illegal or illegal content and access has been stopped.”</p>
<p>As it turns out, the application will send every website you visit to an endpoint on <code>api-shoulei-ssl.xunlei.com</code>. That endpoint will either accept your choice of navigation target or instruct to redirect you to a different address. So when to navigate to <code>example.com</code> the following request will be sent:</p>
<pre tabindex="0"><code>POST /xlppc.blacklist.api/v1/check HTTP/1.1
Content-Length: 29
Content-Type: application/json
Host: api-shoulei-ssl.xunlei.com
{"url":"http://example.com/"}
</code></pre><p>And the server responds with:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"code"</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"msg"</span><span class="p">:</span> <span class="s2">"ok"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"data"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"host"</span><span class="p">:</span> <span class="s2">"example.com"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"redirect"</span><span class="p">:</span> <span class="s2">"https://static.xbase.cloud/file/2rvk4e3gkdnl7u1kl0k/xappnotfound/#/unreach"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"result"</span><span class="p">:</span> <span class="s2">"reject"</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Interestingly, giving it the address <code>http://example.com./</code> (note the trailing dot) will result in the response <code>{"code":403,"msg":"params error","data":null}</code>. With the endpoint being unable to handle this address, the browser will allow you to visit it.</p>
<h4>Native API</h4>
<p>In an interesting twist, the Xunlei browser exposed <code>window.native.CallNativeFunction()</code> method to all web pages. Calls would be forwarded to the main application where any plugin could register its native function handlers. When I checked, there were 179 such handlers registered, though that number might vary depending on the active plugins.</p>
<p>Among the functions exposed were <code>ShellOpen</code> (used Windows shell APIs to open a file), <code>QuerySqlite</code> (query database containing download tasks), <code>SetProxy</code> (configure a proxy server to be used for all downloads) or <code>GetRecentHistorys</code> (retrieve browsing history for the Xunlei browser).</p>
<p>My proof-of-concept exploit would run the following code:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-js"><span class="line"><span class="cl"><span class="kr">native</span><span class="p">.</span><span class="nx">CallNativeFunction</span><span class="p">(</span><span class="s2">"ShellOpen"</span><span class="p">,</span> <span class="s2">"c:\\windows\\system32\\calc.exe"</span><span class="p">);</span>
</span></span></code></pre></div><p>This would open the Windows Calculator, just as you’d expect.</p>
<p>Now this API was never meant to be exposed to all websites but only to a selected few very “trusted” ones. The allowlist here is:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-json"><span class="line"><span class="cl"><span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="s2">".xunlei.com"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"h5-pccloud.onethingpcs.com"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"h5-pccloud.test.onethingpcs.com"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"h5-pciaas.onethingpcs.com"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"h5-pccloud.onethingcloud.com"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"h5-pccloud-test.onethingcloud.com"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"h5-pcxl.hiveshared.com"</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span></code></pre></div><p>And here is how access was being validated:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">isUrlInDomains</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">allowlist</span><span class="p">,</span> <span class="nx">frameUrl</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">let</span> <span class="nx">result</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">index</span> <span class="o"><</span> <span class="nx">allowlist</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">url</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="nx">allowlist</span><span class="p">[</span><span class="nx">index</span><span class="p">])</span> <span class="o">||</span> <span class="nx">frameUrl</span> <span class="o">&&</span> <span class="nx">frameUrl</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="nx">allowlist</span><span class="p">[</span><span class="nx">index</span><span class="p">]))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">result</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As you might have noticed, this doesn’t actually validate the host name against the list but looks for substring matches in the entire address. So <code>https://malicious.com/?www.xunlei.com</code> is also considered a trusted address, allowing for a trivial circumvention of this “protection.”</p>
<h4>Getting into the Xunlei browser</h4>
<p>Now most users hopefully won’t use Xunlei for their regular browsing. These should be safe, right?</p>
<p>Unfortunately not, as there is a number of ways for webpages to open the Xunlei browser. The simplest way is using a special <code>thunderx://</code> address. For example, <code>thunderx://eyJvcHQiOiJ3ZWI6b3BlbiIsInBhcmFtcyI6eyJ1cmwiOiJodHRwczovL2V4YW1wbGUuY29tLyJ9fQ==</code> will open the Xunlei browser and load <code>https://example.com/</code> into it. From the attacker’s point of view, this approach has a downside however: modern browsers ask the user for confirmation before letting external applications handle addresses.</p>
<figure><img alt="Screenshot of a confirmation dialog titled “Open 迅雷?” The text says: “A website wants to open this application.” There are two buttons labeled “Open 迅雷” and “Cancel.”" class="article-image" height="141" src="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/confirmation.png" width="400" /></figure>
<p>There are alternatives however. For example, the Xunlei browser extension (28 million users according to Chrome Web Store) is meant to pass on downloads to the Xunlei application. It could be instrumented into passing on <code>thunderx://</code> links without any user interaction however, and these would immediately open arbitrary web pages in the Xunlei browser.</p>
<p>More ways to achieve this are exposed by the XLLite application’s API which is <a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#achieving-code-execution-via-plugin-installation">introduced later</a>. And that’s likely not even the end of it.</p>
<h4>The fixes</h4>
<p>While Xunlei never communicated any resolution of these issues to me, as of Xunlei Accelerator 12.0.8.2392 (built on February 2, 2024 judging by executable signatures) several changes have been implemented. First of all, the application no longer packages Flash Player. It still activates Flash Player if it is installed on the user’s system, so some users will still be exposed. But chances are good that this Flash Player installation will at least be current (as much as software can be “current” three years after being discontinued).</p>
<p>The <code>isUrlInDomains()</code> function has been rewritten, and the current logic appears reasonable. It will now only check the allowlist against the end of the hostname, matches elsewhere in the address won’t be accepted. So this now leaves “only” all of the xunlei.com domain with access to the application’s internal APIs. Any <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">cross-site scripting vulnerability</a> anywhere on this domain will again put users at risk.</p>
<p>The outdated Chromium base appears to remain unchanged. It still reports as Chromium 83.0.4103.106, and the exploit for CVE-2021-38003 still succeeds.</p>
<p>The browser extension 迅雷下载支持 also received an update, version 3.48 on January 3, 2024. According to automated translation, the changelog entry for this version reads: “Fixed some known issues.” The fix appears to be adding a bunch of checks for the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted">event.isTrusted property</a>, making sure that the extension can no longer be instrumented quite as easily. Given these restrictions, just opening the <code>thunderx://</code> address directly likely has higher chances of success now, especially when combined with social engineering.</p>
<h3>The main application</h3>
<h4>Outdated Electron framework</h4>
<p>The main Xunlei application is based on the <a href="https://en.wikipedia.org/wiki/Electron_(software_framework)">Electron framework</a>. This means that its user interface is written in HTML and displayed via the Chromium web browser (renderer process). And here again it’s somewhat of a concern that the Electron version used is 83.0.4103.122 (released in June 2020). It can be expected to share most of the security vulnerabilities with a similarly old Chromium browser.</p>
<p>Granted, an application like that should be less exposed than a web browser as it won’t just load any website. But it does work with remote websites, so vulnerabilities in the way it handles web content are an issue.</p>
<h4>Cross-site scripting vulnerabilities</h4>
<p>Being HTML-based, the Xunlei application is potentially vulnerable to <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">cross-site scripting vulnerabilities</a>. For most part, this is mitigrated by using the React framework. React doesn’t normally work with raw HTML code, so there is no potential for vulnerabilities here.</p>
<p>Well, normally. Unless <code>dangerouslySetInnerHTML</code> property is being used, which you should normally avoid. But it appears that Xunlei developers used this property in a few places, and now they have code displaying messages like this:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-js"><span class="line"><span class="cl"><span class="nx">$createElement</span><span class="p">(</span><span class="s2">"div"</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">staticClass</span><span class="o">:</span> <span class="s2">"xly-dialog-prompt__text"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">domProps</span><span class="o">:</span> <span class="p">{</span> <span class="nx">innerHTML</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">_s</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">content</span><span class="p">)</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p>If message content ever happens to be some malicious data, it could create HTML elements that will result in execution of arbitrary JavaScript code.</p>
<p>How would malicious data end up here? Easiest way would be <a href="https://palant.info/2024/03/06/numerous-vulnerabilities-in-xunlei-accelerator-application/#native-api">via the browser</a>. There is for example the <code>MessageBoxConfirm</code> native function that could be called like this:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-js"><span class="line"><span class="cl"><span class="kr">native</span><span class="p">.</span><span class="nx">CallNativeFunction</span><span class="p">(</span><span class="s2">"MessageBoxConfirm"</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">title</span><span class="o">:</span> <span class="s2">"Hi"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">content</span><span class="o">:</span> <span class="sb">`<img src="x" onerror="alert(location.href)">`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s2">"info"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">okText</span><span class="o">:</span> <span class="s2">"Ok"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cancelVisible</span><span class="o">:</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl"><span class="p">}));</span>
</span></span></code></pre></div><p>When executed on a “trusted” website in the Xunlei browser, this would make the main application display a message and, as a side-effect, run the JavaScript code <code>alert(location.href)</code>.</p>
<h4>Impact of executing arbitrary code in the renderer process</h4>
<p>Electron normally <a href="https://www.electronjs.org/docs/latest/tutorial/sandbox#renderer-processes">sandboxes renderer processes</a>, making certain that these have only limited privileges and vulnerabilities are harder to exploit. This security mechanism is active in the Xunlei application.</p>
<p>However, Xunlei developers at some point must have considered it rather limiting. After all, their user interface needed to perform lots of operations. And providing a restricted interface for each such operation was too much effort.</p>
<p>So they built a generic interface into the application. By means of messages like <code>AR_BROWSER_REQUIRE</code> or <code>AR_BROWSER_MEMBER_GET</code>, the renderer process can instruct the main (privileged) process of the application to do just about anything.</p>
<p>My proof-of-concept exploit successfully abused this interface by loading Electron’s <a href="https://www.electronjs.org/docs/latest/api/shell">shell module</a> (not accessible to sandboxed renderers by regular means) and calling one of its methods. In other words, the Xunlei application managed to render this security boundary completely useless.</p>
<h4>The (lack of) fixes</h4>
<p>Looking at Xunlei Accelerator 12.0.8.2392, I could not recognize any improvements in this area. The application is still based on Electron 83.0.4103.122. The number of potential XSS vulnerabilities in the message rendering code didn’t change either.</p>
<p>It appears that Xunlei called it a day after making certain that triggering messages with arbitrary content became more difficult. I doubt that it is impossible however.</p>
<h3>The XLLite application</h3>
<h4>Overview of the application</h4>
<p>The XLLite application is one of the plugins running within the Xunlei framework. Given that I never created a Xunlei account to see this application in action, my understanding of its intended functionality is limited. Its purpose however appears to be integrating the Xunlei cloud storage into the main application.</p>
<p>As it cannot modify the main application’s user interface directly, it exposes its own user interface as a local web server, on a randomly chosen port between 10500 and 10599. That server essentially provides static files embedded in the application, all functionality is implemented in client-side JavaScript.</p>
<p>Privileged operations are provided by a separate local server running on port 21603. Some of the API calls exposed here are handled by the application directly, others are forwarded to the main application via yet another local server.</p>
<p>I originally got confused about how the web interface accesses the API server, with the latter failing to implement <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a> correctly – <code>OPTION</code> requests don’t get a correct response, so that only basic requests succeed. It appears that Xunlei developers didn’t manage to resolve this issue and instead resorted to proxying the API server on the user interface server. So any endpoints available on the API server are exposed by the user interface server as well, here correctly (but seemingly unnecessarily) using CORS to allow access from everywhere.</p>
<p>So the communication works like this: the Xunlei application loads <code>http://127.0.0.1:105xx/</code> in a frame. The page then requests some API on its own port, e.g. <code>http://127.0.0.1:105xx/device/now</code>. When handling the request, the XLLite application requests <code>http://127.0.0.1:21603/device/now</code> internally. And the API server handler within the same process responds with the current timestamp.</p>
<p>This approach appears to make little sense. However, it’s my understanding that Xunlei also produces storage appliances which can be installed on the local network. Presumably, these appliances run identical code to expose an API server. This would also explain why the API server is exposed to the network rather than being a localhost-only server.</p>
<h4>The “pan authentication”</h4>
<p>With quite a few API calls having the potential to do serious damage or at the very least expose private information, these need to be protected somehow. As mentioned above, Xunlei developers chose not to use CORS to restrict access but rather decided to expose the API to all websites. Instead, they implemented their own “pan authentication” mechanism.</p>
<p>Their approach of generating authentication tokens was taking the current timestamp, concatenating it with a long static string (hardcoded in the application) and hashing the result with MD5. Such tokens would expire after 5 minutes, apparently an attempt to thwart replay attacks.</p>
<p>They even went as far as to perform time synchronization, making sure to correct for deviation between the current time as perceived by the web page (running on the user’s computer) and by the API server (running on the user’s computer). Again, this is something that probably makes sense if the API server can under some circumstances be running elsewhere on the network.</p>
<p>Needless to say that this “authentication” mechanism doesn’t provide any value beyond very basic obfuscation.</p>
<h4>Achieving code execution via plugin installation</h4>
<p>There are quite a few interesting API calls exposed here. For example, the <code>device/v1/xllite/sign</code> endpoint would sign data with one out of three private RSA keys hardcoded in the application. I don’t know what this functionality is used for, but I sincerely hope that it’s as far away from security and privacy topics as somehow possible.</p>
<p>There is also the <code>device/v1/call</code> endpoint which is yet another way to open a page in the Xunlei browser. Both <code>OnThunderxOpt</code> and <code>OpenNewTab</code> calls allow that, the former taking a <code>thunderx://</code> address to be processed and the latter a raw page address to be opened in the browser.</p>
<p>It’s fairly obvious that the API exposes full access to the user’s cloud storage. I chose to focus my attention on the <code>drive/v1/app/install</code> endpoint however, which looked like it could do even more damage. This endpoint in fact turned out to be a way to install binary plugins.</p>
<p>I couldn’t find any security mechanisms preventing malicious software to be installed this way, apart from the already mentioned useless “pan authentication.” However, I couldn’t find any actual plugins to use as an example. In the end I figured out that a plugin had to be packaged in an archive containing a <code>manifest.yaml</code> file like the following:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-yaml"><span class="line"><span class="cl"><span class="nt">ID</span><span class="p">:</span><span class="w"> </span><span class="l">Exploit</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">Title</span><span class="p">:</span><span class="w"> </span><span class="l">My exploit</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">Description</span><span class="p">:</span><span class="w"> </span><span class="l">This is an exploit</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">Version</span><span class="p">:</span><span class="w"> </span><span class="m">1.0.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">System</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">OS</span><span class="p">:</span><span class="w"> </span><span class="l">windows</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ARCH</span><span class="p">:</span><span class="w"> </span><span class="m">386</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">Service</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ExecStart</span><span class="p">:</span><span class="w"> </span><span class="l">Exploit.exe</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ExecStop</span><span class="p">:</span><span class="w"> </span><span class="l">Exploit.exe</span><span class="w">
</span></span></span></code></pre></div><p>The plugin would install successfully under <code>Thunder\Profiles\XLLite\plugin\Exploit\1.0.1\Exploit</code> but the binary wouldn’t execute for some reason. Maybe there is a security mechanism that I missed, or maybe the plugin interface simply isn’t working yet.</p>
<p>Either way, I started thinking: what if instead of making XLLite run my “plugin” I would replace an existing binary? It’s easy enough to produce an archive with file paths like <code>..\..\..\oops.exe</code>. However, the <a href="https://pkg.go.dev/github.com/mholt/archiver">Go package archiver</a> used here has protection against such path traversal attacks.</p>
<p>The XLLite code deciding which folder to put the plugin into didn’t have any such protections on the other hand. The folder is determined by the <code>ID</code> and <code>Version</code> values of the plugin’s manifest. Messing with the former is inconvenient, it being present twice in the path. But setting the “version” to something like <code>..\..\..</code> achieved the desired results.</p>
<p>Two complications:</p>
<ol>
<li>The application to be replaced cannot be running or the Windows file locking mechanism will prevent it from being replaced.</li>
<li>The plugin installation will only replace entire folders.</li>
</ol>
<p>In the end, I chose to replace Xunlei’s media player for my proof of concept. This one usually won’t be running and it’s contained in a folder of its own. It’s also fairly easy to make Xunlei run the media player by using a <code>thunderx://</code> link. Behold, installation and execution of a malicious application without any user interaction.</p>
<p>Remember that the API server is exposed to the local network, meaning that any devices on the network can also perform API calls. So this attack could not merely be executed from any website the user happened to be visiting, it could also be launched by someone on the same network, e.g. when the user is connected to a public WiFi.</p>
<h4>The fixes</h4>
<p>As of version 3.19.4 of the XLLite plugin (built January 25, 2024 according to its digital signature), the “pan authentication” method changed to use <a href="https://en.wikipedia.org/wiki/JSON_Web_Token">JSON Web Tokens</a>. The authentication token is embedded within the main page of the user interface server. Without any CORS headers being produced for this page, the token cannot be extracted by other web pages.</p>
<p>It wasn’t immediately obvious what secret is being used to generate the token. However, authentication tokens aren’t invalidated if the Xunlei application is restarted. This indicates that the secret isn’t being randomly generated on application startup. The remaining possibilities are: a randomly generated secret stored somewhere on the system (okay) or an obfuscated hardcoded secret in the application (very bad).</p>
<p>While calls to other endpoints succeed after adjusting authentication, calls to the <code>drive/v1/app/install</code> endpoint result in a “permission denied” response now. I did not investigate whether the endpoint has been disabled or some additional security mechanism has been added.</p>
<h3>Plugin management</h3>
<h4>The oddities</h4>
<p>XLLite’s plugin system is actually only one out of at least five completely different plugin management systems in the Xunlei application. One other is the main application’s plugin system, the XLLite application is installed as one such plugin. There are more, and <code>XLLiveUpdateAgent.dll</code> is tasked with keeping them updated. It will download the list of plugins from an address like <code>http://upgrade.xl9.xunlei.com/plugin?os=10.0.22000&pid=21&v=12.0.3.2240&lng=0804</code> and make sure that the appropriate plugins are installed.</p>
<p>Note the lack of TLS encryption here which is quite typical. Part of the issue appears to be that Xunlei decided to implement their own HTTP client for their downloads. In fact, they’ve implemented a number of different HTTP clients instead of using any of the options available via the Windows API for example. Some of these HTTP clients are so limited that they cannot even parse uncommon server responses, much less support TLS. Others support TLS but use their own list of CA certificates which happens to be Mozilla’s list from 2016 (yes, that’s almost eight years old).</p>
<p>Another common issue is that almost all these various update mechanisms run as part of the regular application process, meaning that they only have user’s privileges. How do they manage to write to the application directory then? Well, Xunlei solved this issue: they made the application directory writable with user’s privileges! Another security mechanism successfully dismantled. And there is a bonus: they can store application data in the same directory rather than resorting to per-user nonsense like AppData.</p>
<p>Altogether, you better don’t run Xunlei Accelerator on untrusted networks (meaning: any of them?). Anyone on your network or anyone who manages to insert themselves into the path between you and the Xunlei update server will be able to manipulate the server response. As a result, the application will install a malicious plugin without you even noticing anything.</p>
<p>You also better don’t run Xunlei Accelerator on a computer that you share with other people. Anyone on a shared computer will be able to add malicious components to the Xunlei application, so next time you run it your user account will be compromised.</p>
<h4>Example scenario: XLServicePlatform</h4>
<p>I decided to focus on XLServicePlatform because, unlike all the other plugin management systems, this one runs with system privileges. That’s because it’s a system service and any installed plugins will be loaded as dynamic libraries into this service process. Clearly, injecting a malicious plugin here would result in full system compromise.</p>
<p>The management service downloads the plugin configuration from <code>http://plugin.pc.xunlei.com/config/XLServicePlatform_12.0.3.xml</code>. Yes, no TLS encryption here because the “HTTP client” in question isn’t capable of TLS. So anyone on the same WiFi network as you for example could redirect this request and give you a malicious response.</p>
<p>In fact, that HTTP client was rather badly written, and I found multiple Out-of-Bounds Read vulnerabilities despite not actively looking for them. It was fairly easy to crash the service with an unexpected response.</p>
<p>But it wasn’t just that. The XML response was parsed using libexpat 2.1.0. With that version being released more than ten years ago, there are numerous known vulnerabilities, including a number of critical remote code execution vulnerabilities.</p>
<p>I generally leave binary exploitation to other people however. Continuing with the high-level issues, a malicious plugin configuration will result in a DLL or EXE file being downloaded, yet it won’t run. There is a working security mechanism here: these files need a valid code signature issued to Shenzhen Thunder Networking Technologies Ltd.</p>
<p>But it still downloads. And there is our old friend: a path traversal vulnerability. Choosing the file name <code>..\XLBugReport.exe</code> for that plugin will overwrite the legitimate bug reporter used by the Xunlei service. And crashing the service with a malicious server response will then run this trojanized bug reporter, with system privileges.</p>
<p>My proof of concept exploit merely created a file in the <code>C:\Windows</code> directory, just to demonstrate that it runs with sufficient privileges to do it. But we are talking about complete system compromise here.</p>
<h4>The (lack of?) fixes</h4>
<p>At the time of writing, XLServicePlatform still uses its own HTTP client to download plugins which still doesn’t implement TLS support. Server responses are still parsed using libexpat 2.1.0. Presumably, the Out-of-Bounds Read and Path Traversal vulnerabilities have been resolved but verifying that would take more time than I am willing to invest.</p>
<p>The application will still render its directory writable for all users. It will also produce a number of unencrypted HTTP requests, including some that are related to downloading application components.</p>
<h3>Outdated components</h3>
<p>I’ve already mentioned the browser being based on an outdated Chromium version, the main application being built on top of an outdated Electron platform and a ten years old XML library being widely used throughout the application. This isn’t by any means the end of it however. The application packages lots of third-party components, and the general approach appears to be that none of them are ever updated.</p>
<p>Take for example the media player XMP a.k.a. Thunder Video which is installed as part of the application and can be started via a <code>thunderx://</code> address from any website. This is also an Electron-based application, but it’s based on an even older Electron 59.0.3071.115 (released in June 2017). The playback functionality seems to be based on the APlayer SDK which Xunlei provides for free for other applications to use.</p>
<p>Now you might know that media codecs are extremely complicated pieces of software that are known for disastrous security issues. That’s why web browsers are very careful about which media codecs they include. Yet APlayer SDK features media codecs that have been discontinued more than a decade ago as well as some so ancient that I cannot even figure out who developed them originally. There is FFmpeg 2021-06-30 (likely a snapshot around version 4.4.4), which has <a href="https://ffmpeg.org/security.html">dozens of known vulnerabilities</a>. There is libpng 1.0.56, which was released in July 2011 and is <a href="http://www.libpng.org/pub/png/libpng.html">affected by seven known vulnerabilities</a>. Last but not least, there is zlib 1.2.8-4 which was released in 2015 and is affected by at least two critical vulnerabilities. These are only some examples.</p>
<p>So there is a very real threat that Xunlei users might get compromised via a malicious media file, either because they were tricked into opening it with Xunlei’s video player, or because a website used one of several possible ways to open it automatically.</p>
<p>As of Xunlei Accelerator 12.0.8.2392, I could not notice any updates to these components.</p>
<h3>Reporting the issues</h3>
<p>Reporting security vulnerabilities is usually quite an adventure, and the language barrier doesn’t make it any better. So I was pleasantly surprised to discover <a href="https://security.xunlei.com/">XunLei Security Response Center</a> that was even discoverable via an English-language search thanks to the site heading being translated.</p>
<p>Unfortunately, there was a roadblock: submitting a vulnerability is only possible after logging in via WeChat or QQ. While these social networks are immensely popular in China, creating an account from outside China proved close to impossible. I’ve spent way too much time on verifying that.</p>
<p>That’s when I took a closer look and discovered an email address listed on the page as fallback for people who are unable to log in. So I’ve sent altogether five vulnerability reports on 2023-12-06 and 2023-12-07. The number of reported vulnerabilities was actually higher because the reports typically combined multiple vulnerabilities. The reports mentioned 2024-03-06 as publication deadline.</p>
<p>I received a response a day later, on 2023-12-08:</p>
<blockquote>
<p>Thank you very much for your vulnerability submission. XunLei Security Response Center has received your report. Once we have successfully reproduced the vulnerability, we will be in contact with you.</p>
</blockquote>
<p>Just like most companies, they did not actually contact me again. I saw my proof of concept pages being accessed, so I assumed that the issues are being worked on and did not inquire further. Still, on 2024-02-10 I sent a reminder that the publication deadline was only a month away. I do this because in my experience companies will often “forget” about the deadline otherwise (more likely: they assume that I’m not being serious about it).</p>
<p>I received another laconic reply a week later which read:</p>
<blockquote>
<p>XunLei Security Response Center has verified the vulnerabilities, but the vulnerabilities have not been fully repaired.</p>
</blockquote>
<p>That was the end of the communication. I don’t really know what Xunlei considers fixed and what they still plan to do. Whatever I could tell about the fixes here has been pieced together from looking at the current software release and might not be entirely correct.</p>
<p>It does not appear that Xunlei released any further updates in the month after this communication. Given the nature of the application with its various plugin systems, I cannot be entirely certain however.</p>2024-03-06T13:27:53+00:00This Week In Rust: This Week in Rust 537
https://this-week-in-rust.org/blog/2024/03/06/this-week-in-rust-537/
<p>Hello and welcome to another issue of <em>This Week in Rust</em>!
<a href="https://www.rust-lang.org/">Rust</a> is a programming language empowering everyone to build reliable and efficient software.
This is a weekly summary of its progress and community.
Want something mentioned? Tag us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> on Twitter or <a href="https://mastodon.social/@thisweekinrust">@ThisWeekinRust</a> on mastodon.social, or <a href="https://github.com/rust-lang/this-week-in-rust">send us a pull request</a>.
Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p>
<p><em>This Week in Rust</em> is openly developed <a href="https://github.com/rust-lang/this-week-in-rust">on GitHub</a> and archives can be viewed at <a href="https://this-week-in-rust.org/">this-week-in-rust.org</a>.
If you find any errors in this week's issue, <a href="https://github.com/rust-lang/this-week-in-rust/pulls">please submit a PR</a>.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-rust-community">Updates from Rust Community</a></h4>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#official">Official</a></h5>
<ul>
<li><a href="https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html">Clippy: Deprecating <code>feature = "cargo-clippy"</code></a></li>
<li><a href="https://blog.rust-lang.org/2024/02/26/Windows-7.html">Updated baseline standards for Windows targets</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#projecttooling-updates">Project/Tooling Updates</a></h5>
<ul>
<li><a href="https://polar.sh/davidhewitt/posts/replacing-pyo3-api-pt1">Replacing PyO3's API without breaking everything downstream</a></li>
<li><a href="https://rust-analyzer.github.io/thisweek/2024/03/04/changelog-223.html">rust-analyzer changelog #223</a></li>
<li><a href="https://rust-gcc.github.io/2024/03/05/2024-02-monthly-report.html">rust-gcc February 2024 Monthly report</a></li>
<li><a href="https://godot-rust.github.io/dev/february-2024-update/">godot-rust February 2024 dev update</a></li>
<li><a href="https://www.fluvio.io/news/this-week-in-fluvio-0059/">Fluvio v0.11.5 Release Updates</a></li>
<li><a href="https://crates.io/crates/sshd-openpgp-auth">sshd-openpgp-auth version 0.3.0</a> and <a href="https://crates.io/crates/ssh-openpgp-auth">ssh-openpgp-auth version 0.2.2</a> as updates to the tooling providing <a href="https://codeberg.org/wiktor/ssh-openpgp-auth">OpenPGP based authentication for SSH host keys</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#observationsthoughts">Observations/Thoughts</a></h5>
<ul>
<li><a href="https://smallcultfollowing.com/babysteps/blog/2024/03/04/borrow-checking-without-lifetimes/">Borrow checking without lifetimes</a></li>
<li><a href="https://nnethercote.github.io/2024/03/06/how-to-speed-up-the-rust-compiler-in-march-2024.html">How to speed up the Rust compiler in March 2024</a></li>
<li><a href="https://nnethercote.github.io/2024/03/05/code-review-in-the-rust-compiler.html">Code review in the Rust compiler</a></li>
<li><a href="https://swatinem.de/blog/slow-thread-local/">Rust <code>thread_local!</code>s are surprisingly expensive</a></li>
<li><a href="https://blog.yoshuawuyts.com/building-an-async-runtime-for-wasi/">Designing an Async Runtime for WASI 0.2</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-walkthroughs">Rust Walkthroughs</a></h5>
<ul>
<li><a href="https://ferrous-systems.com/blog/rustls-borrow-checker-p3/">Storing borrowed data in trait objects</a></li>
<li><a href="https://blog.the-pans.com/rusts-early-vs-late-lifetime-binding/">Rust's early vs. late lifetime binding</a></li>
<li><a href="https://dev.to/check/how-moving-from-pandas-to-polars-made-me-write-better-code-without-writing-better-code-52bl">How moving from Pandas to Polars made me write better code without writing better code</a></li>
<li><a href="https://www.shuttle.rs/blog/2024/02/29/fullstack-loco-rust">A Full Stack SaaS Template with Loco</a></li>
<li><a href="https://www.shuttle.rs/blog/2024/02/29/async-rust">Async Rust in a Nutshell</a></li>
<li><a href="https://infinyon.com/blog/2024/02/fluvio-deep-causality-rs/">Real-time Streaming Analytics with Fluvio, DeepCausality, and Rust</a></li>
<li>[video] <a href="https://www.youtube.com/watch?v=Pr6T0Phjvgc">Modern All Rust Stack - Dioxus, Axum, Warp, SurrealDB</a></li>
<li>[video] <a href="https://www.youtube.com/watch?v=PK_FKzgPDWg">Serverless Data Pipelines in Rust by Michele Vigilante</a></li>
<li><a href="https://www.youtube.com/watch?v=8_Pj6q_mVQw">[FR] [video] Rust Lyon Meetup #8 - Impl Snake for Micro:bit — Cyril MARPAUD</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#miscellaneous">Miscellaneous</a></h5>
<ul>
<li><a href="https://rustlang.cz/">Czech Rust community index</a></li>
<li><a href="https://mainmatter.com/blog/2024/02/29/launching-rustrover/">Launching RustRover: JetBrains’ Investment in Rust</a></li>
<li>[audio] <a href="https://ieni.dev/2024/03/%EF%B8%8F-rust-in-art-with-lisa-passing-rustship-6/">RustShip: Rust in Art with Lisa Passing</a></li>
</ul>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#crate-of-the-week">Crate of the Week</a></h4>
<p>This week's crate is <a href="https://github.com/alexpovel/srgn">srgn</a>, a mix of tr, sed, rip-grep and tree-sitter.</p>
<p>Thanks to <a href="https://users.rust-lang.org/t/crate-of-the-week/2704/1294">Alex Povel</a> for the self-suggestion!</p>
<p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Please submit your suggestions and votes for next week</a>!</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-testing"></a><a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">Call for Testing</a></h4>
<p>An important step for RFC implementation is for people to experiment with the
implementation and give feedback, especially before stabilization. The following
RFCs would benefit from user testing before moving forward:</p>
<ul>
<li><em>No RFCs issued a call for testing this week.</em></li>
</ul>
<p>If you are a feature implementer and would like your RFC to appear on the above list, add the new <code>call-for-testing</code>
label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the feature
need testing.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-participation-projects-and-speakers">Call for Participation; projects and speakers</a></h4>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-projects">CFP - Projects</a></h5>
<p>Always wanted to contribute to open-source projects but did not know where to start?
Every week we highlight some tasks from the Rust community for you to pick and get started!</p>
<p>Some of these tasks may also have mentors available, visit the task page for more information.</p>
<ul>
<li><a href="https://github.com/build-trust/ockam/issues/7473">Ockam - Output for both <code>ockam project ticket</code> and <code>ockam project enroll</code> is improved, with support for <code>--output json</code></a></li>
<li><a href="https://github.com/build-trust/ockam/issues/7471">Ockam - Syntax highlighting for fenced code blocks, in command help output, on Linux works</a></li>
<li><a href="https://github.com/build-trust/ockam/issues/6706">Ockam - Command - refactor to use typed interfaces to implement commands for <code>kafka services</code></a></li>
<li><a href="https://github.com/google/zerocopy/issues/553">ZeroCopy - Don't generate warning when deriving on deprecated type</a></li>
<li><a href="https://github.com/google/zerocopy/issues/367">ZeroCopy - Test the output of zerocopy-derive</a></li>
<li><a href="https://github.com/google/zerocopy/issues/357">ZeroCopy - [CI] Check semver compatibility with all target platforms, not just the host platform</a></li>
<li><a href="https://github.com/google/zerocopy/issues/7">ZeroCopy - Inline many trait methods (in zerocopy and in derive-generated code)</a></li>
<li><a href="https://github.com/infinyon/fluvio/issues/3765">Fluvio - fvm switch fails on some systems with running local cluster</a></li>
<li><a href="https://github.com/infinyon/fluvio/issues/3810">Fluvio - Add new command fluvio cluster resume</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-speakers">CFP - Speakers</a></h5>
<p>Are you a new or experienced speaker looking for a place to share something cool? This section highlights events that are being planned and are accepting submissions to join their event as a speaker.</p>
<ul>
<li><a href="https://oxidizeconf.com/">Oxidize 2024</a> <a href="https://pretalx.com/oxidize-berlin-2024/cfp">CFP</a> closes 2024-03-24 | Berlin, Germany | Event date: 2024-05-28 - 2024-05-30</li>
<li><a href="https://foundation.rust-lang.org/news/the-rustconf-2024-call-for-talk-proposals-is-open/">RustConf 2024</a> | CFP closes 2024-04-25 | Montreal, Canada | 2024-09-10</li>
<li><a href="https://www.papercall.io/eurorust-2024">EuroRust 2024</a>| CFP closes 2024-06-03 | Vienna, Austria & online | Event on 2024-10-10</li>
</ul>
<p>If you are an event organizer hoping to expand the reach of your event, please submit a link to the submission website through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a>.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-the-rust-project">Updates from the Rust Project</a></h4>
<p>488 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2024-02-27..2024-03-05">merged in the last week</a></p>
<ul>
<li><a href="https://github.com/rust-lang/rust/pull/121548"><code>ffi_unwind_calls</code>: treat RustIntrinsic like regular Rust calls</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121000"><code>pattern_analysis</code>: rework how we hide empty private fields</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121464">rustc: fix wasm64 metadata object files</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121927">add a proper <code>with_no_queries</code> to printing</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121703">add a way to add constructors for <code>rustc_type_ir</code> types</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120761">add initial support for DataFlowSanitizer</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121917">add new <code>pattern_complexity</code> attribute to add possibility to limit and check recursion in pattern matching</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121765">add platform-specific function to get the error number for HermitOS</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121730">add profiling support to AIX</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121753">add proper cfg to keep only one AlignmentEnum definition for different <code>target_pointer_widths</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121782">allow statics pointing to mutable statics</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121665">always generate GEP i8 / ptradd for <code>struct</code> offsets</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121895">avoid collecting into vecs in some places</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121993">avoid using unnecessary queries when printing the query stack in panics</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121528">consider middle segments of paths in <code>unused_qualifications</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121855">correctly generate item info of trait items</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120305">delete line if suggestion would replace it with an empty line</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121739">display short types for unimplemented trait</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121864">don't grab variances in <code>TypeRelating</code> relation if we're invariant</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121913">don't panic when waiting on poisoned queries</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120646">fix incorrect suggestion for uninitialized binding in pattern</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121226">fix issues in suggesting importing extern crate paths</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121680">fix link generation for foreign macro in jump to definition feature</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121824">implement missing ABI structures in StableMIR</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121792">improve renaming suggestion when item starts with underscore</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/111505">made <code>INVALID_DOC_ATTRIBUTES</code> lint deny by default</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121850">make <code>ZeroablePrimitive</code> trait unsafe</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121784">make the success arms of <code>if lhs || rhs</code> meet up in a separate block</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121716">match lowering: Lower bindings in a predictable order</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121750">match lowering: Separate the <code>bool</code> case from other integers in <code>TestKind</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121715">match lowering: pre-simplify or-patterns too</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121803">never say <code>"</code>Trait is implemented for {type error}<code>"</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121853">normalizes-to: handle negative impls</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121743">opportunistically resolve regions when processing region outlives obligations</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121735">pattern analysis: Don't panic when encountering unexpected constructor</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121987">pattern analysis: abort on arity mismatch</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121622">preserve same vtable pointer when cloning raw waker, to fix <code>Waker::will_wake</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121702">process alias-relate obligations in CoerceUnsized loop</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121912">properly deal with GATs when looking for method chains to point at</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121681">safe Transmute: Revise safety analysis</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121376">skip unnecessary comparison with half-open range patterns</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121695">split <code>rustc_type_ir</code> to avoid <code>rustc_ast</code> from depending on it</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121888">style library/core/src/error.rs</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121130">suggest moving definition if non-found <code>macro_rules!</code> is defined later</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121153">suggest removing superfluous semicolon when statements used as expression</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121892">the ordinary lowering of <code>thir::ExprKind::Let</code> is unreachable</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121596">use volatile access instead of <code>#[used]</code> for <code>on_tls_callback</code></a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3346">miri: add -Zmiri-track-alloc-accesses to readme and fix its wording</a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3348">miri: log when we change the active thread, and fix logging for concurrency</a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3338">miri: print thread name in miri error backtraces; add option to track read/write accesses</a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3343">miri: tree Borrows diagnostic improvements</a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3345">miri: windows: support getting the thread name</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121138">add ASCII fast-path for <code>char::is_grapheme_extended</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121001">perf: improve <code>write_fmt</code> to handle simple strings</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120051">add <code>display</code> method to <code>OsStr</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120291">have <code>String</code> use <code>SliceIndex</code> impls from <code>str</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121666">use the OS thread name by default if <code>THREAD_INFO</code> has not been initialized</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121933">add missing <code>get_name</code> for <code>wasm::thread</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121736">remove <code>Mutex::unlock</code> Function</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121768">implement unwind safety for Condvar on all platforms</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/110543">make <code>ReentrantLock</code> public</a></li>
<li><a href="https://github.com/rust-lang/rustc_codegen_gcc/pull/455">codegen_gcc: debuginfo: Add support for debuginfo, without scope support</a></li>
<li><a href="https://github.com/rust-lang/rustc_codegen_gcc/pull/462">codegen_gcc: switch to the new <code>set_special_chars_allowed_in_func_names</code> API</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13516">cargo add: Fallback to <code>rustc -v</code> when no MSRV is set</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13505">cargo toml: Warn on unset Edition</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13514">cargo msrv: Report all incompatible packages, not just a random one</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13499">cargo rustc: Always pass --edition to rustc</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13533">cargo toml: Don't warn on unset Edition if only 2015 is compatible</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13481">cargo: add all unit's children recursively for <code>doc.extern-map</code> option</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13340">cargo: add "-Zpublic-dependency" for public-dependency feature</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13438">cargo: silently ignore <code>cargo::rustc-check-cfg</code> to avoid MSRV annoyance when stabilizing <code>-Zcheck-cfg</code></a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13492">cargo: stabilize global cache data tracking</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121689">rustdoc: Prevent inclusion of whitespace character after <code>macro_rules</code> ident</a></li>
<li><a href="https://github.com/rust-lang/rustfmt/pull/6085">rustfmt: ensure space around binary exprs</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12409">clippy: <code>identity_op</code>: Fix duplicate diagnostics</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12400">clippy: <code>let_underscore_untyped</code>: fix false positive on async function</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12362">clippy: <code>map_entry</code>: Check insert expression for map use</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12413">clippy: <code>misrefactored_assign_op</code>: fix duplicate diagnostics</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12380">clippy: <code>redundant_closure_call</code>: don't lint closure originating from a macro</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12365">clippy: <code>unnecessary_cast</code>: avoid breaking precedence</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12077">clippy: add <code>assigning_clones</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12354">clippy: add <code>mixed_attributes_style</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12405">clippy: added msrv to threadlocal initializer check</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12341">clippy: check for try blocks in <code>question_mark</code> more consistently</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12406">clippy: dedup <code>std_instead_of_core</code> by using first segment span for uniqueness</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12423">clippy: don't emit "missing backticks" lint if the element is wrapped in <code><code></code> HTML tags</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12276">clippy: fix false positive in <code>threadlocal!</code> when falling back to <code>os_local</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12393">clippy: fix <code>derive_partial_eq_without_eq</code> false positive on trait projection</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12372">clippy: fix <code>nonminimal_bool</code> lint regression</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12010">clippy: fix <code>manual_memcpy</code> wrong indexing for multi dimensional arrays</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12419">clippy: handle plural acronyms in <code>doc_markdown</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12375">clippy: improve <code>is_lint_level</code> code</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12363">clippy: lower <code>bstr</code> version requirement to <code>1.6.0</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12403">clippy: pointers cannot be converted to integers at compile time</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/15938">rust-analyzer: add hover display for trait assoc items</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16719">rust-analyzer: add basic support for native debug</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16723">rust-analyzer: autocomplete constants inside format strings</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16752">rust-analyzer: don't destructure <code>struct</code> with no public fields</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16727">rust-analyzer: don't highlight related assoc items of super traits</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16696">rust-analyzer: goto definition for <code>deref_mut</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16709">rust-analyzer: goto definition for <code>index_mut</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16759">rust-analyzer: goto-definition for constants inside range pattern</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16702">rust-analyzer: ignore generic arguments in intra doc link path resolution</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16757">rust-analyzer: put style lints behind disabled-by-default config</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16693">rust-analyzer: fix rust-project.json projects not preferring sysroot rustc</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16630">rust-analyzer: fix wrong closure kind deduction for closures with predicates</a></li>
<li><a href="https://github.com/rust-lang/futures-rs/pull/2832">futures: parse rhs of <code>select!</code> arms using match-arm rules</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-compiler-performance-triage">Rust Compiler Performance Triage</a></h5>
<p>A bunch of noise this week which has been dropped from the report (but may be
present in the summary figures). As a result, the week is pretty busy in amount
of changes, but the net effect is nearly neutral to a slight regression for
most workloads.</p>
<p>Triage done by <strong>@simulacrum</strong>.
Revision range: <a href="https://perf.rust-lang.org/?start=71ffdf7ff7ac6df5f9f64de7e780b8345797e8a0&end=41d97c8a5dea2731b0e56fe97cd7cb79e21cff79&absolute=false&stat=instructions%3Au">71ffdf7..41d97c8</a></p>
<p>2 Regressions, 0 Improvements, 10 Mixed; 4 of them in rollups
51 artifact comparisons made in total</p>
<p><a href="https://github.com/rust-lang/rustc-perf/blob/master/triage/2024-03-05.md">Full report here</a></p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#approved-rfcs"></a><a href="https://github.com/rust-lang/rfcs/commits/master">Approved RFCs</a></h5>
<p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments) process</a>. These
are the RFCs that were approved for implementation this week:</p>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/3537">RFC: Make Cargo respect minimum supported Rust version (MSRV) when selecting dependencies</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#final-comment-period">Final Comment Period</a></h5>
<p>Every week, <a href="https://www.rust-lang.org/team.html">the team</a> announces the 'final comment period' for RFCs and key PRs
which are reaching a decision. Express your opinions now.</p>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rfcs"></a><a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">RFCs</a></h6>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/3543">RFC: patchable-function-entry</a></li>
<li><a href="https://github.com/rust-lang/rfcs/pull/3287">RFC: Add native code coverage support in Cargo</a></li>
<li><a href="https://github.com/rust-lang/rfcs/pull/3243">RFC: Packages as (optional) namespaces</a></li>
</ul>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#tracking-issues-prs">Tracking Issues & PRs</a></h6>
<a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust"></a><a href="https://github.com/rust-lang/rust/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Rust</a>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/99969">alloc: implement <code>FromIterator</code> for <code>Box<str></code></a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/116891">rework opaque type region inference</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/114655">Make <code>impl<Fd: AsFd></code> impl take <code>?Sized</code></a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/issues/28937">Tracking issue for Allow a re-export for <code>main</code> (RFC 1260)</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/115141">Update Windows platform support </a></li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rust/pull/121602">Resolve region bounds from components of type projection</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/121346">Propagate temporary lifetime extension into if and match.</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/119849">more eagerly instantiate binders</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/issues/121250"><code>E0492: borrow of an interior mutable value may end up in the final value</code> during const eval when no inner mutability is involved</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/121201">align_offset, align_to: no longer allow implementations to spuriously fail to align</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/116016">Soft-destabilize <code>RustcEncodable</code> & <code>RustcDecodable</code>, remove from prelude in next edition</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/121403"><code>impl From<TryReserveError></code> for <code>io::Error</code></a></li>
</ul>
<a class="toclink" href="http://this-week-in-rust.org/atom.xml#cargo"></a><a href="https://github.com/rust-lang/cargo/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Cargo</a>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/cargo/issues/10554">Tracking Issue for rustc <code>--check-cfg</code> integration</a></li>
</ul>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#new-and-updated-rfcs"></a><a href="https://github.com/rust-lang/rfcs/pulls">New and Updated RFCs</a></h6>
<ul>
<li>[new] <a href="https://github.com/rust-lang/rfcs/pull/3579">Public Key Infrastructure for Rust Project</a></li>
</ul>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#upcoming-events">Upcoming Events</a></h4>
<p>Rusty Events between 2024-03-06 - 2024-04-03 🦀</p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#virtual">Virtual</a></h5>
<ul>
<li>2024-03-06 | Virtual (Dublin, IE) | <a href="https://www.meetup.com/rust-dublin/">Rust Dublin</a><ul>
<li><a href="https://www.meetup.com/rust-dublin/events/299358988/"><strong>An intro to <code>nom</code>, parsing made easy for Rustaceans</strong></a></li>
</ul>
</li>
<li>2024-03-06 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs/">Indy Rust</a><ul>
<li><a href="https://www.meetup.com/indyrs/events/299047891/"><strong>Indy.rs - with Social Distancing</strong></a></li>
</ul>
</li>
<li>2024-03-07 | Virtual (Charlottesville, NC, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/">Charlottesville Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/298368787/"><strong>Crafting Interpreters in Rust Collaboratively</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/">Dallas Rust</a><ul>
<li><a href="https://www.meetup.com/dallasrust/events/298341582/"><strong>Second Tuesday</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Hybrid (Virtual + In-person) Munich, DE | <a href="https://www.meetup.com/rust-munich/">Rust Munich</a><ul>
<li><a href="https://www.meetup.com/rust-munich/events/298507657/"><strong>Rust Munich 2024 / 1 - hybrid</strong></a></li>
</ul>
</li>
<li>2024-03-13 | Virtual (Cardiff, UK) | <a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/">Rust and C++ Cardiff</a><ul>
<li><a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/events/299505703/"><strong>Rust for Rustaceans Book Club: Chapter 3 - Designing Interfaces</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/opentechschool-berlin/">OpenTechSchool Berlin</a><ul>
<li><a href="https://www.meetup.com/opentechschool-berlin/events/298406445/"><strong>Web Frontend Co-Learning (online)</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Berlin, DE) | <a href="https://berline.rs/">OpenTechSchool Berlin</a> + <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://meet.jit.si/RustHackAndLearnBerlin"><strong>Rust Hack and Learn</strong></a> | <a href="https://www.meetup.com/rust-berlin/events/298457903/"><strong>Mirror: Rust Hack n Learn Meetup</strong></a> | <a href="https://berline.rs/2024/03/14/rust-hack-and-learn.html"><strong>Mirror: Berline.rs page</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Nürnberg, DE) | <a href="https://www.meetup.com/rust-noris/">Rust Nüremberg</a><ul>
<li><a href="https://www.meetup.com/rust-noris/events/297945252/"><strong>Rust Nürnberg online</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Virtual (Washinigton, DC, US) | <a href="https://www.meetup.com/rustdc/">Rust DC</a><ul>
<li><a href="https://www.meetup.com/rustdc/events/299335006/"><strong>Mid-month Rustful</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Virtual (Vancouver, BC, CA)| <a href="https://www.meetup.com/vancouver-rust/">Vancouver Rust</a><ul>
<li><a href="https://www.meetup.com/vancouver-rust/events/292763494/"><strong>Rust Study/Hack/Hang-out</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Virtual (Charlottesville, NC, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/">Charlottesville Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/298368793/"><strong>Crafting Interpreters in Rust Collaboratively</strong></a></li>
</ul>
</li>
<li>2024-03-26 | Virtual + In Person (Barcelona, ES) | <a href="https://www.meetup.com/es-ES/bcnrust/">BcnRust</a><ul>
<li><a href="https://www.meetup.com/es-ES/bcnrust/events/299223178/"><strong>13th BcnRust Meetup</strong></a> - <a href="https://www.youtube.com/@bcnrust">Stream</a></li>
</ul>
</li>
<li>2024-03-28 | Virtual (Berlin, DE) | <a href="https://berline.rs/">OpenTechSchool Berlin</a> + <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://meet.jit.si/RustHackAndLearnBerlin"><strong>Rust Hack and Learn</strong></a> | <a href="https://www.meetup.com/rust-berlin/events/298457904/"><strong>Mirror: Rust Hack n Learn Meetup</strong></a></li>
</ul>
</li>
<li>2024-04-02 | Virtual (Buffalo, NY, US) | <a href="https://www.meetup.com/buffalo-rust-meetup/">Buffalo Rust</a><ul>
<li><a href="https://www.meetup.com/buffalo-rust-meetup/events/mrnrktygcgbdb/"><strong>Buffalo Rust User Group</strong></a></li>
</ul>
</li>
<li>2024-04-03 | Virtual (Cardiff, UK) | <a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/">Rust and C++ Cardiff</a><ul>
<li><a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/events/299507234/"><strong>Rust for Rustaceans Book Club: Chapter 4 - Error Handling</strong></a></li>
</ul>
</li>
<li>2024-04-03 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs/">Indy Rust</a><ul>
<li><a href="https://www.meetup.com/indyrs/events/299047892/"><strong>Indy.rs - with Social Distancing</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#asia">Asia</a></h5>
<ul>
<li>2024-03-09 | Karnataka, Bengaluru, IN | <a href="https://hasgeek.com/rustbangalore">Rust Bangalore</a><ul>
<li><a href="https://hasgeek.com/rustbangalore/march-2024-rustacean-meetup/"><strong>March 2024 Rustacean Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Tokyo, JP | <a href="https://www.meetup.com/tokyo-rust-meetup/">Tokyo Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/tokyo-rust-meetup/events/299607311/"><strong>Building the Isograph Compiler in Rust</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#europe">Europe</a></h5>
<ul>
<li>2024-03-06 | Cologne / Köln, DE | <a href="https://www.meetup.com/rustcologne/">Rust Cologne</a><ul>
<li><a href="https://www.meetup.com/rustcologne/events/299530888/"><strong>Macros by simple Examples</strong></a></li>
</ul>
</li>
<li>2024-03-06 | Zürich, CH | <a href="https://www.meetup.com/rust-zurich/">Rust Zürisee</a><ul>
<li><a href="https://www.meetup.com/rust-zurich/events/299380190/"><strong>How to (partial) Migration - March Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-07 | Copenhagen, DK | <a href="https://www.meetup.com/copenhagen-rust-community/">Copenhagen Rust Community</a><ul>
<li><a href="https://www.meetup.com/copenhagen-rust-community/events/299451605/"><strong>Rust Hack Night #3: Embedded on Espressif's ESP32C3</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Munich, DE + Virtual | <a href="https://www.meetup.com/rust-munich/">Rust Munich</a><ul>
<li><a href="https://www.meetup.com/rust-munich/events/298507657/"><strong>Rust Munich 2024 / 1 - hybrid</strong></a></li>
</ul>
</li>
<li>2024-03-13 | Paris, FR | <a href="https://www.eventbrite.com/o/paris-rustaceans-74289178383">Paris Rustaceans</a><ul>
<li><a href="https://www.eventbrite.fr/e/rust-meetup-in-paris-tickets-830340830777"><strong>Rust Meetup in Paris</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Reading, UK | <a href="https://www.meetup.com/reading-rust-workshop/">Reading Rust Workshop</a><ul>
<li><a href="https://www.meetup.com/reading-rust-workshop/events/298533419/"><strong>Reading Rust Meetup at Browns</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Aarhus, DK | <a href="https://www.meetup.com/rust-aarhus/">Rust Aarhus</a><ul>
<li><a href="https://www.meetup.com/rust-aarhus/events/299028814/"><strong>Hack Night</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Leipzig, DE | <a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/">Rust - Modern Systems Programming in Leipzig</a><ul>
<li><a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/299309224/"><strong>Rust Interactive Session</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Prague, CZ | <a href="https://www.meetup.com/rust-prague/events/299515169/">Rust Prague</a><ul>
<li><a href="https://www.meetup.com/rust-prague/events/299515169/"><strong>Rust Meetup @ Charles University</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Girona, ES | <a href="https://www.meetup.com/rust-girona/">Rust Girona</a><ul>
<li><a href="https://www.meetup.com/rust-girona/events/299172343/"><strong>Introduction to programming Microcontrollers with Rust</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Lyon, FR | <a href="https://www.meetup.com/fr-FR/rust-lyon/">Rust Lyon</a><ul>
<li><a href="https://www.meetup.com/fr-FR/rust-lyon/events/299527560/"><strong>Rust Lyon Meetup #9</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Augsburg, DE | <a href="https://www.meetup.com/de-DE/rust-meetup-augsburg/">Rust Meetup Augsburg</a><ul>
<li><a href="https://www.meetup.com/de-DE/rust-meetup-augsburg/events/299354449/"><strong>Augsburg Rust Meetup #6</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Lille, FR | <a href="https://www.meetup.com/meetup-group-zgphbyet/">Rust Lille</a><ul>
<li><a href="https://www.meetup.com/meetup-group-zgphbyet/events/299295547/"><strong>Rust Lille #6: Du RSS et de L'ECS !</strong></a></li>
</ul>
</li>
<li>2024-03-26 | Barcelona, ES + Virtual | <a href="https://www.meetup.com/es-ES/bcnrust/">BcnRust</a><ul>
<li><a href="https://www.meetup.com/es-ES/bcnrust/events/299223178/"><strong>13th BcnRust Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-27 - 2024-03-28 | London, UK | <a href="https://www.rustnationuk.com/">Rust Nation UK</a><ul>
<li><a href="https://www.rustnationuk.com/"><strong>Rust Nation 2024 - Conference</strong></a></li>
</ul>
</li>
<li>2024-03-28 | Berlin, DE | <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://www.meetup.com/rust-berlin/events/299288961/"><strong>Rust and Tell</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#north-america">North America</a></h5>
<ul>
<li>2024-03-07 | Mountain View, CA, US | <a href="https://www.meetup.com/mv-rust-meetup/">Mountain View Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/mv-rust-meetup/events/299043793/"><strong>Rust Meetup at Hacker Dojo</strong></a></li>
</ul>
</li>
<li>2024-03-12 | New York, NY, US | <a href="https://www.meetup.com/rust-nyc/">Rust NYC</a><ul>
<li><a href="https://www.meetup.com/rust-nyc/events/299619615/"><strong>Rust NYC Monthly Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-13 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/">Boston Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/bostonrust/events/299262009/"><strong>Northeastern Rust Lunch</strong></a></li>
</ul>
</li>
<li>2024-03-19 | San Francisco, CA, US | <a href="https://www.meetup.com/san-francisco-rust-study-group/">San Francisco Rust Study Group</a><ul>
<li><a href="https://www.meetup.com/san-francisco-rust-study-group/events/299186823/"><strong>Rust Hacking in Person</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Seattle, WA, US | <a href="https://www.meetup.com/seattle-rust-user-group/">Seattle Rust User Group</a><ul>
<li><a href="https://www.meetup.com/seattle-rust-user-group/events/298631832/"><strong>Seattle Rust User Group Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-27 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx/">Rust ATX</a><ul>
<li><a href="https://www.meetup.com/rust-atx/events/299220136/"><strong>Rust Lunch - Fareground</strong></a></li>
</ul>
</li>
<li>2024-03-27 | Hawthorne, CA, US | <a href="https://freeform.co/">Freeform</a><ul>
<li><a href="https://freeformxrust.rsvpify.com/"><strong>Rust in the Physical World 🦀 Tech Talk Event at Freeform</strong></a></li>
</ul>
</li>
</ul>
<p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to get
it mentioned here. Please remember to add a link to the event too.
Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#jobs">Jobs</a></h4>
<p>Please see the latest <a href="https://www.reddit.com/r/rust/comments/1arr8xi/official_rrust_whos_hiring_thread_for_jobseekers/">Who's Hiring thread on r/rust</a></p>
<h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#quote-of-the-week">Quote of the Week</a></h3>
<blockquote>
<p>My experience with C++ is that, as I’ve become more of an expert in the language, I’ve become more disillusioned with it. It’s incredibly hard to do things that you should be able to do in software. And, it’s a huge problem for me to constantly be helping other engineers debug the same bugs over and over. It’s always another use after free. I’ve probably debugged 300 of those. [...]</p>
<p>In our experience using the Rust ecosystem for almost three years now, I don't think we found a bug in a single Rust crate that we've pulled off the shelf. We found a bug in one of them and that was a Rust crate wrapping a C library and the bug was in the C library. The software quality that you kind of get for free is amazing.</p>
</blockquote>
<p>– <a href="https://filtra.io/rust-amp-feb-24">Carter Schultz interviewed on the filtra blog</a></p>
<p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/1543">George Barwood</a> for the suggestion!</p>
<p><a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328">Please submit quotes and vote for next week!</a></p>
<p><em>This Week in Rust is edited by: <a href="https://github.com/nellshamrell">nellshamrell</a>, <a href="https://github.com/llogiq">llogiq</a>, <a href="https://github.com/cdmistman">cdmistman</a>, <a href="https://github.com/ericseppanen">ericseppanen</a>, <a href="https://github.com/extrawurst">extrawurst</a>, <a href="https://github.com/andrewpollack">andrewpollack</a>, <a href="https://github.com/U007D">U007D</a>, <a href="https://github.com/kolharsam">kolharsam</a>, <a href="https://github.com/joelmarcey">joelmarcey</a>, <a href="https://github.com/mariannegoldin">mariannegoldin</a>, <a href="https://github.com/bennyvasquez">bennyvasquez</a>.</em></p>
<p><em>Email list hosting is sponsored by <a href="https://foundation.rust-lang.org/">The Rust Foundation</a></em></p>
<p><small><a href="https://www.reddit.com/r/rust/comments/1b8o0ms/this_week_in_rust_537/">Discuss on r/rust</a></small></p>2024-03-06T05:00:00+00:00TWiR ContributorsMozilla Open Policy & Advocacy Blog: Mozilla Mornings: Choice or Illusion? Tackling Harmful Design Practices
https://blog.mozilla.org/netpolicy/2024/03/05/mozilla-mornings-choice-or-illusion-tackling-harmful-design-practices/
<p><b>The first edition of Mozilla Mornings in 2024 will explore the impact of harmful design on consumers in the digital world and the role regulation can play in addressing such practices.</b></p>
<p>In the evolving digital landscape, deceptive and manipulative design practices, as well as aggressive personalisation and profiling pose significant threats to consumer welfare, potentially leading to financial loss, privacy breaches, and compromised security.</p>
<p>While existing EU regulations address some aspects of these issues, questions persist about their adequacy in combating harmful design patterns comprehensively. What additional measures are needed to ensure digital fairness for consumers and empower designers who want to act ethically?</p>
<p>To discuss these issues, we are delighted to announce that the following speakers will be participating in our panel discussion:</p>
<ul>
<li><b>Egelyn Braun</b>, Team Leader DG JUST, European Commission</li>
<li><b>Estelle Hary</b>, Co-founder, Design Friction</li>
<li><b>Silvia de Conca</b>, Amsterdam Law & Technology Institute, Vrije Universiteit Amsterdam</li>
<li><b>Finn Myrstad</b>, Digital Policy Director, Norwegian Consumer Council</li>
</ul>
<p>The event will also feature a <b>fireside chat with</b> <b>MEP Kim van Sparrentak</b> from Greens/EFA.</p>
<ul>
<li><b>Date: </b>Wednesday 20th March 2024</li>
<li><b>Location:</b> <a href="https://www.l42.be/">L42</a>, Rue de la Loi 42, 1000 Brussels</li>
<li><b>Time: </b>08:30 – 10:30 CET</li>
</ul>
<p>To register, <b>click </b><a href="https://www.eventbrite.com/e/mozilla-mornings-choice-or-illusion-tackling-harmful-design-practices-tickets-845906347657?aff=oddtdtcreator"><b>here</b></a>.</p>
<p>The post <a href="https://blog.mozilla.org/netpolicy/2024/03/05/mozilla-mornings-choice-or-illusion-tackling-harmful-design-practices/">Mozilla Mornings: Choice or Illusion? Tackling Harmful Design Practices</a> appeared first on <a href="https://blog.mozilla.org/netpolicy">Open Policy & Advocacy</a>.</p>2024-03-05T20:00:19+00:00Tasos StampelosNiko Matsakis: Borrow checking without lifetimes
https://smallcultfollowing.com/babysteps/blog/2024/03/04/borrow-checking-without-lifetimes/?utm_source=atom_feed
<p>This blog post explores an alternative formulation of Rust’s type system that eschews <em>lifetimes</em> in favor of <em>places</em>. The TL;DR is that instead of having <code>'a</code> represent a <em>lifetime</em> in the code, it can represent a set of <em>loans</em>, like <code>shared(a.b.c)</code> or <code>mut(x)</code>. If this sounds familiar, it should, it’s the basis for <a href="https://smallcultfollowing.com/babysteps/blog/2023/09/22/polonius-part-1/">polonius</a>, but reformulated as a type system instead of a static analysis. This blog post is just going to give the high-level ideas. In follow-up posts I’ll dig into how we can use this to support interior references and other advanced borrowing patterns. In terms of implementation, I’ve mocked this up a bit, but I intend to start extending <a href="https://github.com/rust-lang/a-mir-formality">a-mir-formality</a> to include this analysis.</p>
<h3>Why would you want to replace lifetimes?</h3>
<p>Lifetimes are the best and worst part of Rust. The best in that they let you express very cool patterns, like returning a pointer into some data in the middle of your data structure. But they’ve got some serious issues. For one, the idea of what a lifetime is rather abstract, and hard for people to grasp (“what does <code>'a</code> actually represent?”). But also Rust is not able to express some important patterns, most notably interior references, where one field of a struct refers to data owned by another field.</p>
<h3>So what <em>is</em> a lifetime exactly?</h3>
<p>Here is the definition of a lifetime from the RFC on non-lexical lifetimes:</p>
<blockquote>
<p>Whenever you create a borrow, the compiler assigns the resulting reference a lifetime. This lifetime corresponds to the span of the code where the reference may be used. The compiler will infer this lifetime to be the smallest lifetime that it can have that still encompasses all the uses of the reference.</p>
</blockquote>
<p><a href="https://rust-lang.github.io/rfcs/2094-nll.html#what-is-a-lifetime">Read the RFC for more details.</a></p>
<h3>Replacing a <em>lifetime</em> with an <em>origin</em></h3>
<p>Under this formulation, <code>'a</code> no longer represents a <em>lifetime</em> but rather an <strong>origin</strong> – i.e., it explains where the reference may have come from. We define an origin as a <strong>set of loans</strong>. Each loan captures some <strong>place expression</strong> (e.g. <code>a</code> or <code>a.b.c</code>), that has been borrowed along with the mode in which it was borrowed (<code>shared</code> or <code>mut</code>).</p>
<pre tabindex="0"><code>Origin = { Loan }
Loan = shared(Place)
| mut(Place)
Place = variable(.field)* // e.g., a.b.c
</code></pre><h3>Defining types</h3>
<p>Using origins, we can define Rust types roughly like this (obviously I’m ignoring a bunch of complexity here…):</p>
<pre tabindex="0"><code>Type = TypeName < Generic* >
| & Origin Type
| & Origin mut Type
TypeName = u32 (for now I'll ignore the rest of the scalars)
| () (unit type, don't worry about tuples)
| StructName
| EnumName
| UnionName
Generic = Type | Origin
</code></pre><p>Here is the first interesting thing to note: there is no <code>'a</code> notation here! This is because I’ve not introduced generics yet. Unlike Rust proper, this formulation of the type system has a concrete syntax (<code>Origin</code>) for what <code>'a</code> represents.</p>
<h3>Explicit types for a simple program</h3>
<p>Having a fully explicit type system also means we can easily write out example programs where all types are fully specified. This used to be rather challenging because we had no notation for lifetimes. Let’s look at a simple example, a program that ought to get an error:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">counter</span>: <span class="kt">u32</span> <span class="o">=</span><span class="w"> </span><span class="mi">22_</span><span class="k">u32</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">let</span><span class="w"> </span><span class="n">p</span>: <span class="kp">&</span> <span class="cm">/*{shared(counter)}*/</span><span class="w"> </span><span class="kt">u32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">counter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ---------------------
</span></span></span><span class="line"><span class="cl"><span class="c1">// no syntax for this today!
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">counter</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// Error: cannot mutate `counter` while `p` is live
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="fm">println!</span><span class="p">(</span><span class="s">"</span><span class="si">{p}</span><span class="s">"</span><span class="p">);</span><span class="w">
</span></span></span></code></pre></div><p>Apart from the type of <code>p</code>, this is valid Rust. Of course, it won’t compile, because we can’t modify <code>counter</code> while there is a live shared reference <code>p</code> (<a href="https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1a05f0a4aad12c33345ca4adc1cd9bb2">playground</a>). As we continue, you will see how the new type system formulation arrives at the same conclusion.</p>
<h3>Basic typing judgments</h3>
<p>Typing judgments are the standard way to describe a type system. We’re going to phase in the typing judgments for our system iteratively. We’ll start with a simple, fairly standard formulation that doesn’t include borrow checking, and then show how we introduce borrow checking. For this first version, the typing judgment we are defining has the form</p>
<pre tabindex="0"><code>Env |- Expr : Type
</code></pre><p>This says, “in the environment <code>Env</code>, the expression <code>Expr</code> is legal and has the type <code>Type</code>”. The <em>environment</em> <code>Env</code> here defines the local variables in scope. The Rust expressions we are looking at for our <a href="https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1a05f0a4aad12c33345ca4adc1cd9bb2">sample program</a> are pretty simple:</p>
<pre tabindex="0"><code>Expr = integer literal (e.g., 22_u32)
| & Place
| Expr + Expr
| Place (read the value of a place)
| Place = Expr (overwrite the value of a place)
| ...
</code></pre><p>Since we only support one scalar type (<code>u32</code>), the typing judgment for <code>Expr + Expr</code> is as simple as:</p>
<pre tabindex="0"><code>Env |- Expr1 : u32
Env |- Expr2 : u32
----------------------------------------- addition
Env |- Expr1 + Expr2 : u32
</code></pre><p>The rule for <code>Place = Expr</code> assignments is based on subtyping:</p>
<pre tabindex="0"><code>Env |- Expr : Type1
Env |- Place : Type2
Env |- Type1 <: Type2
----------------------------------------- assignment
Env |- Place = Expr : ()
</code></pre><p>The rule for <code>&Place</code> is somewhat more interesting:</p>
<pre tabindex="0"><code>Env |- Place : Type
----------------------------------------- shared references
Env |- & Place : & {shared(Place)} Type
</code></pre><p>The rule just says that we figure out the type of the place <code>Place</code> being borrowed (here, the place is <code>counter</code> and its type will be <code>u32</code>) and then we have a resulting reference to that type. The origin of that reference will be <code>{shared(Place)}</code>, indicating that the reference came from <code>Place</code>:</p>
<pre tabindex="0"><code>&{shared(Place)} Type
</code></pre><h3>Computing liveness</h3>
<p>To introduce borrow checking, we need to phase in the idea of <strong>liveness</strong>.<sup id="fnref:1"><a class="footnote-ref" href="http://smallcultfollowing.com/babysteps/atom.xml#fn:1">1</a></sup> If you’re not familiar with the concept, the NLL RFC has a <a href="https://rust-lang.github.io/rfcs/2094-nll.html#liveness">nice introduction</a>:</p>
<blockquote>
<p>The term “liveness” derives from compiler analysis, but it’s fairly intuitive. We say that a variable is live if the current value that it holds may be used later.</p>
</blockquote>
<p>Unlike with NLL, where we just computed live <strong>variables</strong>, we’re going to compute <strong>live places</strong>:</p>
<pre tabindex="0"><code>LivePlaces = { Place }
</code></pre><p>To compute the set of live places, we’ll introduce a helper function <code>LiveBefore(Env, LivePlaces, Expr): LivePlaces</code>. <code>LiveBefore()</code> returns the set of places that are live before <code>Expr</code> is evaluated, given the environment <code>Env</code> and the set of places live after expression. I won’t define this function in detail, but it looks roughly like this:</p>
<pre tabindex="0"><code>// `&Place` reads `Place`, so add it to `LivePlaces`
LiveBefore(Env, LivePlaces, &Place) =
LivePlaces ∪ {Place}
// `Place = Expr` overwrites `Place`, so remove it from `LivePlaces`
LiveBefore(Env, LivePlaces, Place = Expr) =
LiveBefore(Env, (LivePlaces - {Place}), Expr)
// `Expr1` is evaluated first, then `Expr2`, so the set of places
// live after expr1 is the set that are live *before* expr2
LiveBefore(Env, LivePlaces, Expr1 + Expr2) =
LiveBefore(Env, LiveBefore(Env, LivePlaces, Expr2), Expr1)
... etc ...
</code></pre><h3>Integrating liveness into our typing judgments</h3>
<p>To detect borrow check errors, we need to adjust our typing judgment to include liveness. The result will be as follows:</p>
<pre tabindex="0"><code>(Env, LivePlaces) |- Expr : Type
</code></pre><p>This judgment says, “in the environment <code>Env</code>, and given that the function will access <code>LivePlaces</code> in the future, <code>Expr</code> is valid and has type <code>Type</code>”. Integrating liveness in this way gives us some idea of what accesses will happen in the future.</p>
<p>For compound expressions, like <code>Expr1 + Expr2</code>, we have to adjust the set of live places to reflect control flow:</p>
<pre tabindex="0"><code>LiveAfter1 = LiveBefore(Env, LiveAfter2, Expr2)
(Env, LiveAfter1) |- Expr1 : u32
(Env, LiveAfter2) |- Expr2 : u32
----------------------------------------- addition
(Env, LiveAfter2) |- Expr1 + Expr2 : u32
</code></pre><p>We start out with <code>LiveAfter2</code>, i.e., the places that are live after the entire expression. These are also the same as the places live after expression 2 is evaluated, since this expression doesn’t itself reference or overwrite any places. We then compute <code>LiveAfter1</code> – i.e., the places live after <code>Expr1</code> is evaluated – by looking at the places that are live <em>before</em> <code>Expr2</code>. This is a bit mind-bending and took me a bit of time to see. The tricky bit here is that liveness is computed <em>backwards</em>, but most of our typing rules (and intution) tends to flow <em>forwards</em>. If it helps, think of the “fully desugared” version of <code>+</code>:</p>
<pre tabindex="0"><code>let tmp0 = <Expr1>
// <-- the set LiveAfter1 is live here (ignoring tmp0, tmp1)
let tmp1 = <Expr2>
// <-- the set LiveAfter2 is live here (ignoring tmp0, tmp1)
tmp0 + tmp1
// <-- the set LiveAfter2 is live here
</code></pre><h3>Borrow checking with liveness</h3>
<p>Now that we know liveness information, we can use it to do borrow checking. We’ll introduce a “permits” judgment:</p>
<pre tabindex="0"><code>(Env, LiveAfter) permits Loan
</code></pre><p>that indicates that “taking the loan Loan would be allowed given the environment and the live places”. Here is the rule for assignments, modified to include liveness and the new “permits” judgment:</p>
<pre tabindex="0"><code>(Env, LiveAfter - {Place}) |- Expr : Type1
(Env, LiveAfter) |- Place : Type2
(Env, LiveAfter) |- Type1 <: Type2
(Env, LiveAfter) permits mut(Place)
----------------------------------------- assignment
(Env, LiveAfter) |- Place = Expr : ()
</code></pre><p>Before I dive into how we define “permits”, let’s go back to our example and get an intution for what is going on here. We want to declare an error on this assigment:</p>
<div class="highlight"><pre class="chroma" tabindex="0"><code class="language-rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">counter</span>: <span class="kt">u32</span> <span class="o">=</span><span class="w"> </span><span class="mi">22_</span><span class="k">u32</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">let</span><span class="w"> </span><span class="n">p</span>: <span class="kp">&</span><span class="p">{</span><span class="n">shared</span><span class="p">(</span><span class="n">counter</span><span class="p">)}</span><span class="w"> </span><span class="kt">u32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">counter</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">counter</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// <-- Error
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="fm">println!</span><span class="p">(</span><span class="s">"</span><span class="si">{p}</span><span class="s">"</span><span class="p">);</span><span class="w"> </span><span class="c1">// <-- p is live
</span></span></span></code></pre></div><p>Note that, because of the <code>println!</code> on the next line, <code>p</code> will be in our <code>LiveAfter</code> set. Looking at the type of <code>p</code>, we see that it includes the loan <code>shared(counter)</code>. The idea then is that mutating counter is illegal because there is a live loan <code>shared(counter)</code>, which implies that <code>counter</code> must be immutable.</p>
<p>Restating that intution:</p>
<blockquote>
<p>A set <code>Live</code> of live places <em>permits</em> a loan <code>Loan1</code> if, for every live place <code>Place</code> in <code>Live</code>, the loans in the type of <code>Place</code> are compatible with <code>Loan1</code>.</p>
</blockquote>
<p>Written more formally:</p>
<pre tabindex="0"><code>∀ Place ∈ Live {
(Env, Live) |- Place : Type
∀ Loan2 ∈ Loans(Type) { Compatible(Loan1, Loan2) }
}
-----------------------------------------
(Env, Live) permits Loan1
</code></pre><p>This definition makes use of two helper functions:</p>
<ul>
<li><code>Loans(Type)</code> – the set of loans that appear in the type</li>
<li><code>Compatible(Loan1, Loan2)</code> – defines if two loans are compatible. Two shared loans are always compatible. A mutable loan is only compatible with another loan if the places are disjoint.</li>
</ul>
<h3>Conclusion</h3>
<p>The goal of this post was to give a high-level intution. I wrote it from memory, so I’ve probably overlooked a thing or two. In follow-up posts though I want to go deeper into how the system I’ve been playing with works and what new things it can support. Some high-level examples:</p>
<ul>
<li>How to define subtyping, and in particular the role of liveness in subtyping</li>
<li>Important borrow patterns that we use today and how they work in the new system</li>
<li>Interior references that point at data owned by other struct fields and how it can be supported</li>
</ul>
<div class="footnotes">
<hr />
<ol>
<li id="fn:1">
<p>If this is not obvious to you, don’t worry, it wasn’t obvious to me either. It turns out that using liveness in the rules is the key to making them simple. I’ll try to write a follow-up about the alternatives I explored and why they don’t work later on. <a class="footnote-backref" href="http://smallcultfollowing.com/babysteps/atom.xml#fnref:1">↩︎</a></p>
</li>
</ol>
</div>2024-03-04T18:29:34+00:00Mozilla Thunderbird: Towards Thunderbird for Android – K-9 Mail 6.800 Simplifies Adding Email Accounts
https://blog.thunderbird.net/2024/03/towards-thunderbird-for-android-k-9-mail-6-800-simplifies-adding-email-accounts/
<p><img alt="Graphic announcing "Thunderbird for Android" with a Thunderbird icon, and "K-9 Mail 6.800 Released" with a red envelope icon representing K-9 Mail" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2024/03/K-9-Mail-6.800-768x432.jpg" width="640" /></p>
<p>We’re happy to announce the release of K-9 Mail 6.800. The main goal of this version is to make it easier for you to add your email accounts to the app.</p>
<p>With another item crossed off the <a href="https://developer.thunderbird.net/planning/android-roadmap">list</a>, this brings us <a href="https://blog.thunderbird.net/2023/12/when-will-thunderbird-for-android-be-released/">one step closer towards Thunderbird for Android.</a></p>
<h3>New account setup</h3>
<p>Setting up an email account in K-9 Mail is something many new users have struggled with in the past. That’s mainly because automatic setup was only supported for a handful of large email providers. If you had an email account with another email provider, you had to manually enter the incoming and outgoing server settings. But finding the correct server settings can be challenging. </p>
<p>So we set out to improve the setup experience. Since this part of the app was quite old and had a couple of other problems, we used this opportunity to rewrite the whole account setup component. This turned out to be more work than originally anticipated. But we’re quite happy with the result.</p>
<p>Let’s have a brief look at the steps involved in setting up a new account.</p>
<h4>1. Enter email address</h4>
<p>To get the process started, all you have to do is enter the email address of the account you want to set up in K-9 Mail.</p>
<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_enter_email_address.png"><img alt="" class="wp-image-1582" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_enter_email_address-600x1270.png" style="width: 350px;" width="600" /></a></figure></div>
<h4>2. Provide login credentials</h4>
<p>After tapping the <em>Next</em> button, the app will use Thunderbird’s Autoconfig mechanism to try to find the appropriate incoming and outgoing server settings. Then you’ll be asked to provide a password or use the web login flow, depending on the email provider.</p>
<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_configuration_found.png"><img alt="" class="wp-image-1583" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_configuration_found-600x1270.png" width="600" /></a></figure>
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_sign_in.png"><img alt="" class="wp-image-1586" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_sign_in-600x1270.png" width="600" /></a></figure>
</figure>
<p>The app will then try to log in to the incoming and outgoing server using the provided credentials.</p>
<h4>3. Provide some basic information about the account</h4>
<p>If your login credentials check out, you’ll be asked to provide your name for outgoing messages. For all the other inputs you can go with the defaults. All settings can be changed later, once an account has been set up.</p>
<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_display_options.png"><img alt="" class="wp-image-1584" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_display_options-600x1270.png" width="600" /></a></figure>
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_sync_options.png"><img alt="" class="wp-image-1585" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_6.8_sync_options-600x1270.png" width="600" /></a></figure>
</figure>
<p>If everything goes well, that’s all it takes to set up an account.</p>
<p>Of course there’s still cases where the app won’t be able to automatically find a configuration and the user will be asked to manually provide the incoming and outgoing server settings. But we’ll be working with email providers to hopefully reduce the number of times this happens.</p>
<h3>What else is new?</h3>
<p>While the account setup rewrite was our main development focus, we’ve also made a couple of smaller changes and bug fixes. You can find a list of the most notable ones below.</p>
<h4>Improvements and behavior changes</h4>
<ul>
<li>Made it harder to accidentally trigger swipe actions in the message list screen</li>
<li>IMAP: Added support for sending the ID command (that is required by some email providers)</li>
<li>Improved screen reader experience in various places</li>
<li>Improved display of some HTML messages</li>
<li>Changed background color in message view and compose screens when using dark theme</li>
<li>Adding to contacts should now allow you again to add the email address to an existing contact</li>
<li>Added image handling within the context menu for hyperlinks</li>
<li>A URI pasted when composing a message will now be surrounded by angle brackets</li>
<li>Don’t use nickname as display name when auto-completing recipient using the nickname</li>
<li>Changed compose icon in the message list widget to match the icon inside the app</li>
<li>Don’t attempt to open file: URIs in an email; tapping such a link will now copy the URL to the clipboard instead</li>
<li>Added option to return to the message list after marking a message as unread in the message view</li>
<li>Combined settings “Return to list after delete” and “Show next message after delete” into “After deleting or moving a message”</li>
<li>Moved “Show only subscribed folders” setting to “Folders” section</li>
<li>Added copy action to recipient dropdown in compose screen (to work around missing drag & drop functionality)</li>
<li>Simplified the app icon so it can be a vector drawable</li>
<li>Added support for the IMAP MOVE extension</li>
</ul>
<h4>Bug fixes</h4>
<ul>
<li>Fixed bug where account name wasn’t displayed in the message view when it should</li>
<li>Fixed bugs with importing and exporting identities</li>
<li>The app will no longer ask to save a draft when no changes have been made to an existing draft message</li>
<li>Fixed bug where “Cannot connect to crypto provider” was displayed when the problem wasn’t the crypto provider</li>
<li>Fixed a crash caused by an interaction with OpenKeychain 6.0.0</li>
<li>Fixed inconsistent behavior when replying to messages</li>
<li>Fixed display issue with recipients in message view screen</li>
<li>Fixed display issues when rendering a message/rfc822 inline part</li>
<li>Fixed display issue when removing an account</li>
<li>Fixed notification sounds on WearOS devices</li>
<li>Fixed the app so it runs on devices that don’t support home screen widgets</li>
</ul>
<h4>Other changes</h4>
<ul>
<li>Removed Hebrew and Korean translations because of how incomplete they were; <a href="https://hosted.weblate.org/projects/tb-android/">volunteer translators welcome</a>!</li>
</ul>
<h4>Known issues</h4>
<ul>
<li>A fresh app install on Android 14 will be missing the “alarms & reminders” permission required for Push to work. Please allow setting alarms and reminders in Android’s app settings under <em>Alarms & reminders</em>.</li>
<li>Some software keyboards automatically capitalize words when entering the email address in the first account setup screen.</li>
<li>When a password containing line breaks is pasted during account setup, these line breaks are neither ignored nor flagged as an error. This will most likely lead to an authentication error when checking server settings.</li>
</ul>
<h3>Where To Get K-9 Mail Version 6.800</h3>
<p>Version 6.800 has started gradually rolling out. As always, you can get it on the following platforms:</p>
<p><a href="https://github.com/thundernest/k-9/releases/tag/6.800">GitHub</a> | <a href="http://f-droid.org/packages/com.fsck.k9/">F-Droid</a> | <a href="https://play.google.com/store/apps/details?id=com.fsck.k9">Play Store</a></p>
<p>(Note that the release will gradually roll out on the Google Play Store, and should appear shortly on F-Droid, so please be patient if it doesn’t automatically update.)</p>
<p>The post <a href="https://blog.thunderbird.net/2024/03/towards-thunderbird-for-android-k-9-mail-6-800-simplifies-adding-email-accounts/">Towards Thunderbird for Android – K-9 Mail 6.800 Simplifies Adding Email Accounts</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p>2024-03-04T14:00:00+00:00ckettiMozilla Addons Blog: Developer Spotlight: YouTube Search Fixer
https://blog.mozilla.org/addons/2024/03/01/developer-spotlight-youtube-search-fixer/
<p>Like a lot of us during the pandemic lockdown, Shubham Bose found himself consuming more YouTube content than ever before. That’s when he started to notice all the unwanted oddities appearing in his YouTube search results — irrelevant suggested videos, shorts, playlists, etc. Shubham wanted a cleaner, more focused search experience, so he decided to do something about it. He built <a href="https://addons.mozilla.org/firefox/addon/youtube-suite-search-fixer/" rel="noopener" target="_blank">YouTube Search Fixer</a>. The extension streamlines YouTube search results in a slew of customizable ways, like removing “For you,” “People also search for,” “Related to your search,” and so on. You can also remove entire types of content like shorts, live streams, auto-generated mixes, and more.</p>
<div class="wp-caption alignleft" id="attachment_9138" style="width: 262px;"><img alt="" class="size-medium wp-image-9138" height="463" src="https://blog.mozilla.org/addons/files/2024/03/blog_YTSF_UI-252x463.png" width="252" /><p class="wp-caption-text" id="caption-attachment-9138">The extension makes it easy to customize YouTube to suit you.</p></div>
<p>Early versions of the extension were less customizable and removed most types of suggested search results by default, but over time Shubham learned that different users want different things in their search results. “I realized the line between ‘helpful’ and ‘distracting’ is very subjective,” explains Shubham. “What one person finds useful, another might not. Ultimately, it’s up to the user to decide what works best for them. That’s why I decided to give users granular control using an Options page. Now people can go about hiding elements they find distracting while keeping those they deem helpful. It’s all about striking that personal balance.”</p>
<p>Despite YouTube Search Fixer’s current wealth of customization options (a cool new feature automatically redirects Shorts to their normal length versions), Shubham plans to expand his extension’s feature set. He’s considering keyword highlighting and denylist options, which would give users extreme control over search filtering.</p>
<p>More than solving what he felt was a problem with YouTube’s default search results, Shubham was motivated to build his extension as a “way of giving back to a community I deeply appreciate… I’ve used Firefox since I was in high school. Like countless others, I’ve benefited greatly from the ever helpful <a href="https://developer.mozilla.org/" rel="noopener" target="_blank">MDN Web Docs</a> and the incredible <a href="https://addons.mozilla.org/firefox/" rel="noopener" target="_blank">add-ons ecosystem</a> Mozilla hosts and helps thrive. They offer nice developer tools and cultivate a helpful and welcoming community. So making this was my tiny way of giving back and saying ‘thank you’.”</p>
<div class="wp-caption aligncenter" id="attachment_9139" style="width: 610px;"><img alt="" class="wp-image-9139 size-large" height="338" src="https://blog.mozilla.org/addons/files/2024/03/blog_YTSF_flower-600x338.png" width="600" /><p class="wp-caption-text" id="caption-attachment-9139">When he’s not writing extensions that improve the world’s most popular video streaming site, Shubham enjoys photographing his home garden in Lucknow, India. “It isn’t just a hobby,” he explains. “Experimenting with light, composition and color has helped me focus on visual aesthetics (in software development). Now, I actively pay attention to little details when I create visually appealing and user-friendly interfaces.”</p></div>
<p><i>Do you have an intriguing extension development story? Do tell! Maybe your story should appear on this blog. Contact us at </i><b><i>amo-featured [at] mozilla [dot] org</i></b><i> and let us know a bit about your extension development journey. </i></p>
<p>The post <a href="https://blog.mozilla.org/addons/2024/03/01/developer-spotlight-youtube-search-fixer/">Developer Spotlight: YouTube Search Fixer</a> appeared first on <a href="https://blog.mozilla.org/addons">Mozilla Add-ons Community Blog</a>.</p>2024-03-01T19:43:06+00:00Scott DeVaneyMozilla Thunderbird: Thunderbird Monthly Development Digest: February 2024
https://blog.thunderbird.net/2024/02/thunderbird-monthly-development-digest-february-2024/
<p><img alt="Stylized Thunderbird icon with a code prompt in its center, against a purple background." class="attachment-640x360 size-640x360 wp-post-image" height="320" src="https://blog.thunderbird.net/files/2024/01/Developer-banner.png" width="640" /></p>
<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=de&u=https://blog.thunderbird.net/2024/02/thunderbird-monthly-development-digest-february-2024/" rel="noreferrer noopener" target="_blank">Auf Deutsch übersetzen</a></div>
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=fr&u=https://blog.thunderbird.net/2024/02/thunderbird-monthly-development-digest-february-2024/" rel="noreferrer noopener" target="_blank">Traduire en français</a></div>
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=ja&u=https://blog.thunderbird.net/2024/02/thunderbird-monthly-development-digest-february-2024/">日本語に翻訳</a></div>
</div>
<p>Hello Thunderbird Community! I can’t believe it’s already the end of February. Time goes by very fast and it seems that there’s never enough time to do all the things that you set your mind to. Nonetheless, it’s that time of the month again for a juicy and hopefully interesting Thunderbird Development Digest. </p>
<p>If this is your first time reading our monthly Dev Digest, these are short posts to give our community visibility into features and updates being planned for Thunderbird, as well as progress reports on work that’s in the early stages of development. </p>
<p>Let’s jump right into it, because there’s a lot to get excited about! </p>
<h3 class="wp-block-heading"><strong>Rust and Exchange</strong></h3>
<p>Things are moving steadily on this front. Maybe not as fast as we would like, but we’re handling a complicated implementation and we’re adding a new protocol for the first time in more than a decade, so some friction is to be expected.</p>
<p>Nonetheless, you can start following the progress in our <a href="https://github.com/thunderbird/thundercell">Thundercell repository</a>. We’re using this repo to temporarily “park” crates and other libraries we’re aiming to vendor inside Thunderbird.</p>
<p>We’re aiming at reaching an alpha state where we can land in Thunderbird later next month and start asking for user feedback on Daily.</p>
<h3 class="wp-block-heading"><strong>Mozilla Account + Thunderbird Sync</strong></h3>
<div class="wp-block-image">
<figure class="alignright size-full is-resized"><a href="https://blog.thunderbird.net/files/2024/02/Sync-Doodle-Alex-e1709165902878.png"><img alt="Illustration of a continuous cycle with a web browser window, a sync or update icon, and a server rack, indicating a process of technological interaction or data exchange." class="wp-image-1576" src="https://blog.thunderbird.net/files/2024/02/Sync-Doodle-Alex.png" style="width: 398px; height: auto;" /></a><figcaption class="wp-element-caption">Illustration by Alessandro Castellani</figcaption></figure></div>
<p>Things are moving forward on this front as well. We’re currently in the process of setting up our own SyncServer and TokenStorage in order to allow users to log in with their Mozilla Account but sync the Thunderbird data in an independent location from the Firefox data. This gives us an extra layer of security as it will prevent an app from accessing the other app’s data and vice versa.</p>
<p>In case you didn’t know, you can already use a Mozilla account and Sync on Daily, but this only works with a staging server and you’ll need an alternate Mozilla account for testing. There are a couple of known bugs but overall things seem to be working properly. Once we switch to our storage server, we will expose this feature more and enable it on Beta for everyone to test.</p>
<h3 class="wp-block-heading"><strong>Oh, Snap!</strong></h3>
<p>Our continuous efforts to own our packages and distribution methods is moving forward with the internal creation of a Snap package. (For background, last year we took ownership of the <a href="https://flathub.org/apps/org.mozilla.Thunderbird">Thunderbird Flatpak</a>.)</p>
<figure class="wp-block-image size-full is-resized"><a href="https://blog.thunderbird.net/files/2024/02/packages-1.jpg"><img alt="" class="wp-image-1589" height="707" src="https://blog.thunderbird.net/files/2024/02/packages-1.jpg" style="width: 648px; height: auto;" width="2048" /></a></figure>
<p>We’re currently internally testing the Beta and things seem to work accordingly. We will announce it publicly when it’s available from the Snap Store, with the objective of offering both Stable and Beta channels.</p>
<p>We’re exploring the possibility of also offering a Daily channel, but that’s a bit more complicated and we will need more time to make sure it’s doable and automated, so stay tuned.</p>
<p>As usual, if you want to see things as they land you can always check the <a href="https://hg.mozilla.org/comm-central/pushloghtml">pushlog </a>and <a href="https://ftp.mozilla.org/pub/thunderbird/nightly/2024/">try running daily</a>, which would be immensely helpful for catching bugs early.</p>
<p>See ya next month,</p>
<p><strong>Alessandro Castellani</strong> <em>(he, him)<br /></em><strong>Director of Product Engineering</strong></p>
<figure class="wp-block-pullquote" style="border-width: 2px; border-radius: 10px; font-style: normal; font-weight: 400;"><blockquote><p>If you’re interested in joining the technical discussion around Thunderbird development, consider joining one or several of our <a href="https://thunderbird.topicbox.com">mailing list groups here</a>. </p></blockquote></figure>
<p>The post <a href="https://blog.thunderbird.net/2024/02/thunderbird-monthly-development-digest-february-2024/">Thunderbird Monthly Development Digest: February 2024</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p>2024-02-29T13:00:00+00:00Alessandro CastellaniThis Week In Rust: This Week in Rust 536
https://this-week-in-rust.org/blog/2024/02/28/this-week-in-rust-536/
<p>Hello and welcome to another issue of <em>This Week in Rust</em>!
<a href="https://www.rust-lang.org/">Rust</a> is a programming language empowering everyone to build reliable and efficient software.
This is a weekly summary of its progress and community.
Want something mentioned? Tag us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> on Twitter or <a href="https://mastodon.social/@thisweekinrust">@ThisWeekinRust</a> on mastodon.social, or <a href="https://github.com/rust-lang/this-week-in-rust">send us a pull request</a>.
Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p>
<p><em>This Week in Rust</em> is openly developed <a href="https://github.com/rust-lang/this-week-in-rust">on GitHub</a> and archives can be viewed at <a href="https://this-week-in-rust.org/">this-week-in-rust.org</a>.
If you find any errors in this week's issue, <a href="https://github.com/rust-lang/this-week-in-rust/pulls">please submit a PR</a>.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-rust-community">Updates from Rust Community</a></h4>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#projecttooling-updates">Project/Tooling Updates</a></h5>
<ul>
<li><a href="https://servo.org/blog/2024/02/28/gamepads-font-fallback-space-jam/">This month in Servo: gamepad support, font fallback, Space Jam, and more!</a></li>
<li><a href="https://bytecodealliance.org/articles/jco-1.0">Announcing Jco 1.0</a></li>
<li><a href="https://www.lpalmieri.com/posts/this-month-in-pavex-09/">This month in Pavex, #9</a></li>
<li><a href="https://argmin-rs.org/blog/version-v0-10-0/">argmin 0.10.0 - a Rust crate for numerical optimization</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#observationsthoughts">Observations/Thoughts</a></h5>
<ul>
<li><a href="https://maximkaaa.github.io/galileo/blog/posts/text_rendering_design/">Text labels rendering on a map with Rust - research and design</a></li>
<li><a href="https://devclass.com/2024/02/20/rust-developers-fear-language-is-getting-too-complex-and-prefer-bug-fixes-to-new-features/">Rust developers fear language is getting too complex and prefer bug fixes to new features</a></li>
<li><a href="https://www.codethink.co.uk/articles/2024/distributed_system_rust/">Lessons learnt from building a distributed system in Rust</a></li>
<li><a href="https://filtra.io/rust-amp-feb-24">How Rust Could Change Robotics</a></li>
<li><a href="https://without.boats/blog/asynchronous-clean-up/">Asynchronous clean-up</a></li>
<li><a href="https://apollolabsblog.hashnode.dev/edge-iot-with-rust-on-esp-ping">Edge IoT with Rust on ESP: Ping!</a></li>
<li><a href="https://apollolabsblog.hashnode.dev/esp-embedded-rust-command-line-interface">ESP Embedded Rust: Command Line Interface</a></li>
<li><a href="https://apollolabsblog.hashnode.dev/esp-embedded-rust-ping-cli-app-part-2">ESP Embedded Rust: Ping CLI App Part 2</a></li>
<li><a href="https://crustc.com/string-to-int-in-rust/">Convert a String to int in Rust</a></li>
<li><a href="https://asyncmove.com/blog/2024/02/mastering-manuallydropt-a-guide-to-explicit-resource-management-in-rust/">Mastering <code>ManuallyDrop<T></code> - A Guide to Explicit Resource Management in Rust</a></li>
<li><a href="https://hegdenu.net/posts/rust-but-async/">Rust, but async</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-walkthroughs">Rust Walkthroughs</a></h5>
<ul>
<li><a href="https://www.jacobelder.com/2024/02/26/rust-matching-and-iterators.html">Matching and iterators in Rust</a></li>
<li><a href="https://dev-state.com/posts/error_handling/">Practical guide to Error Handling in Rust</a></li>
<li><a href="https://tweedegolf.nl/en/blog/114/building-an-async-runtime-with-mio">Building an Async Runtime with mio</a></li>
<li>[HE] [video] <a href="https://www.youtube.com/playlist?list=PLm2NBp4tb5F3QZNMW6bEt3IoAQAu2LAPs">Rust Course</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#miscellaneous">Miscellaneous</a></h5>
<ul>
<li><a href="https://blog.logrocket.com/guide-using-tensorflow-rust/">Guide to using TensorFlow in Rust</a></li>
<li><a href="https://justinpombrio.net/2024/02/23/a-twist-on-Wadlers-printer.html">A Twist on Wadler's Printer</a></li>
<li><a href="https://www.shuttle.rs/blog/2024/02/22/api-rate-limiting-rust">Implementing API Rate Limiting in Rust</a></li>
<li><a href="https://bencher.dev/learn/benchmarking/rust/iai/">How to benchmark Rust code with Iai</a></li>
<li><a href="https://tweedegolf.nl/en/blog/115/sequential-storage-efficiently-store-data-in-flash">Sequential-storage: efficiently store data in flash</a></li>
<li>[audio] <a href="https://corrode.dev/podcast/s01e06-sentry/">Sentry - Rust in Production Podcast</a></li>
<li>[video] <a href="https://www.youtube.com/watch?v=-gkvOoxgp8E">A First Look at Lifetimes in Rust</a></li>
<li>[video] <a href="https://www.youtube.com/watch?v=VH4z60akQuM">Firmware for an ESP32 to read from a noise sensor in Rust</a></li>
</ul>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#crate-of-the-week">Crate of the Week</a></h4>
<p>This week's crate is <a href="https://github.com/orottier/web-audio-api-rs">web-audio-api-rs</a>, a Rust implementation of the Web Audio API for use <em>outside</em> the browser.</p>
<p>Thanks to <a href="https://users.rust-lang.org/t/crate-of-the-week/2704/1292">Otto Rottier</a> for the self-suggestion!</p>
<p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Please submit your suggestions and votes for next week</a>!</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-testing"></a><a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">Call for Testing</a></h4>
<p>An important step for RFC implementation is for people to experiment with the
implementation and give feedback, especially before stabilization. The following
RFCs would benefit from user testing before moving forward:</p>
<ul>
<li><em>No RFCs issued a call for testing this week.</em></li>
</ul>
<p>If you are a feature implementer and would like your RFC to appear on the above list, add the new <code>call-for-testing</code>
label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the feature
need testing.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-participation-projects-and-speakers">Call for Participation; projects and speakers</a></h4>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-projects">CFP - Projects</a></h5>
<p>Always wanted to contribute to open-source projects but did not know where to start?
Every week we highlight some tasks from the Rust community for you to pick and get started!</p>
<p>Some of these tasks may also have mentors available, visit the task page for more information.</p>
<ul>
<li><a href="https://github.com/juspay/hyperswitch/issues/3749"> Hyperswitch - [FEATURE] : add <code>offset</code> field to disputes list</a></li>
<li><a href="https://github.com/juspay/hyperswitch/issues/3748"> Hyperswitch - [FEATURE]: add<code>offset</code> field to mandates list</a></li>
<li><a href="https://github.com/build-trust/ockam/issues/7625">Ockam - <code>ockam node create --identity X</code> should fail if <code>X</code> doesn't exist</a></li>
<li><a href="https://github.com/build-trust/ockam/issues/7478">Ockam - Output for <code>ockam project ticket</code> is improved and information is not opaque</a></li>
<li><a href="https://github.com/build-trust/ockam/issues/7473">Ockam - Output for both <code>ockam project ticket</code> and <code>ockam project enroll</code> is improved, with support for <code>--output json</code></a></li>
<li><a href="https://github.com/google/zerocopy/issues/953">ZeroCopy - In zerocopy-derive UI tests, detect whether we're building with <code>RUSTFLAGS='-Wwarnings'</code></a></li>
</ul>
<p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://users.rust-lang.org/t/twir-call-for-participation/4821">here</a>.</p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-speakers">CFP - Speakers</a></h5>
<p>Are you a new or experienced speaker looking for a place to share something cool? This section highlights events that are being planned and are accepting submissions to join their event as a speaker.</p>
<p>If you are an event organizer hoping to expand the reach of your event, please submit a link to the submission website through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a>.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-the-rust-project">Updates from the Rust Project</a></h4>
<p>430 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2024-02-20..2024-02-27">merged in the last week</a></p>
<ul>
<li><a href="https://github.com/rust-lang/rust/pull/120393">Avoid non-local definitions in functions</a> (RFC <a href="https://rust-lang.github.io/rfcs/3373-avoid-nonlocal-definitions-in-fns.html">#3373</a>)</li>
<li><a href="https://github.com/rust-lang/rust/pull/120588">wasm: store rlib metadata in wasm object files</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121435">account for RPITIT in E0310 explicit lifetime constraint suggestion</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121617">actually use the right closure kind when checking async Fn goals</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121114">add <code>#[rustc_no_mir_inline]</code> for standard library UB checks</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121482">allow for a missing <code>adt_def</code> in <code>NamePrivacyVisitor</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119106">avoid generalization inside of aliases</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121493">by changing some attributes to <code>only_local,</code> reducing encoding attributes in the crate metadate</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121628">do not const prop unions</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121470">don't ICE on anonymous <code>struct</code> in <code>enum</code> variant</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121344">expand weak alias types before collecting constrained/referenced late bound regions + refactorings</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121427">fix panic when compiling <code>Rocket</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121309">make intrinsic fallback bodies cross-crate inlineable</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121396">make it possible for outside crates to inspect a <code>mir::ConstValue</code> with the interpreter</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120805">make non-PartialEq-typed consts as patterns a hard error</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120742">mark <code>min_exhaustive_patterns</code> as complete</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121393">match lowering: Introduce a <code>TestCase enum</code> to replace most matching on <code>PatKind</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120904">match lowering: eagerly simplify match pairs</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121172">match lowering: simplify empty candidate selection</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121175">match lowering: test one or pattern at a time</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121391">Fix liveness analysis in the presence of never patterns</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120598">no need to <code>validate_alias_bound_self_from_param_env</code> in <code>assemble_alias_bound_candidates</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121409">prevent cycle in implied predicates computation</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121515">promotion: don't promote <code>int::MIN / -1</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121651">properly emit <code>expected ;</code> on <code>#[attr] expr</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120730">provide suggestions through <code>rustc_confusables</code> annotations</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121277">refactor trait implementations in <code>core::convert::num</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120840">split Diagnostics for Uncommon Codepoints: Add Individual Identifier Types</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121044">support async trait bounds in macros</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121392">unify dylib loading between proc macros and codegen backends</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121471">when encountering <code><&T as Clone>::clone(x)</code> because <code>T: Clone</code>, suggest <code>#[derive(Clone)]</code></a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3328">miri: /miri many-seeds: support <code>MIRI_SEED_END</code> to control the end of the seed range</a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3312">miri: add "cargo miri clean" command</a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3316">miri: windows miri-script execution ergonomics</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120650">use <code>br</code> instead of a conditional when switching on a constant boolean</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119590">stabilize <code>cfg_target_abi</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/117174">improve UEFI stdio</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121337">windows: use ProcessPrng for random keys</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121225">require <code>simd_insert, simd_extract</code> indices to be constants</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119536">make <code>Barrier::new()</code> const</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/117107">implement <code>MappedMutexGuard</code>, <code>MappedRwLockReadGuard</code>, and <code>MappedRwLockWriteGuard</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120718">add "algebraic" fast-math intrinsics, based on fast-math ops that cannot return poison</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/118634">remove useless <code>'static</code> bounds on <code>Box</code> allocator</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121646">mpsc: fix race between block initialization and receiver disconnection</a></li>
<li><a href="https://github.com/rust-lang/futures-rs/pull/2830">futures: add <code>'static</code> bound to <code>waker_ref</code></a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13281">cargo add: Improve error when adding registry packages while vendored</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13463">cargo: Control clap colors through config</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13479">cargo: Respect <code>CARGO_TERM_COLOR</code> in '--list' and '-Zhelp'</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13480">cargo: error messages when collecting workspace members now mention the workspace root location</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13197">cargo: support <code>target.<triple>.rustdocflags</code> officially</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121490">rustdoc: include crate name in links for local primitives</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12355">clippy: <code>box_default</code>: preserve required path segments</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/11136">clippy: <code>read_line_without_trim</code>: detect string literal comparison and <code>.ends_with()</code> calls</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12303">clippy: add <code>unnecessary_clippy_cfg</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12259">clippy: add new <code>multiple_bound_locations</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12339">clippy: add new <code>unnecessary_get_then_check</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12333">clippy: allow <code>unused_imports,</code> and <code>unused_import_braces</code> on <code>use</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12317">clippy: don't lint <code>infinite_loop</code> in external or proc macros</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12336">clippy: make <code>redundant_guards</code> take constness into account</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12322">clippy: <code>unused_unit</code>: be careful with expressions with attributes</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12342">clippy: new lint: <code>empty docs</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12324">clippy: extend <code>unnecessary_to_owned</code> to handle <code>Borrow</code> trait in map types</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12126">clippy: fix sign-handling bugs and false negatives in <code>cast_sign_loss</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12116">clippy: fix suggestion error in <code>useless_vec</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12323">clippy: fix <code>no_effect_underscore_binding</code> firing on ignored parameters of async fns</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12308">clippy: look for <code>implied_bounds_in_impls</code> in more positions</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12260">clippy: take lifetime extension into account in <code>ref_as_ptr</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16651">rust-analyzer: add assist for filling fields by replacing ellipsis in record syntax</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16654">rust-analyzer: add short flag -V for consistency with other rust tooling</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16687">rust-analyzer: add "make tuple" tactic to term search</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16647">rust-analyzer: <code>replace_filter_map_next_with_find_map</code> shouldn't work for dyn trait</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16684">rust-analyzer: don't panic on synthetic syntax in inference diagnostics</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16691">rust-analyzer: fix completions panicking with certain macro setups</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16645">rust-analyzer: fix deadlock in <code>recreate_crate_graph <-> file_line_index</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16679">rust-analyzer: fix modules in blocks not resolving in ide layer</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16637">rust-analyzer: fix proc-macro server not accounting for string delimiters correctly</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16621">rust-analyzer: fix recompiles due to <code>RUSTC_BOOTSTRAP</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16678">rust-analyzer: panic when inlining callsites inside macros' parameters</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16669">rust-analyzer: merge <code>BorrowKind::Unique</code> into <code>BorrowKind::Mut</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16555">rust-analyzer: speed up Method Completions By Taking Advantage of Orphan Rules</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-compiler-performance-triage">Rust Compiler Performance Triage</a></h5>
<p>A rare week where regressions out powered improvements to make the compiler roughly half a percent slower on average on nearly 100 benchmarks. Some regressions have fixes in the pipeline, but some remain elusive or were introduced to address correctness issues.</p>
<p>Triage done by <strong>@rylev</strong>.
Revision range: <a href="https://perf.rust-lang.org/?start=5af2130440c198afefbe5b8099342057cf272ef4&end=71ffdf7ff7ac6df5f9f64de7e780b8345797e8a0&absolute=false&stat=instructions%3Au">5af21304..71ffdf7f</a></p>
<p><strong>Summary</strong>:</p>
<table>
<thead>
<tr>
<th align="center">(instructions:u)</th>
<th align="center">mean</th>
<th align="center">range</th>
<th align="center">count</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">Regressions ❌ <br /> (primary)</td>
<td align="center">1.0%</td>
<td align="center">[0.2%, 4.4%]</td>
<td align="center">69</td>
</tr>
<tr>
<td align="center">Regressions ❌ <br /> (secondary)</td>
<td align="center">1.4%</td>
<td align="center">[0.2%, 4.9%]</td>
<td align="center">66</td>
</tr>
<tr>
<td align="center">Improvements ✅ <br /> (primary)</td>
<td align="center">-1.1%</td>
<td align="center">[-3.3%, -0.2%]</td>
<td align="center">28</td>
</tr>
<tr>
<td align="center">Improvements ✅ <br /> (secondary)</td>
<td align="center">-0.6%</td>
<td align="center">[-1.5%, -0.2%]</td>
<td align="center">33</td>
</tr>
<tr>
<td align="center">All ❌✅ (primary)</td>
<td align="center">0.4%</td>
<td align="center">[-3.3%, 4.4%]</td>
<td align="center">97</td>
</tr>
</tbody>
</table>
<p>4 Regressions, 6 Improvements, 5 Mixed; 2 of them in rollups
58 artifact comparisons made in total</p>
<p><a href="https://github.com/rust-lang/rustc-perf/blob/0528b31d7dad7c98af395e29271591740e984e16/triage/2024-02-27.md">Full report here</a></p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#approved-rfcs"></a><a href="https://github.com/rust-lang/rfcs/commits/master">Approved RFCs</a></h5>
<p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments) process</a>. These
are the RFCs that were approved for implementation this week:</p>
<ul>
<li><em>No RFCs were approved this week.</em></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#final-comment-period">Final Comment Period</a></h5>
<p>Every week, <a href="https://www.rust-lang.org/team.html">the team</a> announces the 'final comment period' for RFCs and key PRs
which are reaching a decision. Express your opinions now.</p>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rfcs"></a><a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">RFCs</a></h6>
<ul>
<li><em>No RFCs entered Final Comment Period this week.</em></li>
</ul>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#tracking-issues-prs">Tracking Issues & PRs</a></h6>
<a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust"></a><a href="https://github.com/rust-lang/rust/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Rust</a>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/118879">Lint singleton gaps after exclusive ranges</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/issues/76014">Tracking Issue for slice::split_at_unchecked() and split_at_mut_unchecked()</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/issues/120257">Tracking Issue for generic <code>NonZero</code></a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/111505">Made <code>INVALID_DOC_ATTRIBUTES</code> lint deny by default</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/issues/117215">Tracking Issue for ARM CRC32 intrinsics</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/100824">use <code>confstr(_CS_DARWIN_USER_TEMP_DIR, ...)</code> as a <code>TMPDIR</code> fallback on Darwin</a></li>
</ul>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#new-and-updated-rfcs"></a><a href="https://github.com/rust-lang/rfcs/pulls">New and Updated RFCs</a></h6>
<ul>
<li>[new] <a href="https://github.com/rust-lang/rfcs/pull/3577">RFC: RArrow Dereference for Pointer Ergonomics</a></li>
</ul>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#upcoming-events">Upcoming Events</a></h4>
<p>Rusty Events between 2024-02-28 - 2024-03-27 🦀</p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#virtual">Virtual</a></h5>
<ul>
<li>2024-02-29 | Virtual (Berlin, DE) | <a href="https://berline.rs/">OpenTechSchool Berlin</a> + <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://meet.jit.si/RustHackAndLearnBerlin"><strong>Rust Hack and Learn</strong></a> | <a href="https://www.meetup.com/rust-berlin/events/298457901/"><strong>Mirror: Rust Hack n Learn Meetup</strong></a> | <a href="https://berline.rs/2024/02/29/rust-hack-and-learn.html"><strong>Mirror: Berline.rs page</strong></a></li>
</ul>
</li>
<li>2024-02-29 | Virtual (Charlottesville, NC, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/">Charlottesville Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/298372724/"><strong>Surfing the Rusty Wireless Waves with the ESP32-C3 Board</strong></a></li>
</ul>
</li>
<li>2024-03-06 | Virtual (Dublin, IE) | <a href="https://www.meetup.com/rust-dublin/">Rust Dublin</a><ul>
<li><a href="https://www.meetup.com/rust-dublin/events/299358988/"><strong>An intro to <code>nom</code>, parsing made easy for Rustaceans</strong></a></li>
</ul>
</li>
<li>2024-03-06 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs/">Indy Rust</a><ul>
<li><a href="https://www.meetup.com/indyrs/events/299047891/"><strong>Indy.rs - with Social Distancing</strong></a></li>
</ul>
</li>
<li>2024-03-07 | Virtual (Charlottesville, NC, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/">Charlottesville Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/298368787/"><strong>Crafting Interpreters in Rust Collaboratively</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/">Dallas Rust</a><ul>
<li><a href="https://www.meetup.com/dallasrust/events/298341582/"><strong>Second Tuesday</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Hybrid (Virtual + In-person) Munich, DE | <a href="https://www.meetup.com/rust-munich/">Rust Munich</a><ul>
<li><a href="https://www.meetup.com/rust-munich/events/298507657/"><strong>Rust Munich 2024 / 1 - hybrid</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/opentechschool-berlin/">OpenTechSchool Berlin</a><ul>
<li><a href="https://www.meetup.com/opentechschool-berlin/events/298406445/"><strong>Web Frontend Co-Learning (online)</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Berlin, DE) | <a href="https://berline.rs/">OpenTechSchool Berlin</a> + <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://meet.jit.si/RustHackAndLearnBerlin"><strong>Rust Hack and Learn</strong></a> | <a href="https://www.meetup.com/rust-berlin/events/298457903/"><strong>Mirror: Rust Hack n Learn Meetup</strong></a> | <a href="https://berline.rs/2024/03/14/rust-hack-and-learn.html"><strong>Mirror: Berline.rs page</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Nürnberg, DE) | <a href="https://www.meetup.com/rust-noris/">Rust Nüremberg</a><ul>
<li><a href="https://www.meetup.com/rust-noris/events/297945252/"><strong>Rust Nürnberg online</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Seattle, WA, US | <a href="https://www.meetup.com/seattle-rust-user-group/">Seattle Rust User Group</a><ul>
<li><a href="https://www.meetup.com/seattle-rust-user-group/events/298631832/"><strong>Seattle Rust User Group Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-26 | Virtual + In Person (Barcelona, ES) | <a href="https://www.meetup.com/es-ES/bcnrust/">BcnRust</a><ul>
<li><a href="https://www.meetup.com/es-ES/bcnrust/events/299223178/"><strong>13th BcnRust Meetup</strong></a> - <a href="https://www.youtube.com/@bcnrust">Stream</a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#europe">Europe</a></h5>
<ul>
<li>2024-02-29 | Berlin, DE | <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://www.meetup.com/rust-berlin/events/299190389/"><strong>Rust and Tell - Season start 2024</strong></a></li>
</ul>
</li>
<li>2024-02-29 | Copenhagen, DK | <a href="https://www.meetup.com/copenhagen-rust-community/">Copenhagen Rust Community</a><ul>
<li><a href="https://www.meetup.com/copenhagen-rust-community/events/299353844/"><strong>Rust Meetup #44 sponsored by Bang & Olufsen</strong></a></li>
</ul>
</li>
<li>2024-03-06 | Zürich, CH | <a href="https://www.meetup.com/rust-zurich/">Rust Zürisee</a><ul>
<li><a href="https://www.meetup.com/rust-zurich/events/299380190/"><strong>How to (partial) Migration - March Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Munich, DE + Virtual | <a href="https://www.meetup.com/rust-munich/">Rust Munich</a><ul>
<li><a href="https://www.meetup.com/rust-munich/events/298507657/"><strong>Rust Munich 2024 / 1 - hybrid</strong></a></li>
</ul>
</li>
<li>2024-03-13 | Paris, FR | <a href="https://www.eventbrite.com/o/paris-rustaceans-74289178383">Paris Rustaceans</a><ul>
<li><a href="https://www.eventbrite.fr/e/rust-meetup-in-paris-tickets-830340830777"><strong>Rust Meetup in Paris</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Reading, UK | <a href="https://www.meetup.com/reading-rust-workshop/">Reading Rust Workshop</a><ul>
<li><a href="https://www.meetup.com/reading-rust-workshop/events/298533419/"><strong>Reading Rust Meetup at Browns</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Aarhus, DK | <a href="https://www.meetup.com/rust-aarhus/">Rust Aarhus</a><ul>
<li><a href="https://www.meetup.com/rust-aarhus/events/299028814/"><strong>Hack Night</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Leipzig, DE | <a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/">Rust - Modern Systems Programming in Leipzig</a><ul>
<li><a href="https://www.meetup.com/rust-modern-systems-programming-in-leipzig/events/299309224/"><strong>Rust Interactive Session</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Girona, ES | <a href="https://www.meetup.com/rust-girona/">Rust Girona</a><ul>
<li><a href="https://www.meetup.com/rust-girona/events/299172343/"><strong>Introduction to programming Microcontrollers with Rust</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Augsburg, DE | <a href="https://www.meetup.com/de-DE/rust-meetup-augsburg/">Rust Meetup Augsburg</a><ul>
<li><a href="https://www.meetup.com/de-DE/rust-meetup-augsburg/events/299354449/"><strong>Augsburg Rust Meetup #6</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Lille, FR | <a href="https://www.meetup.com/meetup-group-zgphbyet/">Rust Lille</a><ul>
<li><a href="https://www.meetup.com/meetup-group-zgphbyet/events/299295547/"><strong>Rust Lille #6: Du RSS et de L'ECS !</strong></a></li>
</ul>
</li>
<li>2024-03-26 | Barcelona, ES + Virtual | <a href="https://www.meetup.com/es-ES/bcnrust/">BcnRust</a><ul>
<li><a href="https://www.meetup.com/es-ES/bcnrust/events/299223178/"><strong>13th BcnRust Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-26, 2024-03-28 | London, UK | <a href="https://www.rustnationuk.com/">Rust Nation UK</a><ul>
<li><a href="https://www.rustnationuk.com/"><strong>Rust Nation 2024</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#north-america">North America</a></h5>
<ul>
<li>2024-02-28 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx/">Rust ATX</a><ul>
<li><a href="https://www.meetup.com/rust-atx/events/297380841/"><strong>Rust Lunch - Fareground</strong></a></li>
</ul>
</li>
<li>2024-02-28 | Chicago, IL, US | <a href="https://www.meetup.com/deep-dish-rust/">Deep Dish Rust</a><ul>
<li><a href="https://www.meetup.com/deep-dish-rust/events/299284926/"><strong>Rust Happy Hour</strong></a></li>
</ul>
</li>
<li>2024-03-04 | Cambridge, MA, US | <a href="https://www.meetup.com/bostonrust/">Boston Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/bostonrust/events/299261953/"><strong>Central Cambridge Rust Lunch</strong></a></li>
</ul>
</li>
<li>2024-03-07 | Mountain View, CA, US | <a href="https://www.meetup.com/mv-rust-meetup/">Mountain View Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/mv-rust-meetup/events/299043793/"><strong>Rust Meetup at Hacker Dojo</strong></a></li>
</ul>
</li>
<li>2024-03-13 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/">Boston Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/bostonrust/events/299262009/"><strong>Northeastern Rust Lunch</strong></a></li>
</ul>
</li>
<li>2024-03-19 | San Francisco, CA, US | <a href="https://www.meetup.com/san-francisco-rust-study-group/">San Francisco Rust Study Group</a><ul>
<li><a href="https://www.meetup.com/san-francisco-rust-study-group/events/299186823/"><strong>Rust Hacking in Person</strong></a></li>
</ul>
</li>
<li>2024-03-27 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx/">Rust ATX</a><ul>
<li><a href="https://www.meetup.com/rust-atx/events/299220136/"><strong>Rust Lunch - Fareground</strong></a></li>
</ul>
</li>
<li>2024-03-27 | Hawthorne, CA, US | <a href="https://freeform.co/">Freeform</a><ul>
<li><a href="https://freeformxrust.rsvpify.com/"><strong>Rust in the Physical World 🦀 Tech Talk Event at Freeform</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#oceania">Oceania</a></h5>
<ul>
<li>2024-02-29 | Brisbane, QLD, AU | <a href="https://www.meetup.com/rust-brisbane/">Rust Brisbane</a><ul>
<li><a href="https://www.meetup.com/rust-brisbane/events/299304438/"><strong>February Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-05 | Auckland, NZ | <a href="https://www.meetup.com/rust-akl/">Rust AKL</a><ul>
<li><a href="https://www.meetup.com/rust-akl/events/299158887/"><strong>Rust AKL: Introduction to Embedded Rust + The State of Rust UI</strong></a></li>
</ul>
</li>
</ul>
<p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to get
it mentioned here. Please remember to add a link to the event too.
Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#jobs">Jobs</a></h4>
<p>Please see the latest <a href="https://www.reddit.com/r/rust/comments/1arr8xi/official_rrust_whos_hiring_thread_for_jobseekers/">Who's Hiring thread on r/rust</a></p>
<h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#quote-of-the-week">Quote of the Week</a></h3>
<blockquote>
<p>That would take 18 million terabytes of RAM. You don't have that much memory.</p>
</blockquote>
<p>– <a href="https://users.rust-lang.org/t/what-is-max-array-size/107058/4">Alice Ryhl answering "What is MAX array size" on rust-users</a></p>
<p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/1536">Zeroexcuses</a> for the suggestion!</p>
<p><a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328">Please submit quotes and vote for next week!</a></p>
<p><em>This Week in Rust is edited by: <a href="https://github.com/nellshamrell">nellshamrell</a>, <a href="https://github.com/llogiq">llogiq</a>, <a href="https://github.com/cdmistman">cdmistman</a>, <a href="https://github.com/ericseppanen">ericseppanen</a>, <a href="https://github.com/extrawurst">extrawurst</a>, <a href="https://github.com/andrewpollack">andrewpollack</a>, <a href="https://github.com/U007D">U007D</a>, <a href="https://github.com/kolharsam">kolharsam</a>, <a href="https://github.com/joelmarcey">joelmarcey</a>, <a href="https://github.com/mariannegoldin">mariannegoldin</a>, <a href="https://github.com/bennyvasquez">bennyvasquez</a>.</em></p>
<p><em>Email list hosting is sponsored by <a href="https://foundation.rust-lang.org/">The Rust Foundation</a></em></p>
<p><small><a href="https://www.reddit.com/r/rust/comments/1b2n4bw/this_week_in_rust_536/">Discuss on r/rust</a></small></p>2024-02-28T05:00:00+00:00TWiR ContributorsThe Servo Blog: This month in Servo: gamepad support, font fallback, Space Jam, and more!
https://servo.org/blog/2024/02/28/gamepads-font-fallback-space-jam/
<figure class="_figr"><a href="https://servo.org/img/blog/font-fallback.png"><img alt="Servo nightly showing Chinese, Japanese, and Korean Wikipedia with working font fallback" src="https://servo.org/img/blog/font-fallback.png" /></a>
<figcaption>Font fallback now works for Chinese, Japanese, and Korean.</figcaption></figure>
<p><a href="https://wpt.servo.org/">A couple of weeks ago</a>, Servo surpassed its legacy layout engine in a core set of CSS2 test suites (84.2% vs 82.8% in legacy), but now we’ve <strong>surpassed legacy in the whole CSS test suite</strong> (63.6% vs 63.5%) as well!
More on how we got there in a bit, but first let’s talk about new API support:</p>
<ul>
<li>as of 2024-02-07, you can safely <strong>console.log() symbols and large arrays</strong> (<a href="https://github.com/syvb">@syvb</a>, <a href="https://github.com/servo/servo/pull/31241">#31241</a>, <a href="https://github.com/servo/servo/pull/31267">#31267</a>)</li>
<li>as of 2024-02-07, we support <strong>CanvasRenderingContext2D.reset()</strong> (<a href="https://github.com/syvb">@syvb</a>, <a href="https://github.com/servo/servo/pull/31258">#31258</a>)</li>
<li>as of 2024-02-08, we support <strong>navigator.hardwareConcurrency</strong> (<a href="https://github.com/syvb">@syvb</a>, <a href="https://github.com/servo/servo/pull/31268">#31268</a>)</li>
<li>as of 2024-02-11, you can look up <strong>shorthands like ‘margin’ in getComputedStyle()</strong> (<a href="https://github.com/sebsebmc">@sebsebmc</a>, <a href="https://github.com/servo/servo/pull/31277">#31277</a>)</li>
<li>as of 2024-02-15, we accept SVG with the <strong>image/svg+xml mime type</strong> (<a href="https://github.com/KiChjang">@KiChjang</a>, <a href="https://github.com/servo/servo/pull/31318">#31318</a>)</li>
<li>as of 2024-02-20, we support non-XR <strong>game controllers with the Gamepad API</strong> (<a href="https://github.com/msub2">@msub2</a>, <a href="https://github.com/servo/servo/pull/31200">#31200</a>)</li>
<li>as of 2024-02-23, we have basic support for <strong>‘text-transform’</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/servo/pull/31396">#31396</a>)
<br />— except ‘full-width’, ‘full-size-kana’, grapheme clusters, and language-specific transforms</li>
</ul>
<p>As of 2024-02-12, we have basic support for <strong>font fallback</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31254">#31254</a>)!
This is especially important for pages that mix text from different languages.
More work is needed to support shaping across element boundaries and shaping complex scripts like Arabic, but the current version should be enough for Chinese, Japanese, and Korean.
If you encounter text that still fails to display, be sure to check your installed fonts against the page styles and Servo’s default font lists (<a href="https://github.com/servo/servo/blob/304ab9b09c0beace5ac08c073c957060621d4056/components/gfx/platform/windows/font_list.rs">Windows</a>, <a href="https://github.com/servo/servo/blob/304ab9b09c0beace5ac08c073c957060621d4056/components/gfx/platform/macos/font_list.rs">macOS</a>, <a href="https://github.com/servo/servo/blob/304ab9b09c0beace5ac08c073c957060621d4056/components/gfx/platform/freetype/font_list.rs">Linux</a>).</p>
<figure class="_figl"><a href="https://servo.org/img/blog/space-jam.png"><img alt="Servo nightly showing the Space Jam (1996) website with its table-based menu correctly laid out" src="https://servo.org/img/blog/space-jam.png" /></a>
<figcaption>
<p><a href="https://www.spacejam.com/1996/">Space Jam (1996)</a> now has correct layout with <code>--pref layout.tables.enabled</code>.</p></figcaption></figure><p></p>
<p>As of 2024-02-24, <strong>layout now runs in the script thread</strong>, rather than in a dedicated layout thread (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/servo/servo/pull/31346">#31346</a>), though it can still spawn worker threads to parallelise layout work.
Since the web platform almost always requires layout to run synchronously with script, this should allow us to make layout simpler and more reliable without regressing performance.</p>
<p>Our experimental <strong>tables support</strong> (<code>--pref layout.tables.enabled</code>) has vastly improved:</p>
<ul>
<li>as of 2024-01-26, we compute <strong>table column widths</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loiroriol">@Loiroriol</a>, <a href="https://github.com/servo/servo/pull/31165">#31165</a>)</li>
<li>as of 2024-01-30, we support the <strong><table cellpadding> attribute</strong> (<a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/31201">#31201</a>)</li>
<li>as of 2024-02-11, we support <strong>‘vertical-align’ in table cells</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/31246">#31246</a>)</li>
<li>as of 2024-02-14, we support <strong>‘border-spacing’ on tables</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/31166">#31166</a>, <a href="https://github.com/servo/servo/pull/31337">#31337</a>)</li>
<li>as of 2024-02-21, we support <strong>rows, columns, and row/column groups</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/31341">#31341</a>)</li>
</ul>
<p>Together with inline layout for <strong><div align> and <center></strong> (<a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/31388">#31388</a>) landing in 2024-02-24, we now render the classic <strong><a href="https://www.spacejam.com/1996/">Space Jam</a></strong> website correctly when tables are enabled!</p>
<p>As of 2024-02-24, we support <strong>videos with autoplay</strong> (<a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/servo/servo/pull/31412">#31412</a>), and windows containing <strong>videos no longer crash</strong> when closed (<a href="https://github.com/jdm">@jdm</a>, <a href="https://github.com/servo/servo/pull/31413">#31413</a>).</p>
<p>Many layout and CSS bugs have also been fixed:</p>
<ul>
<li>as of 2024-01-28, correct <strong>rounding of clientLeft, clientTop, clientWidth, and clientHeight</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31187">#31187</a>)</li>
<li>as of 2024-01-30, correct <strong>cache invalidation of client{Left,Top,Width,Height} after reflow</strong> (<a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/31210">#31210</a>, <a href="https://github.com/servo/servo/pull/31219">#31219</a>)</li>
<li>as of 2024-02-03, correct <strong>width and height for preloaded Image objects</strong> (<a href="https://github.com/syvb">@syvb</a>, <a href="https://github.com/servo/servo/pull/31253">#31253</a>)</li>
<li>as of 2024-02-07, correct <strong>[...spreading] and indexing[0] of style objects</strong> (<a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/servo/servo/pull/31299">#31299</a>)</li>
<li>as of 2024-02-09, correct <strong>border widths in fragmented inlines</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31292">#31292</a>)</li>
<li>as of 2024-02-11, correct <strong>UA styles for <hr></strong> (<a href="https://github.com/sebsebmc">@sebsebmc</a>, <a href="https://github.com/servo/servo/pull/31297">#31297</a>)</li>
<li>as of 2024-02-24, correct <strong>positioning of absolutes with ‘inset: auto’</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31418">#31418</a>)</li>
</ul>
<h3>Embedding, code health, and dev changes <a class="header-anchor" href="https://servo.org/blog/2024/02/28/gamepads-font-fallback-space-jam/#embedding%2C-code-health%2C-and-dev-changes">
<span class="icon hashlink"><i class="fas fa-link"></i></span>
</a></h3>
<p>We’ve landed a few embedding improvements:</p>
<ul>
<li>we’ve removed several mandatory <code>WindowMethods</code> relating to OpenGL video playback (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31209">#31209</a>)</li>
<li>we’ve removed <code>webrender_surfman</code>, and <code>WebrenderSurfman</code> is now in <code>gfx</code> as <code>RenderingContext</code> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31184">#31184</a>)</li>
</ul>
<p>We’ve finished migrating our DOM bindings to use typed arrays where possible (<a href="https://github.com/Taym95">@Taym95</a>, <a href="https://github.com/servo/servo/pull/31145">#31145</a>, <a href="https://github.com/servo/servo/pull/31164">#31164</a>, <a href="https://github.com/servo/servo/pull/31167">#31167</a>, <a href="https://github.com/servo/servo/pull/31189">#31189</a>, <a href="https://github.com/servo/servo/pull/31202">#31202</a>, <a href="https://github.com/servo/servo/pull/31317">#31317</a>, <a href="https://github.com/servo/servo/pull/31325">#31325</a>), as part of an effort to <strong>reduce our unsafe code surface</strong> (<a href="https://github.com/servo/servo/issues/30889">#30889</a>, <a href="https://github.com/servo/servo/issues/30862">#30862</a>).</p>
<p><a href="https://github.com/servo/webrender">WebRender</a> and <a href="https://github.com/servo/stylo">Stylo</a> are two major components of Servo that have been adopted by Firefox, making Servo’s versions of them a downstream fork.
To make these forks easier to update, we’ve <strong>split WebRender and Stylo out of <a href="https://github.com/servo/servo">our main repo</a></strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/delan">@delan</a>, <a href="https://github.com/servo/servo/pull/31212">#31212</a>, <a href="https://github.com/servo/servo/pull/31351">#31351</a>, <a href="https://github.com/servo/servo/pull/31349">#31349</a>, <a href="https://github.com/servo/servo/pull/31358">#31358</a>, <a href="https://github.com/servo/servo/pull/31363">#31363</a>, <a href="https://github.com/servo/servo/pull/31365">#31365</a>, <a href="https://github.com/servo/servo/pull/31408">#31408</a>, <a href="https://github.com/servo/servo/pull/31387">#31387</a>, <a href="https://github.com/servo/servo/pull/31411">#31411</a>, <a href="https://github.com/servo/servo/pull/31350">#31350</a>).</p>
<p>We’ve fixed one of the blockers for building Servo with clang 16 (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31306">#31306</a>), but a blocker for clang 15 still remains.
See <a href="https://github.com/servo/servo/issues/31059">#31059</a> for more details, including how to build Servo against clang 14.</p>
<p>We’ve also made some other dev changes:</p>
<ul>
<li>we’ve removed the unmaintained <strong>libsimpleservo C API</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31172">#31172</a>), though we’re open to adding a new C API someday</li>
<li>we’ve upgraded <strong>surfman</strong> such that it <strong>no longer depends on winit</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31224">#31224</a>)</li>
<li>we’ve added support for building Servo on <strong>Asahi Linux</strong> (<a href="https://github.com/arrynfr">@arrynfr</a>, <a href="https://github.com/servo/servo/pull/31207">#31207</a>)</li>
<li>we’ve fixed problems building Servo on <strong>Debian</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/servo/pull/31281">#31281</a>, <a href="https://github.com/servo/servo/pull/31276">#31276</a>) and <strong>NixOS</strong> (<a href="https://github.com/syvb">@syvb</a>, <a href="https://github.com/servo/servo/pull/31231">#31231</a>)</li>
<li>we’ve fixed failures when <strong>starting multiple CI try jobs</strong> at once (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31347">#31347</a>)</li>
<li>we’ve made several improvements to <strong>mach try</strong> for starting CI try jobs (<a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31141">#31141</a>, <a href="https://github.com/servo/servo/pull/31290">#31290</a>)</li>
</ul>
<h3>Conference talks <a class="header-anchor" href="https://servo.org/blog/2024/02/28/gamepads-font-fallback-space-jam/#conference-talks">
<span class="icon hashlink"><i class="fas fa-link"></i></span>
</a></h3>
<p>Rakhi Sharma will <a href="https://ossna2024.sched.com/event/1aBNF/a-year-of-servo-reboot-where-are-we-now-rakhi-sharma-igalia"><strong>speak about Servo’s achievements</strong></a> at <a href="https://events.linuxfoundation.org/open-source-summit-north-america/">Open Source Summit North America</a> on <strong>16 April 2024</strong> at <strong>14:15 local time</strong> (21:15 UTC).</p>
<p>In the meantime, check out Rakhi’s recent talk <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2321-embedding-servo-in-rust-projects/"><em>Embedding Servo in Rust projects</em></a>, which she gave at <a href="https://fosdem.org/2024/">FOSDEM 2024</a> on 3 February 2024.
Here you’ll learn about the state of the art around embedding Servo and Stylo, including a walkthrough of our example browser <em>servoshell</em>, our ongoing effort to <a href="https://servo.org/blog/2024/01/19/embedding-update/">integrate Servo with Tauri</a>, and a sneak peek into how Stylo might someday be usable with <a href="https://dioxuslabs.com/">Dioxus</a>:</p>
<figure class="_fig">
<video controls="">
<source src="https://video.fosdem.org/2024/h1308/fosdem-2024-2321-embedding-servo-in-rust-projects.av1.webm" type="video/webm; codecs="av01.0.08m.08.0.110.01.01.01.0"" />
<source src="https://video.fosdem.org/2024/h1308/fosdem-2024-2321-embedding-servo-in-rust-projects.mp4" type="video/mp4" />
<p><a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2321-embedding-servo-in-rust-projects/">Embedding Servo in Rust projects</a> by Rakhi Sharma at FOSDEM 2024</p>
</video>
</figure>2024-02-28T00:00:00+00:00The Rust Programming Language Blog: Clippy: Deprecating `feature = "cargo-clippy"`
https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html
<p>Since Clippy <a href="https://github.com/rust-lang/rust-clippy/blob/61daf674eaf17f3b504c51f01b4ee63fac47dfcf/CHANGELOG.md?plain=0#0097--2016-11-03"><code>v0.0.97</code></a> and before it was shipped with <code>rustup</code>, Clippy
implicitly added a <code>feature = "cargo-clippy"</code> config<sup class="footnote-ref"><a href="https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html#fn-1" id="fnref-1">1</a></sup> when linting your code
with <code>cargo clippy</code>.</p>
<p>Back in the day (2016) this was necessary to allow, warn or deny Clippy lints
using attributes:</p>
<pre><code class="language-rust">#[cfg_attr(feature = "cargo-clippy", allow(clippy_lint_name))]
</code></pre>
<p>Doing this hasn't been necessary for a long time. Today, Clippy users will set
lint levels with tool lint attributes using the <code>clippy::</code> prefix:</p>
<pre><code class="language-rust">#[allow(clippy::lint_name)]
</code></pre>
<p>The implicit <code>feature = "cargo-clippy"</code> has only been kept for backwards
compatibility, but will be deprecated in upcoming nightlies and later in
<code>1.78.0</code>.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html#alternative" id="alternative"></a>Alternative</h3>
<p>As there is a rare <a href="https://doc.rust-lang.org/clippy/configuration.html#disabling-evaluation-of-certain-code">use case</a> for conditional compilation depending on Clippy,
we will provide an alternative. So in the future (<code>1.78.0</code>) you will be able to
use:</p>
<pre><code class="language-rust">#[cfg(clippy)]
</code></pre>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html#transitioning" id="transitioning"></a>Transitioning</h3>
<blockquote>
<p>Should you only use stable toolchains, you can wait with the transition until
Rust <code>1.78.0</code> (2024-05-02) is released.</p>
</blockquote>
<p>Should you have instances of <code>feature = "cargo-clippy"</code> in your code base, you
will see a warning from the new Clippy lint
<a href="https://rust-lang.github.io/rust-clippy/master/index.html#/deprecated_clippy_cfg_attr"><code>clippy::deprecated_clippy_cfg_attr</code></a> available in the latest nightly Clippy.
This lint can automatically fix your code. So if you should see this lint
triggering, just run:</p>
<pre><code>cargo clippy --fix -- -Aclippy::all -Wclippy::deprecated_clippy_cfg_attr
</code></pre>
<p>This will fix all instances in your code.</p>
<p>In addition, check your <code>.cargo/config</code> file for:</p>
<pre><code class="language-toml">[target.'cfg(feature = "cargo-clippy")']
rustflags = ["-Aclippy::..."]
</code></pre>
<p>If you have this config, you will have to update it yourself, by either changing
it to <code>cfg(clippy)</code> or taking this opportunity to transition to <a href="https://doc.rust-lang.org/cargo/reference/manifest.html#the-lints-section">setting lint
levels in <code>Cargo.toml</code></a> directly.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html#motivation-for-deprecation" id="motivation-for-deprecation"></a>Motivation for Deprecation</h3>
<p>Currently, there's a <a href="https://github.com/rust-lang/rfcs/pull/3013#issuecomment-1936648479">call for testing</a>, in order to stabilize <a href="https://github.com/rust-lang/rfcs/pull/3013">checking
conditional compilation at compile time</a>, aka <code>cargo check -Zcheck-cfg</code>. If we were to keep the <code>feature = "cargo-clippy"</code> config, users
would start seeing a lot of warnings on their <code>feature = "cargo-clippy"</code>
conditions. To work around this, they would either need to allow the lint or
have to add a dummy feature to their <code>Cargo.toml</code> in order to silence those
warnings:</p>
<pre><code class="language-toml">[features]
cargo-clippy = []
</code></pre>
<p>We didn't think this would be user friendly, and decided that instead we want to
deprecate the implicit <code>feature = "cargo-clippy"</code> config and replace it with the
<code>clippy</code> config.</p>
<section class="footnotes">
<ol>
<li id="fn-1">
<p>It's likely that you didn't even know that Clippy implicitly sets this
config (which was not a Cargo feature). This is intentional, as we stopped
advertising and documenting this a long time ago. <a class="footnote-backref" href="https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html#fnref-1">↩</a></p>
</li>
</ol>
</section>2024-02-28T00:00:00+00:00The Clippy TeamThe Mozilla Blog: Mozilla Announces Call for Entries for the 2nd Annual Rise25 Awards in Dublin, Ireland
https://blog.mozilla.org/en/mozilla/mozilla-rise25-ai-nominations/
<p class="has-text-align-center"><a href="https://www.mozilla.org/rise25/nominate/">www.mozilla.org/rise25/nominate/</a></p>
<p>On the heels of Mozilla’s <em>Rise25 Awards</em> in Berlin last year, we’re excited to announce that we’ll be returning once again with a special celebration that will take place in Dublin, Ireland later this year.</p>
<p>The <em>2nd Annual Rise25 Awards </em>will feature familiar categories, but with an emphasis on trustworthy AI. We will be honoring 25 people who are leading that next wave of AI — who are using philanthropy, collective power, and the principles of open source to make sure the future of AI is responsible, trustworthy, inclusive and centered around human dignity. </p>
<p><a href="https://blog.mozilla.org/en/mozilla/ai/ai-2023s-most-celebrated-influencer/">2023 was indeed the year of AI</a>, and as more people adopt it, we know it is a technology that will continue to impact our culture and society, act as a catalyst for innovation and creation, and be a medium to engage people from all walks of life in conversations thanks to its growing ubiquity in our everyday lives.</p>
<p>We know we cannot do this alone: At Mozilla, we believe the most groundbreaking innovations emerge when people from diverse backgrounds unite to collaborate and openly trade ideas. </p>
<p>So if you know someone who you think should be celebrated, <a href="https://www.mozilla.org/rise25/nominate/">we want to hear from you</a>! </p>
<p>Five winners from each of the five categories below will be selected to make up our 2024 Rise25 cohort: </p>
<p><strong>Advocates </strong>–<strong> </strong><em>Guiding AI towards a responsible future</em></p>
<p>These are the policymakers, activists, and thinkers ensuring AI is developed ethically, inclusively, and transparently. This category also includes those who are adept at translating complex AI concepts for the broader public — including journalists, content creators, and cultural commentators. They champion digital rights and accessible AI, striving to make AI a force for societal good.</p>
<p><strong>Builders </strong>– <em>Developing AI through ethical innovation</em></p>
<p>They are the architects of trustworthy AI, including engineers and data scientists dedicated to developing AI’s open-source language infrastructure. They focus on technical proficiency and responsible and ethical construction. Their work ensures AI is secure, accessible, and reliable, aiming to create tools that empower and advance society. </p>
<p><strong>Artists </strong>– <em>Reimagining AI’s creative potential</em></p>
<p>They transcend traditional AI applications, like synthesizing visuals or using large language models. Their projects, whether interactive websites, films, or digital media, challenge our perceptions and demonstrate how AI can amplify and empower human creativity. Their work provokes thought and offers fresh perspectives on the intersection of AI and art.</p>
<p><strong>Entrepreneurs </strong>– <em>Fueling AI’s evolution with visionary ventures</em></p>
<p>These daring individuals are transforming imaginative ideas into reality. They’re crafting businesses and solutions with AI to meet societal needs, improve everyday life and forge new technological paths. They embody innovation, steering startups and projects with a commitment to ethical standards, inclusiveness and enhancing human welfare through technology.</p>
<p><strong>Change Agents </strong>– <em>Cultivating inclusive AI</em></p>
<p>They are challengers that lead the way in diversifying AI, bringing varied community voices into tech. They focus on inclusivity in AI development, ensuring technology serves and represents everyone, especially those historically excluded from the tech narrative. They are community leaders, corporate leaders, activists and outside-the-box thinkers finding ways to amplify the impacts of AI for marginalized communities. Their work fosters an AI environment of equality and empowerment.</p>
<p>This year’s awards build upon the success of last year’s programming and community event in Berlin, which brought to life what a future trustworthy Internet could look like. Last year’s event <a href="https://rise25.mozilla.org/">crowned</a> trailblazers and visionaries across five distinct categories: Builders, Activists, Artists, Creators, and Advocates. (Psst! Stay tuned as we unveil their inspiring stories in a <a href="https://blog.mozilla.org/en/internet-culture/trisha-prabhu-rise25-rethink-cyberbullying/">video series</a> airing across Mozilla channels throughout the year, leading up to the <em>2nd Annual Rise25 Awards</em>.)</p>
<p>So join us as we honor the innovators, advocates, entrepreneurs, and communities who are working to build a happier, healthier web. <a href="https://www.mozilla.org/rise25/nominate/">Click here to submit your nomination today.</a></p>
<p></p>
<p>The post <a href="https://blog.mozilla.org/en/mozilla/mozilla-rise25-ai-nominations/">Mozilla Announces Call for Entries for the 2nd Annual Rise25 Awards in Dublin, Ireland</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-02-27T17:02:35+00:00DamianoFirefox Nightly: Inspector Performance and Other Improvements – These Weeks in Firefox: Issue 155
https://blog.nightly.mozilla.org/2024/02/26/inspector-performance-and-other-improvements-these-weeks-in-firefox-issue-155/
<h3>Highlights</h3>
<ul>
<li>Alex added added a new option to log frame return to the nascent JS Tracer feature (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1852028">bug</a>)
<ul>
<li>This can be really useful paired with the “Log function arguments and returned values”. See the example below, tracing a Redux reducer on about:home</li>
<li><img src="https://blog.nightly.mozilla.org/files/2024/02/headlines155_0.png" /></li>
<li>The JS Tracer is a tool that the DevTools team is developing to log JavaScript execution at runtime. This can be very helpful when debugging or exploring a new JavaScript codebase!
<ul>
<li>Set devtools.debugger.features.javascript-tracing to true to enable the JS Tracer feature and try it out!</li>
</ul>
</li>
</ul>
</li>
<li>Nicolas fixed a performance issue in the Inspector when showing a lot of rules (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1247751">bug</a>)
<ul>
<li>for 5000 rules, on Nicolas’s engineering machine, this went from <b>7 seconds</b> to <b>50 milliseconds!</b></li>
</ul>
</li>
<li>Marco enabled cross-container tab searching in Nightly (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876743">1876743</a>). Users can now search in the URL bar for tabs open in different containers. This behaviour can be controlled through the browser.urlbar.switchTabs.searchAllContainers boolean pref.</li>
<li>The Firefox View team has added new <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1857005">tab indicators</a> to the Open Tabs section (sound playing, notifications, etc) and the option of sorting Open Tabs by recency. Both are slated to ship in Firefox 124!
<ul>
<li><img src="https://blog.nightly.mozilla.org/files/2024/02/headlines155_1.png" /></li>
</ul>
</li>
</ul>
<h3>Friends of the Firefox team</h3>
<h4><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20%28excluding%20employees%29&quicksearch=1832792%2C1877883%2C1875460%2C1872860%2C1871365%2C1879991%2C1853038&list_id=16907686">Resolved bugs (excluding employees)</a></h4>
<p><a href="https://github.com/niklasbaumgardner/NewContributorScraper">Script to find new contributors from bug list</a></p>
<h4>New contributors (🌟 = first patch)</h4>
<ul>
<li>Jing Zhu <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1832792">updated RemoteValue deserialization methods</a> to have `serializedValue` as first argument</li>
<li>Redfire <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879991">updated example in comment</a> on Console.cpp</li>
<li>🌟 Sho Sugihara <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1853038">removed ‘get’ from Lit template function names</a> in Shopping</li>
</ul>
<h3>Project Updates</h3>
<h4>Developer Tools</h4>
<h5>DevTools</h5>
<ul>
<li><a href="https://bugzilla.mozilla.org/user_profile?user_id=681623">Redfire</a> fixed an erroneous comment in Console.cpp (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879991">bug</a>)</li>
<li>Arai migrated ESMified <a href="https://searchfox.org/mozilla-central/source/devtools/client/performance-new">devtools/client/performance-new</a> JSMs (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878457">bug</a>)</li>
<li>Dylan made the Netmonitor to show resources loaded from a file url (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870580">bug</a>)
<ul>
<li><img src="https://blog.nightly.mozilla.org/files/2024/02/headlines155_2.png" /></li>
<li><a href="https://snipboard.io/JZ0lfn.jpg">screenshot</a></li>
</ul>
</li>
<li>Nicolas added an option in the settings panel to control the behavior of the Enter key in the Rules view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878490">bug</a>)
<ul>
<li><img src="https://blog.nightly.mozilla.org/files/2024/02/headlines155_3.png" /></li>
<li><a href="https://snipboard.io/sRYByf.jpg">screenshot</a></li>
</ul>
</li>
<li>Nicolas started the migration of DevTools to CodeMirror6. The first consumer is the EventTooltip, in the markup view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878605">bug</a>)</li>
<li>Hubert will manage the migration of the Debugger to the new CodeMirror version, which will happen incrementally behind a pref, until everything is ready (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878644">bug</a>)</li>
</ul>
<h5>WebDrive BiDi</h5>
<ul>
<li>Thanks to Jing Zhu for updating various deserialization methods in RemoteAgent to match the specifications more closely (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1832792">bug</a>).</li>
<li>Kagami updated Marionette permissions to handle storage-related permissions (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875257">bug</a>).</li>
<li>Sasha implemented the storage.getCookie command, which allows to retrieve cookies (with support for partitions and filtering) (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1854580">bug</a>).</li>
<li>Sasha also implemented the storage.setCookie command to create new cookies (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1854582">bug</a>).</li>
<li>Julian added basic support for two network interception commands network.continueRequest and network.continueResponse (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874206">bug</a>). We also removed the experimental flag gating the various network interception commands (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1845345">bug</a>).</li>
<li>Julian implemented the userContext parameter for browsingContext.create, which allows to set user context (Firefox container) owning a new tab or window (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874918">bug</a>). We added the userContext field to events and payloads describing a browsing context, so that you can check which container owns a given browsing context (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874920">bug</a>).</li>
<li>Julian fixed a bug for the network.fetchError event which was missing in case a network request failed really early on (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877438">bug</a>).</li>
<li>Henrik fixed a bug with Get Element Text (WebDriver classic) which could fail when used with web components (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1865381">bug</a>).</li>
</ul>
<h4>ESMification status</h4>
<ul>
<li>
<ul>
<li>ESMified status:
<ul>
<li>browser: <b>100%!</b></li>
<li>toolkit: 99.83%</li>
<li>devtools: 89.09%</li>
<li>dom: 96%</li>
<li>services: 98.94%</li>
<li><b>Only 10 JSMs left in the tree!</b></li>
<li>Total: 99.34% (+.86% from last week)</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>
<ul>
<li></li>
</ul>
</li>
</ul>
<ul>
<li></li>
<li>#esmification on Matrix</li>
<li><img src="https://blog.nightly.mozilla.org/files/2024/02/headlines155_4.png" /></li>
</ul>
<h4>Information Management</h4>
<ul>
<li>Firefox View
<ul>
<li>More Open Tabs features we’re planning to ship in 125: Pinned Tabs, Bookmark and New Tab pinned Indicators</li>
</ul>
</li>
<li>Session Restore
<ul>
<li>Change to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1861555">browser.sessionstore.max_windows_undo</a> to change from 3 to 5 as part of incremental improvements this module</li>
</ul>
</li>
</ul>
<h4>Picture-in-Picture</h4>
<ul>
<li>bradwerth has <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1880558">posted a patch</a> that makes the Picture-in-Picture player window use the native macOS fullscreen mode</li>
</ul>
<h4>Performance</h4>
<ul>
<li>Shout out to aosmond who <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877429#c30">landed a patch that resulted in some nice gains in offscreen canvas and webcodecs rendering benchmarks</a>!</li>
<li>The off-main-thread Windows Jump List implementation got a green sign-off from QA and is <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1880082">riding the trains to Firefox 124 beta</a>!</li>
<li>We <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1749345">improved the performance</a> of launching Firefox after installing on a system with a pre-existing user profile with the stub installer</li>
</ul>
<h4>Reader Mode</h4>
<ul>
<li>Irene landed a patch that fixes Reader Mode losing its scroll position when navigating a link and returning back (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1780350">1780350</a>)</li>
<li>Irene also implemented an enhancement allowing for Reader Mode paragraph spacing to adjust alongside line-height (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874983">1874983</a>)</li>
</ul>
<h4>Screenshots (set screenshots.browser.component.enabled to true)</h4>
<ul>
<li>sfoster fixed <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874154">a bug to consistently</a> position the screenshot copied indicator</li>
<li>niklas updated screenshots so <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1791086">hovering elements within an iframe</a> is now possible</li>
<li>niklas fixed a bug where the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874026">overlay could draw outside the document</a></li>
</ul>
<h4>Search and Navigation</h4>
<h5>Enhanced Cross-Platform Suggest</h5>
<ul>
<li>Drew updated the MDN suggestion code, weather suggestion code and quick suggest config to account for all three of those suggestion types being implemented in Rust (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877595">1877595</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878441">1878441</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878444">1878444</a>)</li>
<li>Drew finalized the UX for Yelp suggestions (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878727">1878727</a>)</li>
<li>Drew added a “Local recommendations” group label for Yelp suggestions (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879397">1879397</a>)</li>
<li>Drew updated the Yelp desktop suggestions to accommodate certain prefix-matching rules that are applied to what the user types into the urlbar (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879642">1879642</a>)</li>
<li>Daisuke implemented the result menu for Yelp suggestions (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878728">1878728</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879637">1879637</a>)</li>
<li>Daisuke ensured Yelp suggestions are labeled as “sponsored” (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878814">1878814</a>)</li>
<li>Daisuke added a Nimbus variable for testing Yelp suggestions as a top pick (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877920">1877920</a>)</li>
<li>Daisuke allowed Yelp suggestions to pull location information from the Merino service if that Yelp suggestion didn’t already have a location (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878206">1878206</a>)</li>
</ul>
<p> </p>
<h5>Search and SERP (Search Engine Result Page) telemetry</h5>
<ul>
<li>James and Stephanie have continued their work on the SERP categorization project (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1848197">1848197</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879737">1879737</a>)</li>
<li>James fixed two issues with how we record SERP telemetry when the SERP is a single page app (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878062">1878062</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879404">1879404</a>)</li>
</ul>
<p> </p>
<h5>Consolidated Search Configuration</h5>
<ul>
<li>Mandy fixed an issue where prior search settings were lost when using Amazon as the default search engine in Spain (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878277">1878277</a>)</li>
</ul>
<p> </p>
<h5>General Search Service</h5>
<ul>
<li>Standard8 simplified the way the search service loads engines (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1879126">1879126</a>)</li>
</ul>
<p> </p>
<h5>General Improvements</h5>
<p>Karandeep landed the first in a series of patches to remove an ultimately unused API for urlbar experiments (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1855958">1855958</a>)</p>2024-02-26T17:22:35+00:00Niklas BaumgardnerThe Rust Programming Language Blog: Updated baseline standards for Windows targets
https://blog.rust-lang.org/2024/02/26/Windows-7.html
<p>The minimum requirements for Tier 1 toolchains targeting Windows will increase with the 1.78 release (scheduled for May 02, 2024).
Windows 10 will now be the minimum supported version for the <code>*-pc-windows-*</code> targets.
These requirements apply both to the Rust toolchain itself and to binaries produced by Rust.</p>
<p>Two new targets have been added with Windows 7 as their baseline: <code>x86_64-win7-windows-msvc</code> and <code>i686-win7-windows-msvc</code>.
They are starting as Tier 3 targets, meaning that the Rust codebase has support for them but we don't build or test them automatically.
Once these targets reach Tier 2 status, they will be available to use via rustup.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/26/Windows-7.html#affected-targets" id="affected-targets"></a>Affected targets</h3>
<ul>
<li><code>x86_64-pc-windows-msvc</code></li>
<li><code>i686-pc-windows-msvc</code></li>
<li><code>x86_64-pc-windows-gnu</code></li>
<li><code>i686-pc-windows-gnu</code></li>
<li><code>x86_64-pc-windows-gnullvm</code></li>
<li><code>i686-pc-windows-gnullvm</code></li>
</ul>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/26/Windows-7.html#why-are-the-requirements-being-changed" id="why-are-the-requirements-being-changed"></a>Why are the requirements being changed?</h3>
<p>Prior to now, Rust had Tier 1 support for Windows 7, 8, and 8.1 but these targets no longer meet our requirements.
In particular, these targets could no longer be tested in CI which is required by the <a href="https://doc.rust-lang.org/rustc/target-tier-policy.html#tier-1-target-policy">Target Tier Policy</a> and are not supported by their vendor.</p>2024-02-26T00:00:00+00:00Chris Denton on behalf of the Compiler TeamThe Talospace Project: Firefox 123 on POWER
https://www.talospace.com/2024/02/firefox-123-on-power.html
Finally getting back towards something approaching current. <a href="https://www.mozilla.org/en-US/firefox/123.0/releasenotes/">Firefox 123 is out</a>, adding <a href="https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/123">platform improvements</a>, off-main-thread canvas and the ability to report problematic sites. Or, I dunno, sites that work just fine but claim they don't, like PG&E, the soulless natural monopolist Abilisks of northern California. No particular reason. The other reported improvement was PGO optimization improvements on Apple silicon Macs and Android. How cute! Meanwhile, <a href="https://gist.github.com/classilla/1202f8d467749c029325278a87a068c8">our own PGO-LTO patch got simpler</a> and I was able to drop the other changes we needed for Python 3.12 on Fedora 39, which now builds with this smaller PGO-LTO patch and <a href="https://www.talospace.com/2024/01/firefox-122-on-power.html"><tt>.mozconfig</tt>s from Firefox 122</a>. Some of you reported crashes on Fx122 but I haven't observed any with that release or this one built from source. Fingers crossed.2024-02-25T07:00:43+00:00ClassicHasClassPatrick Cloke: Joining the Matrix Spec Core Team
https://patrick.cloke.us/posts/2024/02/23/joining-the-matrix-spec-core-team/
<p>I was recently invited to join the Matrix “Spec Core Team”, the group who
steward the Matrix protocol, from their <a class="reference external" href="https://matrix.org/about/">own documentation</a>:</p>
<blockquote>
The contents and direction of the Matrix Spec is governed by the Spec Core Team;
a set of experts from across the whole Matrix community, representing all aspects
of the Matrix ecosystem. The Spec Core Team acts as a subcommittee of the Foundation.</blockquote>
<p>This was the <a class="reference external" href="https://matrix.org/blog/2024/02/09/this-week-in-matrix-2024-02-09/#dept-of-status-of-matrix-face-with-th">announced a couple of weeks ago</a> and I’m just starting to get my feet
wet! You can see an interview between myself, Tulir (another new member of the Spec
Core Team), and Matthew (the Spec Core Team lead) in today’s <a class="reference external" href="https://matrix.org/blog/2024/02/23/this-week-in-matrix-2024-02-23/">This Week in Matrix</a>.
We cover a range of topics including <a class="reference external" href="https://www.thunderbird.net/">Thunderbird</a> (and <a class="reference external" href="http://instantbird.com/">Instantbird</a>), some
improvements I hope to make and more.</p>
<div class="youtube youtube-16x9"></div>2024-02-23T21:01:00+00:00Patrick ClokePatrick Cloke: Synapse URL Previews
https://patrick.cloke.us/posts/2024/02/23/synapse-url-previews/
<p>Matrix includes the ability for a client to request that the server
<a class="reference external" href="https://spec.matrix.org/v1.8/client-server-api/#get_matrixmediav3preview_url">generate a “preview” for a <span class="caps">URL</span></a>. The client provides a <span class="caps">URL</span> to the server which
returns <a class="reference external" href="https://ogp.me/">Open Graph</a> data as a <span class="caps">JSON</span> response. This leaks any URLs detected in
the message content to the server, but protects the end user’s <span class="caps">IP</span> address, etc.
from the <span class="caps">URL</span> being previewed. <a class="footnote-reference" href="http://patrick.cloke.us/feeds/rss.xml#footnote-1" id="footnote-reference-1">[1]</a> (Note that clients generally disable <span class="caps">URL</span> previews
for encrypted rooms, but it can be enabled.)</p>
<div class="section" id="improvements">
<h3>Improvements</h3>
<p>Synapse implements the <span class="caps">URL</span> preview endpoint, but it was a bit neglected. I was
one of the few main developers running with <span class="caps">URL</span> previews enabled and sunk a bit of
time into improving <span class="caps">URL</span> previews for my on sake. Some highlights of the improvements
made include (in addition to lots and lots of refactoring):</p>
<ul class="simple">
<li>Support <a class="reference external" href="https://oembed.com/">oEmbed</a> for <span class="caps">URL</span> previews:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/7920">#7920</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/10714">#10714</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/10759">#10759</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/10814">#10814</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/10819">#10819</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/10822">#10822</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/11065">#11065</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/11669">#11669</a> (combine with <span class="caps">HTML</span> results),
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/14089">#14089</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/14781">#14781</a>.</li>
<li>Reduction of 500 errors:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/8883">#8883</a> (empty media),
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/9333">#9333</a> (unable to parse),
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/11061">#11061</a> (oEmbed errors).</li>
<li>Improved support for document encodings:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/9164">#9164</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/9333">#9333</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/11077">#11077</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/11089">#11089</a>.</li>
<li>Support previewing <span class="caps">XML</span> documents (<a class="reference external" href="https://github.com/matrix-org/synapse/pull/11196">#11196</a>)
and <tt class="docutils literal">data:</tt> URIs (<a class="reference external" href="https://github.com/matrix-org/synapse/pull/11767">#11767</a>).</li>
<li>Return partial information if images or oEmbed can’t be fetched:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/12950">#12950</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/15092">#15092</a>.</li>
<li>Skipping empty Open Graph (<tt class="docutils literal">og</tt>) or <tt class="docutils literal">meta</tt> tags:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/12951">#12951</a>.</li>
<li>Support previewing from <a class="reference external" href="https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started">Twitter card information</a>:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/13056">#13056</a>.</li>
<li>Fallback to favicon if no images found:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/12951">#12951</a>.</li>
<li>Ignore navgiation tags: <a class="reference external" href="https://github.com/matrix-org/synapse/pull/12951">#12951</a>.</li>
<li>Document how Synapse <a class="reference external" href="https://github.com/matrix-org/synapse/blob/be65a8ec0195955c15fdb179c9158b187638e39a/synapse/media/url_previewer.py#L101-L154">generates <span class="caps">URL</span> previews</a>:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/10753">#10753</a>,
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/13261">#13261</a>.</li>
</ul>
<p>I also helped review many changes by others:</p>
<ul class="simple">
<li>Improved support for encodings: <a class="reference external" href="https://github.com/matrix-org/synapse/pull/10410">#10410</a>.</li>
<li>Safer content-type support: <a class="reference external" href="https://github.com/matrix-org/synapse/pull/11936">#11936</a>.</li>
<li>Attempts to fix Twitter previews: <a class="reference external" href="https://github.com/matrix-org/synapse/pull/11985">#11985</a>.</li>
<li>Remove useless elements from previews: <a class="reference external" href="https://github.com/matrix-org/synapse/pull/12887">#12887</a>.</li>
<li>Avoid crashes due to unbounded recursion:
<a class="reference external" href="https://github.com/matrix-org/synapse/security/advisories/GHSA-22p3-qrh9-cx32"><span class="caps">GHSA</span>-22p3-qrh9-cx32</a>.</li>
</ul>
<p>And also fixed some security issues:</p>
<ul class="simple">
<li>Apply <tt class="docutils literal">url_preview_url_blacklist</tt> to oEmbed and pre-cached images:
<a class="reference external" href="https://github.com/matrix-org/synapse/pull/15601">#15601</a>.</li>
</ul>
</div>
<div class="section" id="results">
<h3>Results</h3>
<p>Overall, there was an improved result (from my point of view). A summary of some
of the improvements. I tested 26 URLs (based on ones that had previously been
reported or found to give issues). See the table below for testing at a few versions.
The error reason was also broken out into whether JavaScript was required or some
other error occurred. <a class="footnote-reference" href="http://patrick.cloke.us/feeds/rss.xml#footnote-2" id="footnote-reference-2">[2]</a></p>
<table border="1" class="docutils">
<colgroup>
<col width="9%" />
<col width="14%" />
<col width="20%" />
<col width="28%" />
<col width="29%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Version</th>
<th class="head">Release date</th>
<th class="head">Successful preview</th>
<th class="head">JavaScript required error</th>
<th class="head">Found image <span class="amp">&</span> description?</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>1.0.0</td>
<td>2019-06-11</td>
<td>15</td>
<td>4</td>
<td>14</td>
</tr>
<tr><td>1.12.0</td>
<td>2020-03-23</td>
<td>18</td>
<td>4</td>
<td>17</td>
</tr>
<tr><td>1.24.0</td>
<td>2020-12-09</td>
<td>20</td>
<td>1</td>
<td>16</td>
</tr>
<tr><td>1.36.0</td>
<td>2021-06-15</td>
<td>20</td>
<td>1</td>
<td>16</td>
</tr>
<tr><td>1.48.0</td>
<td>2021-11-30</td>
<td>20</td>
<td>1</td>
<td>11</td>
</tr>
<tr><td>1.60.0</td>
<td>2022-05-31</td>
<td>21</td>
<td>0</td>
<td>21</td>
</tr>
<tr><td>1.72.0</td>
<td>2022-11-22</td>
<td>22</td>
<td>0</td>
<td>21</td>
</tr>
<tr><td>1.84.0</td>
<td>2023-05-23</td>
<td>22</td>
<td>0</td>
<td>21</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="future-improvements">
<h3>Future improvements</h3>
<p>I am no longer working on Synapse, but some of the ideas I had for additional improvements included:</p>
<ul class="simple">
<li>Use <a class="reference external" href="https://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a> instead of a custom parser to handle some edge cases in <span class="caps">HTML</span>
documents better (<span class="caps">WIP</span> @ <a class="reference external" href="https://github.com/matrix-org/synapse/tree/clokep/bs4"><tt class="docutils literal">clokep/bs4</tt></a>).</li>
<li>Always request both oEmbed and <span class="caps">HTML</span> (<span class="caps">WIP</span> @ <a class="reference external" href="https://github.com/matrix-org/synapse/tree/clokep/oembed-and-html"><tt class="docutils literal"><span class="pre">clokep/oembed-and-html</span></tt></a>).</li>
<li>Structured data support (<a class="reference external" href="https://json-ld.org/"><span class="caps">JSON</span>-<span class="caps">LD</span></a>, <a class="reference external" href="https://html.spec.whatwg.org/multipage/">Microdata</a>, <a class="reference external" href="https://rdfa.info/">RDFa</a>) (<a class="reference external" href="https://github.com/matrix-org/synapse/issues/11540">#11540</a>).</li>
<li>Some minimal JavaScript support (<a class="reference external" href="https://github.com/matrix-org/synapse/issues/14118">#14118</a>).</li>
<li>Fixing any of the other issues with particular URLs (see this <a class="reference external" href="https://github.com/matrix-org/synapse/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3AA-URL-Preview+">GitHub search</a>).</li>
<li>Thumbnailing of <span class="caps">SVG</span> images (which sites tend to use for favicons) (<a class="reference external" href="https://github.com/matrix-org/synapse/issues/1309">#1309</a>).</li>
</ul>
<p>There’s also a ton more that could be done here if you wanted, e.g. handling more
data types (text and <span class="caps">PDF</span> are the ones I have frequently come across that would be
helpful to preview). I’m sure there are also many other URLs that don’t work right
now for some reason. Hopefully the <span class="caps">URL</span> preview code continues to improve!</p>
<table class="docutils footnote" frame="void" id="footnote-1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="http://patrick.cloke.us/feeds/rss.xml#footnote-reference-1">[1]</a></td><td>See some <a class="reference external" href="https://github.com/matrix-org/matrix-spec/blob/main/attic/drafts/url_previews.md">ancient documentation</a> on the tradeoffs and design of <span class="caps">URL</span> previews.
<a class="reference external" href="https://github.com/matrix-org/matrix-spec-proposals/pull/4095"><span class="caps">MSC4095</span></a> was recently written to bundle the <span class="caps">URL</span> preview information into
evens.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="footnote-2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="http://patrick.cloke.us/feeds/rss.xml#footnote-reference-2">[2]</a></td><td>This was done by instantiating different Synapse versions via Docker and
asking them to preview URLs. (See <a class="reference external" href="https://github.com/clokep/test-matrix-url-previews/tree/e0e20154ec348fc25d203546ddede0c881b9772a/docker">the code</a>.) This is not a super realistic
test since it assumes that URLs are static over time. In particular some
sites (e.g. Twitter) like to change what they allow you to access without
being authenticated.</td></tr>
</tbody>
</table>
</div>2024-02-23T20:35:00+00:00Patrick ClokeThe Mozilla Blog: Next steps for Mozilla and Trustworthy AI
https://blog.mozilla.org/en/mozilla/ai/next-steps-for-mozilla-and-trustworthy-ai/
<p></p>
<p><em>(In short: Mozilla has updated its take on the state of AI — and what we need to do to make AI more trustworthy.</em> <em><strong>Read <a href="https://foundation.mozilla.org/en/research/library/accelerating-progress-toward-trustworthy-ai/whitepaper/">the paper </a>and share your feedback: AIPaper@mozillafoundation.org.)</strong></em></p>
<p>In 2020, when Mozilla first focused its philanthropy and advocacy on trustworthy AI, we published a<a href="https://foundation.mozilla.org/en/blog/trustworthy-ai-abridged-version/"> paper</a> outlining our vision. We mapped the barriers to a better AI ecosystem — barriers like centralization, algorithmic bias, and poor data privacy norms. We also mapped paths forward, like shifting industry norms and introducing new regulations and incentives. </p>
<p>The upshot of that report? We learned AI has a lot in common with the early web. So much promise, but also peril — with harms spanning privacy, security, centralization, and competition. Mozilla’s expertise in open source and holding incumbent tech players accountable put us in a good place to unpack this dynamic and take action. </p>
<p>A lot has changed since 2020. AI technology has grown more centralized, powerful, and pervasive; its risks and opportunities are not abstractions. Conversations about AI have grown louder and more urgent. Meanwhile, within Mozilla, we’ve made progress on our vision, from <a href="https://www.mozilla.ai/">research</a> and <a href="https://mozilla.vc/">investments</a> to <a href="https://www.fakespot.com/">products</a> and <a href="https://foundation.mozilla.org/en/what-we-fund/trustworthy-ai-funding-principles/">grantmaking</a>. </p>
<p><strong>Today, we’re publishing an update to our 2020 report — the progress we’ve made so far, and the work that is left to do.</strong></p>
<p><a href="https://mzl.la/accelerating-trustworthy-AI"><strong><em>[Read: Accelerating Progress Toward Trustworthy AI]</em></strong></a></p>
<p>Our original paper focused on four strategic areas: </p>
<ul>
<li>Changing AI development norms,</li>
<li>Building new tech and products,</li>
<li>Raising consumer awareness,</li>
<li>Strengthening AI regulations and incentives. </li>
</ul>
<p>This update revisits those areas, outlining what’s changed for the better, what’s changed for the worse, and what’s stayed the same. At a very high level, our takeaways are:</p>
<ul>
<li>Norms: The people that broke the internet are the ones building AI. </li>
<li>Products: More trustworthy AI products need to be mainstream. </li>
<li>Consumers: A more engaged public still needs better choices on AI. </li>
<li>Policy: Governments are making progress while grappling with conflicting influences. </li>
</ul>
<p>A consistent theme across these areas is the importance and potential of openness for the development of more trustworthy AI — something Mozilla <a href="https://open.mozilla.org/letter/">hasn’t been quiet about</a>. </p>
<p>Our first trustworthy AI paper was both a guidepost and map, and this one will be, too. Within are Mozilla’s plans for engaging with AI issues and trends. The paper outlines five key steps Mozilla will take in the years ahead (like making open-source generative AI more trustworthy and mainstream), and also five steps the broader movement can take (like pushing back on regulations that would make AI even less open). </p>
<p>Our first paper was also “open source,” and this one is, too. We are seeking input on the report and on the state of the AI ecosystem more broadly. Through your comments and a series of public events, we will take feedback from the AI community and use it to strengthen our understanding and vision for the future. <strong>Please contact us at AIPaper@mozillafoundation.org and send us your feedback on the report, as well as examples of trustworthy AI approaches and applications.</strong></p>
<p>The movement for trustworthy AI has made meaningful progress since 2020, but there’s still much more work to be done. It’s time to redouble our efforts and recommit to our core principles, and this report is Mozilla’s next step in doing that.<em> </em>It will take all of us, working together, to turn this vision into reality. There’s no time to waste — let’s get to work.</p>
<p>The post <a href="https://blog.mozilla.org/en/mozilla/ai/next-steps-for-mozilla-and-trustworthy-ai/">Next steps for Mozilla and Trustworthy AI</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-02-22T16:15:00+00:00Mark SurmanThis Week In Rust: This Week in Rust 535
https://this-week-in-rust.org/blog/2024/02/21/this-week-in-rust-535/
<p>Hello and welcome to another issue of <em>This Week in Rust</em>!
<a href="https://www.rust-lang.org/">Rust</a> is a programming language empowering everyone to build reliable and efficient software.
This is a weekly summary of its progress and community.
Want something mentioned? Tag us at <a href="https://twitter.com/ThisWeekInRust">@ThisWeekInRust</a> on Twitter or <a href="https://mastodon.social/@thisweekinrust">@ThisWeekinRust</a> on mastodon.social, or <a href="https://github.com/rust-lang/this-week-in-rust">send us a pull request</a>.
Want to get involved? <a href="https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md">We love contributions</a>.</p>
<p><em>This Week in Rust</em> is openly developed <a href="https://github.com/rust-lang/this-week-in-rust">on GitHub</a> and archives can be viewed at <a href="https://this-week-in-rust.org/">this-week-in-rust.org</a>.
If you find any errors in this week's issue, <a href="https://github.com/rust-lang/this-week-in-rust/pulls">please submit a PR</a>.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-rust-community">Updates from Rust Community</a></h4>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#official">Official</a></h5>
<ul>
<li><a href="https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html">2023 Annual Rust Survey Results</a></li>
<li><a href="https://blog.rust-lang.org/2024/02/21/Rust-participates-in-GSoC-2024.html">Rust participates in Google Summer of Code 2024</a></li>
<li><a href="https://blog.rust-lang.org/inside-rust/2024/02/19/leadership-council-repr-selection.html">Leadership Council March Representative Selections</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#foundation">Foundation</a></h5>
<ul>
<li><a href="https://foundation.rust-lang.org/news/save-the-date-rustconf-2024-september-10-13/">Save the Date: RustConf 2024 – September 10-13</a></li>
<li><a href="https://foundation.rust-lang.org/news/second-security-initiative-report-details-rust-security-advancements/">Second Security Initiative Report Details Rust Security Advancements</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#projecttooling-updates">Project/Tooling Updates</a></h5>
<ul>
<li><a href="https://bevyengine.org/news/bevy-0-13/">Bevy 0.13</a></li>
<li><a href="https://joonaa.dev/blog/05/bevy-xpbd-0-4-0">Bevy XPBD 0.4: Collider Agnosticism, Layer Rework, and Bevy 0.13</a></li>
<li><a href="https://astral.sh/blog/uv">uv: Python packaging in Rust</a></li>
<li><a href="https://git-cliff.org/blog/2.0.0/">git-cliff: What's new in 2.0.0? (highly customizable changelog generator)</a></li>
<li><a href="https://blog.antoyo.xyz/rustc_codegen_gcc-progress-report-30">rustc_codegen_gcc: Progress Report #30</a></li>
<li><a href="https://blog.jetbrains.com/rust/2024/02/14/q4-2023-features-retrospective/">RustRover Q4 2023 Feature Updates Retrospective</a></li>
<li><a href="https://rust-analyzer.github.io/thisweek/2024/02/19/changelog-221.html">rust-analyzer changelog #221</a></li>
<li><a href="https://www.reddit.com/r/rust/comments/1amjknw/anouncing_stabby_300_and_rustconf_video_available/">Anouncing Stabby 3.0</a></li>
<li><a href="https://argmin-rs.org/blog/argmin-testfunctions-v0-2-0/">argmin_testfunctions 0.2.0: test functions for optimization problems in Rust and Python</a></li>
<li><a href="https://github.com/emberian/vscode-rustup">vscode-rustup released: interface with rustup as a VSCode extension</a></li>
<li><a href="https://codeberg.org/openpgp-card/openpgp-card-tools">OpenPGP-card-tools 0.10.0 released. The project provides the <code>oct</code> commandline tool for inspecting, configuring and using OpenPGP card devices such as Nitrokey or Yubikey.</a></li>
<li><a href="https://www.timeplus.com/post/rust-client-for-proton">Rust Client for Timeplus Proton SQL Streaming</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#observationsthoughts">Observations/Thoughts</a></h5>
<ul>
<li><a href="https://without.boats/blog/futures-unordered/">FuturesUnordered and the order of futures</a></li>
<li><a href="https://www.shuttle.rs/blog/2024/02/15/best-rust-tooling">Rust Tooling: 8 tools that will increase your productivity</a></li>
<li><a href="https://gist.github.com/ia0/820ab50d4c5f0f5e3aeb841cef8e6792">Writing down my mental model of unsafe</a></li>
<li><a href="https://kerkour.com/rust-fast-techempower-web-framework-benchmarks">How can Rust be so fast in the TechEmpower Web Framework Benchmarks?</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-walkthroughs">Rust Walkthroughs</a></h5>
<ul>
<li><a href="https://registerspill.thorstenball.com/p/from-1s-to-4ms">From 1s to 4ms</a></li>
<li><a href="https://mary.codes/blog/programming/translating_openstreetmaps_to_HTML5_canvas_rust_wasm/">Translating OpenStreetMap data to HTML5 Canvas with Rust and WebAssembly</a></li>
<li><a href="https://auroranssolis.github.io/rust/2024/02/14/macros-rule.html">macros_rule!</a></li>
<li><a href="https://www.shuttle.rs/blog/2024/02/21/using-jwt-auth-rust">Implementing JWT Authentication in Rust</a></li>
<li><a href="https://medium.com/@sam.van.overmeire/deploying-axum-to-lambda-and-ecs-using-lambda-web-adapter-2273bd56bb81">Deploying Axum to Lambda and ECS, using Lambda Web Adapter</a></li>
<li><a href="https://tylerjw.dev/posts/rust-cmake-interop-part-3-cxx/">Rust/C++ Interop Part 3 - Cxx</a></li>
<li>[FR] <a href="https://lafor.ge/closure/">Les closures en Rust</a></li>
<li>[video] <a href="https://www.youtube.com/watch?v=vfMpIsJwpjU">Safe Rust AIN'T SAFE!? (cve-rs)</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#miscellaneous">Miscellaneous</a></h5>
<ul>
<li>[video] <a href="https://www.youtube.com/watch?v=kXPBVGDkQSs">Release-plz: releasing crates like it's 2023 (RustLab 2023)</a></li>
</ul>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#crate-of-the-week">Crate of the Week</a></h4>
<p>This week's crate is <a href="https://github.com/wingbackapp/kind/">kind</a>, a helper crate for typed UUIDs.</p>
<p>Thanks to <a href="https://users.rust-lang.org/t/crate-of-the-week/2704/1290">Denys Séguret</a> for the self-suggestion!</p>
<p><a href="https://users.rust-lang.org/t/crate-of-the-week/2704">Please submit your suggestions and votes for next week</a>!</p>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-testing"></a><a href="https://github.com/rust-lang/rfcs/issues?q=label%3Acall-for-testing">Call for Testing</a></h6>
<p>An important step for RFC implementation is for people to experiment with the
implementation and give feedback, especially before stabilization. The following
RFCs would benefit from user testing before moving forward:</p>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/3013">RFC: Checking conditional compilation at compile time</a><ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/3013#issuecomment-1936648479">Testing steps</a></li>
</ul>
</li>
</ul>
<p>If you are a feature implementer and would like your RFC to appear on the above list, add the new <code>call-for-testing</code>
label to your RFC along with a comment providing testing instructions and/or guidance on which aspect(s) of the feature
need testing.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#call-for-participation-projects-and-speakers">Call for Participation; projects and speakers</a></h4>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-projects">CFP - Projects</a></h5>
<p>Always wanted to contribute to open-source projects but did not know where to start?
Every week we highlight some tasks from the Rust community for you to pick and get started!</p>
<p>Some of these tasks may also have mentors available, visit the task page for more information.</p>
<ul>
<li><a href="https://github.com/build-trust/ockam/issues/7471">Ockam - Syntax highlighting for fenced code blocks, in command help output, on Linux works</a></li>
<li><a href="https://github.com/build-trust/ockam/issues/7575">Ockam - Shut down Worker/Processor if initialization failed</a></li>
<li><a href="https://github.com/build-trust/ockam/issues/7478">Ockam - Output for ockam project ticket is improved and information is not opaque</a></li>
<li><a href="https://github.com/juspay/hyperswitch/issues/3749">Hyperswitch - [FEATURE] : add <code>offset</code> field to disputes list</a></li>
<li><a href="https://github.com/juspay/hyperswitch/issues/3748">Hyperswitch - [FEATURE]: add<code>offset</code> field to mandates list</a></li>
<li><a href="https://github.com/juspay/hyperswitch/issues/3746">Hyperswitch - [FEATURE]: add pagination support for customers list</a></li>
</ul>
<p>If you are a Rust project owner and are looking for contributors, please submit tasks <a href="https://users.rust-lang.org/t/twir-call-for-participation/4821">here</a>.</p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#cfp-speakers">CFP - Speakers</a></h5>
<p>Are you a new or experienced speaker looking for a place to share something cool? This section highlights events that are being planned and are accepting submissions to join their event as a speaker.</p>
<p>If you are an event organizer hoping to expand the reach of your event, please submit a link to the submission website through a <a href="https://github.com/rust-lang/this-week-in-rust">PR to TWiR</a>.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#updates-from-the-rust-project">Updates from the Rust Project</a></h4>
<p>508 pull requests were <a href="https://github.com/search?q=is%3Apr+org%3Arust-lang+is%3Amerged+merged%3A2024-02-13..2024-02-20">merged in the last week</a></p>
<ul>
<li><a href="https://github.com/rust-lang/rust/pull/121088">implicitly enable evex512 if avx512 is enabled</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120932"><code>const_mut_refs</code>: allow mutable pointers to statics</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119673"><code>macro_rules</code>: Preserve all metavariable spans in a global side table</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120982">add APIs for fetching foreign items</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121203">add <code>rust.frame-pointers</code> config option</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121198">add more checks for <code>unnamed_fields</code> during HIR analysis</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121256">allow AST and HIR visitors to return <code>ControlFlow</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121179">allow mutable references in const values when they point to no memory</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121087">always evaluate free constants and statics, even if previous errors occurred</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121020">avoid an ICE in diagnostics</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120530">be less confident when <code>dyn</code> suggestion is not checked for object safety</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/118882">check normalized call signature for WF in mir typeck</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119338">consider principal trait ref's auto-trait super-traits in dyn upcasting</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120847">continue compilation after <code>check_mod_type_wf</code> errors</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121113">continue compilation even if inherent impl checks fail</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121032">continue reporting remaining errors instead of silently dropping them</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121100">detect when method call on argument could be removed to fulfill failed trait bound</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121181">fix an ICE in the recursion lint</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121104">ignore unsized types when trying to determine the size of the original type</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119432">make <code>ConstPropLint</code> lint run on promoteds</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121119">make <code>async Fn</code> trait kind errors better</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120780">properly deal with weak alias types as self types of impls</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121286">rename <code>ConstPropLint</code> to <code>KnownPanicsLint</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/116564">store static initializers in metadata instead of the MIR of statics</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119928">suggest <code>into_iter()</code> when <code>Iterator</code> method called on <code>impl IntoIterator</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121318">trigger <code>unsafe_code</code> lint on invocations of <code>global_asm</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121193">use fulfillment in next trait solver coherence</a></li>
<li><a href="https://github.com/rust-lang/miri/pull/3192">miri: implement x86 AVX intrinsics</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121015">optimize <code>delayed_bug</code> handling</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/100603">optimize away poison guards when std is built with panic=abort</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120576">overhaul <code>Diagnostic</code> and <code>DiagnosticBuilder</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120889">implement <code>Instant</code> for UEFI</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121024">implement <code>Default</code> for <code>AsciiChar</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/119808">store <code>core::str::CharSearcher::utf8_size</code> as u8</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120538">make <code>File::read_to_end</code> less special</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121241">implement <code>NonZero</code> traits generically</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120563">make <code>NonZero::get</code> generic</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120741">make <code>io::BorrowedCursor::advance</code> safe</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121311">make <code>is_nonoverlapping #[inline]</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121204">specialize flattening iterators with only one inner item</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/105917">specialize some methods of <code>io::Chain</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/116385">rename <code>MaybeUninit::write_slice</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120952">don't use <code>mem::zeroed</code> in <code>vec::IntoIter</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/118264">optimize <code>VecDeque::drain</code> for (half-)open ranges</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120505">fix BTreeMap's <code>Cursor::remove_{next,prev}</code></a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121041">add <code>Future</code> and <code>IntoFuture</code> to the 2024 prelude</a></li>
<li><a href="https://github.com/rust-lang/hashbrown/pull/505">hashbrown: inline tweaks to <code>HashTable</code></a></li>
<li><a href="https://github.com/rust-lang/hashbrown/pull/495">hashbrown: make <code>HashSet::insert</code> return OccupiedEntry</a></li>
<li><a href="https://github.com/rust-lang/rustc_codegen_gcc/pull/429">codegen_gcc: correctly handle <code>--use-system-gcc</code></a></li>
<li><a href="https://github.com/rust-lang/rustc_codegen_gcc/pull/437">codegen_gcc: implement dummy emit=llvm-ir</a></li>
<li><a href="https://github.com/rust-lang/rustc_codegen_gcc/pull/440">codegen_gcc: use the default rust mangling</a></li>
<li><a href="https://github.com/rust-lang/rustc_codegen_cranelift/pull/1457">codegen_cranelift: fix <code>simd_select_bitmask</code> on big-endian systems</a></li>
<li><a href="https://github.com/rust-lang/rustc_codegen_cranelift/pull/1458">codegen_cranelift: fix download hash check on big-endian systems</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13434">cargo add: Ensure users know a feature is being created</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13446">cargo add: Remove inconsistent period</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/13448">cargo test: Suggest <code>--</code> for libtest arguments</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/12861">cargo: respect <code>rust-version</code> when generating lockfile</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120526">rustdoc: correctly handle long crate names on mobile</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121022">rustdoc: cross-crate re-exports: correctly render late-bound params in source order even if early-bound params are present</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/120548">rustdoc: fix handling of <code>doc_auto_cfg</code> feature for cfg attributes on glob reexport</a></li>
<li><a href="https://github.com/rust-lang/rustfmt/pull/6073">rustfmt: fix error trying to format unnormalized UTF8</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121035">format <code>async</code> trait bounds in rustfmt</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/121137">add clippy into the known <code>cfg</code> list</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12292">clippy: add new lint <code>deprecated_clippy_cfg_attr</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12293">clippy: <code>case_sensitive_file_extension_comparisons</code>: Don't trigger on digits-only extensions</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/11881">clippy: <code>implied_bounds_in_impls</code>: avoid linting on overlapping associated tys</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12275">clippy: <code>incompatible_msrv</code>: allow expressions that come from desugaring</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/10903">clippy: <code>new_without_default</code>: Now emits on const fns</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/11641">clippy: allow negative literals in <code>redundant_guards</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12294">clippy: check trait items in <code>min_ident_chars</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12314">clippy: default test output conflict handling to error</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12305">clippy: ensure ASM syntax detect <code>global_asm!</code> and <code>asm!</code> only on x86 architectures</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12059">clippy: add check for identical guards in lint <code>match_same_arms</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12309">clippy: make <code>#[allow]</code> work on field for <code>pub_underscore_fields</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/12285">clippy: ignore imported items in <code>min_ident_chars</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16550">rust-analyzer: activate on top level <code>Cargo.toml</code> and <code>rust-project.json</code> files</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16358">rust-analyzer: deduplicate references when some of them are in macro expansions</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16489">rust-analyzer: create alias when renaming an import</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16303">rust-analyzer: add non-exhaustive-let diagnostic</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16589">rust-analyzer: add unresolved-ident diagnostic</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16475">rust-analyzer: support multiple tab stops for completions in VSCode</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/15003">rust-analyzer: add basic support for <code>become</code> expr/tail calls</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16618">rust-analyzer: don't add <code>\</code> before <code>{</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16583">rust-analyzer: don't show type mismatches for <code>{unknown}</code> to non-<code>{unknown}</code> mismatches</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16574">rust-analyzer: fix "needless return" diagnostic for trailing item declarations</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16247">rust-analyzer: fix build scripts not being rebuilt in some occasions</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16590">rust-analyzer: fix false positives for "unnecessary else" diagnostic</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16579">rust-analyzer: fix snippets being placed leftwards of where they should be</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16553">rust-analyzer: improve recover on <code>=</code> for record field initializer and pattern</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16544">rust-analyzer: only complete traits in <code>impl .. for</code></a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16569">rust-analyzer: place snippets correctly in multi-edit assists</a></li>
<li><a href="https://github.com/rust-lang/rust-analyzer/pull/16616">rust-analyzer: server hanging up on build script task</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust-compiler-performance-triage">Rust Compiler Performance Triage</a></h5>
<p>Relatively few PRs affecting performance, but massive improvements thanks to the
update to LLVM 18 (PR #12005), as well as the merging of two related compiler
queries (PR #120919) and other small improvements from a rollup (PR #121055).</p>
<p>Triage done by <strong>@pnkfelix</strong>.
Revision range: <a href="https://perf.rust-lang.org/?start=74c3f5a146860c94ff4d179fc3bfa34f879adf41&end=5af2130440c198afefbe5b8099342057cf272ef4&absolute=false&stat=instructions%3Au">74c3f5a1..5af21304</a></p>
<p>3 Regressions, 1 Improvements, 6 Mixed; 1 of them in rollups
65 artifact comparisons made in total</p>
<p><a href="https://github.com/rust-lang/rustc-perf/blob/d18e18944c4ab14988ca5219b17530454d133474/triage/2024-02-20.md">Full report here</a></p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#approved-rfcs"></a><a href="https://github.com/rust-lang/rfcs/commits/master">Approved RFCs</a></h5>
<p>Changes to Rust follow the Rust <a href="https://github.com/rust-lang/rfcs#rust-rfcs">RFC (request for comments) process</a>. These
are the RFCs that were approved for implementation this week:</p>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/3558">eRFC: Iterate on and stabilize libtest's programmatic output</a></li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#final-comment-period">Final Comment Period</a></h5>
<p>Every week, <a href="https://www.rust-lang.org/team.html">the team</a> announces the 'final comment period' for RFCs and key PRs
which are reaching a decision. Express your opinions now.</p>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#rfcs"></a><a href="https://github.com/rust-lang/rfcs/labels/final-comment-period">RFCs</a></h6>
<ul>
<li><a href="https://github.com/rust-lang/rfcs/pull/3537">RFC: Make Cargo respect minimum supported Rust version (MSRV) when selecting dependencies</a></li>
</ul>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#tracking-issues-prs">Tracking Issues & PRs</a></h6>
<a class="toclink" href="http://this-week-in-rust.org/atom.xml#rust"></a><a href="https://github.com/rust-lang/rust/issues?q=is%3Aopen+label%3Afinal-comment-period+sort%3Aupdated-desc">Rust</a>
<ul>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/118247">change equate for binders to not rely on subtyping</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/120393">Implement RFC 3373: Avoid non-local definitions in functions</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/issues/96992">Tracking Issue for <code>waker_getters</code></a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/119888">Stabilize the <code>#[diagnostic]</code> namespace and <code>#[diagnostic::on_unimplemented]</code> attribute</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/issues/80970">Tracking Issue for cfg-target-abi</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/120805">make non-PartialEq-typed consts as patterns a hard error</a></li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rust/pull/99333">Allow ?-converting from <code>Result<T, E></code> in functions returning <code>Option<Result<T, E>></code></a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/99153">Add Read Impl for &Stdin</a></li>
<li>[disposition: merge] <a href="https://github.com/rust-lang/rust/pull/119536">Make <code>Barrier::new()</code> const </a></li>
<li>[disposition: close] <a href="https://github.com/rust-lang/rust/pull/109691">Implement <code>Future</code> for <code>Option<F></code></a></li>
</ul>
<h6><a class="toclink" href="http://this-week-in-rust.org/atom.xml#new-and-updated-rfcs"></a><a href="https://github.com/rust-lang/rfcs/pulls">New and Updated RFCs</a></h6>
<ul>
<li>[new] <a href="https://github.com/rust-lang/rfcs/pull/3573"><code>is</code> operator for pattern-matching and binding</a></li>
</ul>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#upcoming-events">Upcoming Events</a></h4>
<p>Rusty Events between 2024-02-21 - 2024-03-20 🦀</p>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#virtual">Virtual</a></h5>
<ul>
<li>2024-02-21 | Virtual (Cardiff, UK) | <a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/">Rust and C++ Cardiff</a><ul>
<li><a href="https://www.meetup.com/rust-and-c-plus-plus-in-cardiff/events/298991687/"><strong>Rust for Rustaceans Book Club: Chapter 2 - Types</strong></a></li>
</ul>
</li>
<li>2024-02-21 | Virtual (Vancouver, BC, CA) | <a href="https://www.meetup.com/vancouver-rust/">Vancouver Rust</a><ul>
<li><a href="https://www.meetup.com/vancouver-rust/events/292763497/"><strong>Rust Study/Hack/Hang-out</strong></a></li>
</ul>
</li>
<li>2024-02-22 | Virtual (Charlottesville, NC, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/">Charlottesville Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/298251150/"><strong>Crafting Interpreters in Rust Collaboratively</strong></a></li>
</ul>
</li>
<li>2024-02-27 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/">Dallas Rust</a><ul>
<li><a href="https://www.meetup.com/dallasrust/events/299068302/"><strong>Last Tuesday</strong></a></li>
</ul>
</li>
<li>2024-02-29 | Virtual (Berlin, DE) | <a href="https://berline.rs/">OpenTechSchool Berlin</a> + <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://meet.jit.si/RustHackAndLearnBerlin"><strong>Rust Hack and Learn</strong></a> | <a href="https://www.meetup.com/rust-berlin/events/298457901/"><strong>Mirror: Rust Hack n Learn Meetup</strong></a> | <a href="https://berline.rs/2024/02/29/rust-hack-and-learn.html"><strong>Mirror: Berline.rs page</strong></a></li>
</ul>
</li>
<li>2024-02-29 | Virtual (Charlottesville, NC, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/">Charlottesville Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/298372724/"><strong>Surfing the Rusty Wireless Waves with the ESP32-C3 Board</strong></a></li>
</ul>
</li>
<li>2024-03-06 | Virtual (Indianapolis, IN, US) | <a href="https://www.meetup.com/indyrs/">Indy Rust</a><ul>
<li><a href="https://www.meetup.com/indyrs/events/299047891/"><strong>Indy.rs - with Social Distancing</strong></a></li>
</ul>
</li>
<li>2024-03-07 | Virtual (Charlottesville, NC, US) | <a href="https://www.meetup.com/charlottesville-rust-meetup/">Charlottesville Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/charlottesville-rust-meetup/events/298368787/"><strong>Crafting Interpreters in Rust Collaboratively</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Virtual (Dallas, TX, US) | <a href="https://www.meetup.com/dallasrust/">Dallas Rust</a><ul>
<li><a href="https://www.meetup.com/dallasrust/events/298341582/"><strong>Second Tuesday</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Hybrid (Virtual + In-person) Munich, DE | <a href="https://www.meetup.com/rust-munich/">Rust Munich</a><ul>
<li><a href="https://www.meetup.com/rust-munich/events/298507657/"><strong>Rust Munich 2024 / 1 - hybrid</strong></a></li>
</ul>
</li>
<li>2024-03-14 | Virtual (Berlin, DE) | <a href="https://www.meetup.com/opentechschool-berlin/">OpenTechSchool Berlin</a><ul>
<li><a href="https://www.meetup.com/opentechschool-berlin/events/298406445/"><strong>Web Frontend Co-Learning (online)</strong></a></li>
</ul>
</li>
<li>2024-03-21 | Seattle, WA, US | <a href="https://www.meetup.com/seattle-rust-user-group/">Seattle Rust User Group</a><ul>
<li><a href="https://www.meetup.com/seattle-rust-user-group/events/298631832/"><strong>Seattle Rust User Group Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-26 | Virtual + In Person (Barcelona, ES) | <a href="https://www.meetup.com/es-ES/bcnrust/">BcnRust</a><ul>
<li><a href="https://www.meetup.com/es-ES/bcnrust/events/299223178/"><strong>13th BcnRust Meetup</strong></a> - <a href="https://www.youtube.com/@bcnrust">Stream</a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#europe">Europe</a></h5>
<ul>
<li>2024-02-21 | Lyon, FR | <a href="https://www.meetup.com/fr-FR/rust-lyon/">Rust Lyon</a><ul>
<li><a href="https://www.meetup.com/fr-FR/rust-lyon/events/298775631/"><strong>Rust Lyon Meetup #8</strong></a></li>
</ul>
</li>
<li>2024-02-22 | Aarhus, DK | <a href="https://www.meetup.com/rust-aarhus/">Rust Aarhus</a><ul>
<li><a href="https://www.meetup.com/rust-aarhus/events/298689622/"><strong>Rust and Talk at Partisia</strong></a></li>
</ul>
</li>
<li>2024-02-29 | Berlin, DE | <a href="https://www.meetup.com/rust-berlin/">Rust Berlin</a><ul>
<li><a href="https://www.meetup.com/rust-berlin/events/299190389/"><strong>Rust and Tell - Season start 2024</strong></a></li>
</ul>
</li>
<li>2024-03-12 | Munich, DE + Virtual | <a href="https://www.meetup.com/rust-munich/">Rust Munich</a><ul>
<li><a href="https://www.meetup.com/rust-munich/events/298507657/"><strong>Rust Munich 2024 / 1 - hybrid</strong></a></li>
</ul>
</li>
<li>2024-03-19 | Aarhus, DK | <a href="https://www.meetup.com/rust-aarhus/">Rust Aarhus</a><ul>
<li><a href="https://www.meetup.com/rust-aarhus/events/299028814/"><strong>Hack Night</strong></a></li>
</ul>
</li>
<li>2024-03-20 | Girona, ES | <a href="https://www.meetup.com/rust-girona/">Rust Girona</a><ul>
<li><a href="https://www.meetup.com/rust-girona/events/299172343/"><strong>Introduction to programming Microcontrollers with Rust</strong></a></li>
</ul>
</li>
<li>2024-03-26 | Barcelona, ES + Virtual | <a href="https://www.meetup.com/es-ES/bcnrust/">BcnRust</a><ul>
<li><a href="https://www.meetup.com/es-ES/bcnrust/events/299223178/"><strong>13th BcnRust Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-26, 2024-03-28 | London, UK | <a href="https://www.rustnationuk.com/">Rust Nation UK</a><ul>
<li><a href="https://www.rustnationuk.com/"><strong>Rust Nation 2024</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#north-america">North America</a></h5>
<ul>
<li>2024-02-21 | Boston, MA, US | <a href="https://www.meetup.com/bostonrust/">Boston Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/bostonrust/events/299054786/"><strong>Evening Boston Rust Meetup at Microsoft, February 21</strong></a></li>
</ul>
</li>
<li>2024-02-22 | Mountain View, CA, US | <a href="https://www.meetup.com/mv-rust-meetup/">Mountain View Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/mv-rust-meetup/events/299043763/"><strong>Rust Meetup at Hacker Dojo</strong></a></li>
</ul>
</li>
<li>2024-02-28 | Austin, TX, US | <a href="https://www.meetup.com/rust-atx/">Rust ATX</a><ul>
<li><a href="https://www.meetup.com/rust-atx/events/297380841/"><strong>Rust Lunch - Fareground</strong></a></li>
</ul>
</li>
<li>2024-03-07 | Mountain View, CA, US | <a href="https://www.meetup.com/mv-rust-meetup/">Mountain View Rust Meetup</a><ul>
<li><a href="https://www.meetup.com/mv-rust-meetup/events/299043793/"><strong>Rust Meetup at Hacker Dojo</strong></a></li>
</ul>
</li>
</ul>
<h5><a class="toclink" href="http://this-week-in-rust.org/atom.xml#oceania">Oceania</a></h5>
<ul>
<li>2024-02-27 | Canberra, ACT, AU | <a href="https://www.meetup.com/rust-canberra/">Canberra Rust User Group</a><ul>
<li><a href="https://www.meetup.com/rust-canberra/events/297650401/"><strong>February Meetup</strong></a></li>
</ul>
</li>
<li>2024-02-27 | Sydney, NSW, AU | <a href="https://www.meetup.com/rust-sydney/">Rust Sydney</a><ul>
<li><a href="https://www.meetup.com/rust-sydney/events/298892952/"><strong>🦀 spire ⚡ & Quick</strong></a></li>
</ul>
</li>
<li>2024-02-29 | Brisbane, QLD, AU | <a href="https://www.meetup.com/rust-brisbane/">Rust Brisbane</a><ul>
<li><a href="https://www.meetup.com/rust-brisbane/events/299304438/"><strong>February Meetup</strong></a></li>
</ul>
</li>
<li>2024-03-05 | Auckland, NZ | <a href="https://www.meetup.com/rust-akl/">Rust AKL</a><ul>
<li><a href="https://www.meetup.com/rust-akl/events/299158887/"><strong>Rust AKL: Introduction to Embedded Rust + The State of Rust UI</strong></a></li>
</ul>
</li>
</ul>
<p>If you are running a Rust event please add it to the <a href="https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.com">calendar</a> to get
it mentioned here. Please remember to add a link to the event too.
Email the <a href="mailto:community-team@rust-lang.org">Rust Community Team</a> for access.</p>
<h4><a class="toclink" href="http://this-week-in-rust.org/atom.xml#jobs">Jobs</a></h4>
<p>Please see the latest <a href="https://www.reddit.com/r/rust/comments/1arr8xi/official_rrust_whos_hiring_thread_for_jobseekers">Who's Hiring thread on r/rust</a></p>
<h3><a class="toclink" href="http://this-week-in-rust.org/atom.xml#quote-of-the-week">Quote of the Week</a></h3>
<blockquote>
<p>Shared mutable state is evil, and you can solve it by forbidding mutation, or by forbidding sharing. Rust supports both.</p>
</blockquote>
<p>– <a href="https://lobste.rs/s/fud3fk/from_1s_4ms#c_relksr">kornel on Lobste.rs</a></p>
<p>Thanks to <a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328/1535">Aleksey Kladov</a> for the suggestion!</p>
<p><a href="https://users.rust-lang.org/t/twir-quote-of-the-week/328">Please submit quotes and vote for next week!</a></p>
<p><em>This Week in Rust is edited by: <a href="https://github.com/nellshamrell">nellshamrell</a>, <a href="https://github.com/llogiq">llogiq</a>, <a href="https://github.com/cdmistman">cdmistman</a>, <a href="https://github.com/ericseppanen">ericseppanen</a>, <a href="https://github.com/extrawurst">extrawurst</a>, <a href="https://github.com/andrewpollack">andrewpollack</a>, <a href="https://github.com/U007D">U007D</a>, <a href="https://github.com/kolharsam">kolharsam</a>, <a href="https://github.com/joelmarcey">joelmarcey</a>, <a href="https://github.com/mariannegoldin">mariannegoldin</a>, <a href="https://github.com/bennyvasquez">bennyvasquez</a>.</em></p>
<p><em>Email list hosting is sponsored by <a href="https://foundation.rust-lang.org/">The Rust Foundation</a></em></p>
<p><small><a href="https://www.reddit.com/r/rust/comments/1awuo07/this_week_in_rust_535/">Discuss on r/rust</a></small></p>2024-02-21T05:00:00+00:00TWiR ContributorsThe Rust Programming Language Blog: Rust participates in Google Summer of Code 2024
https://blog.rust-lang.org/2024/02/21/Rust-participates-in-GSoC-2024.html
<p>We're writing this blog post to announce that the Rust Project will be participating in <a href="https://summerofcode.withgoogle.com">Google Summer of Code (GSoC) 2024</a>. If you're not eligible or interested in participating in GSoC, then most of this post likely isn't relevant to you; if you are, this should contain some useful information and links.</p>
<p>Google Summer of Code (GSoC) is an annual global program organized by Google that aims to bring new contributors to the world of open-source. The program pairs organizations (such as the Rust Project) with contributors (usually students), with the goal of helping the participants make meaningful open-source contributions under the guidance of experienced mentors.</p>
<p>As of today, the organizations that have been accepted into the program have been announced by Google. The GSoC applicants now have several weeks to send project proposals to organizations that appeal to them. If their project proposal is accepted, they will embark on a 12-week journey during which they will try to complete their proposed project under the guidance of an assigned mentor.</p>
<p>We have prepared a <a href="https://github.com/rust-lang/google-summer-of-code">list of project ideas</a> that can serve as inspiration for potential GSoC contributors that would like to send a project proposal to the Rust organization. However, applicants can also come up with their own project ideas. You can discuss project ideas or try to find mentors in the <a href="https://rust-lang.zulipchat.com/#narrow/stream/421156-gsoc">#gsoc</a> Zulip stream. We have also prepared a <a href="https://github.com/rust-lang/google-summer-of-code/blob/main/proposal-guide.md">proposal guide</a> that should help you with preparing your project proposals.</p>
<p>You can start discussing the project ideas with Rust Project maintainers immediately. The project proposal application period starts on March 18, 2024, and ends on April 2, 2024 at 18:00 UTC. Take note of that deadline, as there will be no extensions!</p>
<p>If you are interested in contributing to the Rust Project, we encourage you to check out our project idea list and send us a GSoC project proposal! Of course, you are also free to discuss these projects and/or try to move them forward even if you do not intend to (or cannot) participate in GSoC. We welcome all contributors to Rust, as there is always enough work to do.</p>
<p>This is the first time that the Rust Project is participating in GSoC, so we are quite excited about it. We hope that participants in the program can improve their skills, but also would love for this to bring new contributors to the Project and increase the awareness of Rust in general. We will publish another blog post later this year with more information about our participation in the program.</p>2024-02-21T00:00:00+00:00Jakub Beránek, Jack Huey and Paul LenzMozilla Performance Blog: Web Performance @ FOSDEM 2024
https://blog.mozilla.org/performance/2024/02/20/web-performance-fosdem-2024/
<p><a href="https://fosdem.org/">FOSDEM</a> (Free and Open Source Software Developers’ European Meeting) is one of the largest gatherings of open-source enthusiasts, developers, and advocates worldwide. Each year there are many focused developer rooms (devrooms), managed by volunteers, and <a href="https://fosdem.org/2024/">this year’s edition on 3-4 February</a> saw the return of the Web Performance devroom managed by Peter Hedenskog from Wikimedia and myself (Dave Hunt) from Mozilla. Thanks to so many great talk proposals (we easily could have filled a full day), we were able to assemble a <a href="https://fosdem.org/2024/schedule/track/web-performance/">fantastic schedule</a>, and at times the room was full, with as many people standing outside hoping to get in!</p>
<h3>Dive into the talks</h3>
<p>Thanks to the FOSDEM organisers and preparation from our speakers, we successfully managed to squeeze nine talks into the morning with a tight turnaround time. Here’s a rundown of the sessions:</p>
<h4><b>1. The importance of Web Performance to Information Equity</b><b><br />
</b></h4>
<p><a href="https://fosdem.org/2024/schedule/speaker/LNXBGL/">Bas Schouten</a> kicked off the morning with <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2411-the-importance-of-web-performance-to-information-equity/">his informative talk</a> on the vital role web performance plays on ensuring equal access to information and services for those with slower devices.</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>2. Let’s build a RUM system with open source tools</h4>
<p>Next up we had <a href="https://fosdem.org/2024/schedule/speaker/8K8PMA/">Tsvetan Stoychev</a> share <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2088-let-s-build-a-rum-system-with-open-source-tools/">what he’s learned working on Basic RUM</a> – an open source real user monitoring system.</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>3. Better than loading fast… is loading instantly!</h4>
<p>At this point the room was at capacity, with at least as many people waiting outside! Next, <a href="https://fosdem.org/2024/schedule/speaker/JKX97Y/">Barry Pollard</a> gave shared details on how to score near-perfect Core Web Vitals in <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2003-better-than-loading-fast-is-loading-instantly-/">his talk</a> on pre-fetching and pre-rendering.</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>4. Keyboard Interactions</h4>
<p><a href="https://fosdem.org/2024/schedule/speaker/M7MMES/">Patricija Cerkaite</a> followed with <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2410-keyboard-interactions/">her talk</a> on how she helped to improve measuring keyboard interactions, and how this influenced Interaction to Next Paint, leading to a better experience for Input Method Editors (IME).</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>5. Web Performance at Mozilla and Wikimedia</h4>
<p>Midway through the morning, <a href="https://fosdem.org/2024/schedule/speaker/MHTMV8/">Peter Hedenskog</a> & <a href="https://fosdem.org/2024/schedule/speaker/EQJBEL/">myself</a> shared some insights into how Wikimedia and Mozilla measure performance in <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2162-web-performance-at-mozilla-and-wikimedia/">our talk</a>. Peter shared a some public dashboards, and I ran through a recent example of a performance regression affecting our page load tests.</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>6. Understanding how the web browser works, or tracing your way out of (performance) problems</h4>
<p>We handed the spotlight over to <a href="https://fosdem.org/2024/schedule/speaker/83PCTB/">Alexander Timin</a> for <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2777-understanding-how-the-web-browser-works-or-tracing-your-way-out-of-performance-problems/">his talk</a> on event tracing and browser engineering based on his experience working on the Chromium project.</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>7. Fast JavaScript with Data-Oriented Design</h4>
<p>The morning continued to go from strength to strength, with <a href="https://fosdem.org/2024/schedule/speaker/VX99AK/">Markus Stange</a> demonstrating <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2773-fast-javascript-with-data-oriented-design/">in his talk</a> how to iterate and optimise a small example project and showing how easy it is to use the Firefox Profiler.</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>8. From Google AdSense to FOSS: Lightning-fast privacy-friendly banners</h4>
<p>As we got closer to lunch, <a href="https://fosdem.org/2024/schedule/speaker/BFUW9W/">Tim Vereecke</a> teased us with hamburger banner ads <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2266-from-google-adsense-to-foss-lightning-fast-privacy-friendly-banners/">in his talk</a> on replacing Google AdSense with open source alternative Revive Adserver to address privacy and performance concerns.</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>9. Insights from the RUM Archive</h4>
<p>For our <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-1975-insights-from-the-rum-archive/">final session</a> of the morning, <a href="https://fosdem.org/2024/schedule/speaker/ME8QJ7/">Robin Marx</a> introduced us to the RUM Archive, shared some insights and challenges with the data, and discussed the part real user monitoring plays alongside other performance analysis.</p>
<p style="text-align: left;"><span class="mce_SELRES_start" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;"></span></p>
<h4>Beyond the devroom</h4>
<p>It was great to see that the topic of web performance wasn’t limited to our devroom, with talks such as <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-1873-debugging-http-3-upload-speed-in-firefox/">Debugging HTTP/3 upload speed in Firefox</a> in the <a href="https://fosdem.org/2024/schedule/track/mozilla/">Mozilla devroom</a>, <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-1713-web-performance-leveraging-qwik-to-meet-google-s-core-web-vitals/">Web Performance: Leveraging Qwik to Meet Google’s Core Web Vitals</a> in the <a href="https://fosdem.org/2024/schedule/track/javascript/">JavaScript devroom</a>, and <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2716-firefox-power-profiling-a-powerful-visualization-of-web-sustainability/">Firefox power profiling: a powerful visualization of web sustainability</a> in the main track.</p>
<h3>Acknowledgements</h3>
<p>I would like to thank all the amazing FOSDEM volunteers for supporting the event. Thank you to our wonderful speakers and everyone who submitted a proposal for providing us with such an excellent schedule. Thank you to Peter Hedenskog for bringing his devroom management experience to the organisation and facilitation of the devroom. Thank you to Andrej Glavic, Julien Wajsberg, and Nazım Can Altınova for their help managing the room and ensuring everything ran smoothly. See you next year!</p>2024-02-20T19:04:54+00:00Dave HuntFirefox Developer Experience: Firefox WebDriver Newsletter — 123
https://fxdx.dev/firefox-webdriver-newsletter-123/
<p><em>WebDriver is a remote control interface that enables introspection and control of user agents. As such it can</em> <em>help developers to verify that their websites are working and performing well with all major browsers. The protocol is standardized by the <a href="https://www.w3.org/">W3C</a> and consists of two separate specifications: <a href="https://w3c.github.io/webdriver/">WebDriver classic</a> (HTTP) and the new <a href="https://w3c.github.io/webdriver-bidi/">WebDriver BiDi </a>(Bi-Directional).</em></p>
<p id="block-657c8643-6b93-4546-8626-3d7c3976c217"><em>This newsletter gives an overview of the work we’ve done as part of the Firefox 123 release cycle</em>.</p>
<h3>Contributions</h3>
<p id="block-9278fa20-63dc-4975-a72b-e3ba73b202a4">With Firefox being an open source project, we are grateful to get contributions from people outside of Mozilla.</p>
<p id="block-f6e2b9b0-63b6-4a4b-aeea-cffbde1019dd">WebDriver code is written in JavaScript, Python, and Rust so any web developer can contribute! Read <a href="https://firefox-source-docs.mozilla.org/devtools/getting-started/README.html">how to setup the work environment</a> and check <a href="https://codetribute.mozilla.org/projects/automation">the list of mentored issues</a> for Marionette.</p>
<h3>WebDriver BiDi</h3>
<h4>New: Support for the “browsingContext.locateNodes” command</h4>
<p>Support for the <code>browsingContext.locateNodes</code> command has been introduced to find elements on the given page. Supported locators for now are <a href="https://bugzil.la/1855023"><code>CssLocator</code></a> and <a href="https://bugzil.la/1869536"><code>XPathLocator</code></a>. Additional support for locating elements by <code>InnerTextLocator</code> will be added in a later version.</p>
<p>This command encapsulates the logic for locating elements within a web page’s DOM, streamlining the process for users familiar with the <code>Find Element(s)</code> methods from WebDriver classic (HTTP). Alternatively, users can still utilize <code>script.evaluate</code>, although it necessitates knowledge of the appropriate JavaScript code for evaluation.</p>
<h4>New: Support for the “network.fetchError” event</h4>
<p>Added <a href="https://bugzil.la/1790375">support for the <code>network.fetchError</code> event</a> that is emitted when a network request ends in an error.</p>
<h4>Update for the “browsingContext.create” command</h4>
<p>The <a href="http://Firefox bug 1875086"><code>browsingContext.create</code> command has been improved on Android</a> to seamlessly switch to opening a new tab if the <code>type</code> argument is specified as <code>window</code>.</p>
<p>We implemented this change to simplify the creation of tests that need to run across various desktop platforms and Android. Consequently, specific adjustments for new top-level browsing contexts are no longer required, enhancing the test creation process.</p>
<h4>Bug Fixes</h4>
<ul>
<li>An <a href="https://bugzil.la/1872116">issue with the deserialization process of a <code>DateRemoteValue</code> was fixed</a>, where the presence of a non-standard (ISO 8601) date string such as <code>200009</code> did not trigger an error.</li>
<li>An <a href="https://bugzil.la/1873688">issue with the <code>script.evaluate</code>, <code>script.callFunction</code>, and <code>script.disown</code> commands was fixed</a> where specifying both the <code>context</code> and <code>realm</code> arguments would result in an <code>invalid argument</code> error, rather than simply ignoring the <code>realm</code> argument as intended.</li>
</ul>
<h3>Marionette (WebDriver classic)</h3>
<h4>Bug Fixes</h4>
<ul>
<li>An <a href="https://bugzil.la/1866431">issue with <code>Element Send Keys</code> was fixed</a> where sending text containing surrogate pairs would fail.</li>
</ul>2024-02-20T14:10:17+00:00Henrik SkupinThe Rust Programming Language Blog: 2023 Annual Rust Survey Results
https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html
<p>Hello, Rustaceans!</p>
<p>The Rust Survey Team is excited to share the results of our <a href="https://blog.rust-lang.org/2023/12/18/survey-launch.html">2023 survey on the Rust Programming language</a>, conducted between December 18, 2023 and January 15, 2024.
As in previous years, the 2023 State of Rust Survey was focused on gathering insights and feedback from Rust users, and all those who are interested in the future of Rust more generally.</p>
<p>This eighth edition of the survey surfaced new insights and learning opportunities straight from the global Rust language community, which we will summarize below. In addition to this blog post, this year we have also prepared a <a href="https://raw.githubusercontent.com/rust-lang/surveys/main/surveys/2023-annual-survey/report/annual-survey-2023-report.pdf">report</a> containing charts with aggregated results of all questions in the survey. Based on feedback from recent years, we have also tried to provide more comprehensive and interactive charts in this summary blog post. Let us know what you think!</p>
<p><strong>Our sincerest thanks to every community member who took the time to express their opinions and experiences with Rust over the past year. Your participation will help us make Rust better for everyone.</strong></p>
<p>There's a lot of data to go through, so strap in and enjoy!</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html#participation" id="participation"></a>Participation</h3>
<table>
<thead>
<tr>
<th align="center"><strong>Survey</strong></th>
<th align="right"><strong>Started</strong></th>
<th align="right"><strong>Completed</strong></th>
<th align="right"><strong>Completion rate</strong></th>
<th align="right"><strong>Views</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">2022</td>
<td align="right">11 482</td>
<td align="right">9 433</td>
<td align="right">81.3%</td>
<td align="right">25 581</td>
</tr>
<tr>
<td align="center">2023</td>
<td align="right">11 950</td>
<td align="right">9 710</td>
<td align="right">82.2%</td>
<td align="right">16 028</td>
</tr>
</tbody>
</table>
<p>As shown above, in 2023, we have received 37% fewer survey views in vs 2022, but saw a slight uptick in starts and completions. There are many reasons why this could have been the case, but it’s possible that because we released the <a href="https://blog.rust-lang.org/2023/08/07/Rust-Survey-2023-Results.html">2022 analysis blog</a> so late last year, the survey was fresh in many Rustaceans’ minds. This might have prompted fewer people to feel the need to open the most recent survey. Therefore, we find it doubly impressive that there were more starts and completions in 2023, despite the lower overall view count.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html#community" id="community"></a>Community</h3>
<p>This year, we have relied on automated translations of the survey, and we have asked volunteers to review them. We thank the hardworking volunteers who reviewed these automated survey translations, ultimately allowing us to offer the survey in seven languages: English, Simplified Chinese, French, German, Japanese, Russian, and Spanish. We decided not to publish the survey in languages without a translation review volunteer, meaning we could not issue the survey in Portuguese, Ukrainian, Traditional Chinese, or Korean.</p>
<p>The Rust Survey team understands that there were some issues with several of these translated versions, and we apologize for any difficulty this has caused. We are always looking for ways to improve going forward and are in the process of discussing improvements to this part of the survey creation process for next year.</p>
<p>We saw a 3pp increase in respondents taking this year’s survey in English – 80% in 2023 and 77% in 2022. Across all other languages, we saw only minor variations – all of which are likely due to us offering fewer languages overall this year due to having fewer volunteers.</p>
<p>Rust user respondents were asked which country they live in. The top 10 countries represented were, in order: United States (22%), Germany (12%), China (6%), United Kingdom (6%), France (6%), Canada (3%), Russia (3%), Netherlands (3%), Japan (3%), and Poland (3%) . We were interested to see a small reduction in participants taking the survey in the United States in 2023 (down 3pp from the 2022 edition) which is a positive indication of the growing global nature of our community! You can try to find your country in the chart below:</p>
<div>
<div class="pie-chart" id="where-do-you-live" style="height: 600px; width: 100%;"><noscript>
<img alt="where-do-you-live" height="600" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/where-do-you-live.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/where-do-you-live.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/where-do-you-live.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>Once again, the majority of our respondents reported being most comfortable communicating on technical topics in English at 92.7% — a slight difference from 93% in 2022. Again, Chinese was the second-highest choice for preferred language for technical communication at 6.1% (7% in 2022).</p>
<div>
<div class="bar-chart" id="what-are-your-preferred-languages-for-technical-communication" style="height: 400px; width: 100%;"><noscript>
<img alt="what-are-your-preferred-languages-for-technical-communication" height="400" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-are-your-preferred-languages-for-technical-communication.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-are-your-preferred-languages-for-technical-communication.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-are-your-preferred-languages-for-technical-communication.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>We also asked whether respondents consider themselves members of a marginalized community. Out of those who answered, 76% selected no, 14% selected yes, and 10% preferred not to say.</p>
<p>We have asked the group that selected “yes” which specific groups they identified as being a member of. The majority of those who consider themselves a member of an underrepresented or marginalized group in technology identify as lesbian, gay, bisexual, or otherwise non-heterosexual. The second most selected option was neurodivergent at 41% followed by trans at 31.4%. Going forward, it will be important for us to track these figures over time to learn how our community changes and to identify the gaps we need to fill.</p>
<div>
<div class="bar-chart" id="which-marginalized-group" style="height: 500px; width: 100%;"><noscript>
<img alt="which-marginalized-group" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-marginalized-group.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-marginalized-group.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-marginalized-group.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>As Rust continues to grow, we must acknowledge the diversity, equity, and inclusivity (DEI)-related gaps that exist in the Rust community. Sadly, Rust is not unique in this regard. For instance, only 20% of 2023 respondents to this representation question consider themselves a member of a racial or ethnic minority and only 26% identify as a woman. We would like to see more equitable figures in these and other categories. In 2023, the Rust Foundation formed a diversity, equity, and inclusion subcommittee on its Board of Directors whose members are aware of these results and are actively discussing ways that the Foundation might be able to better support underrepresented groups in Rust and help make our ecosystem more globally inclusive. One of the central goals of the Rust Foundation board's subcommittee is to analyze information about our community to find out what gaps exist, so this information is a helpful place to start. This topic deserves much more depth than is possible here, but readers can expect more on the subject in the future.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html#rust-usage" id="rust-usage"></a>Rust usage</h3>
<p>In 2023, we saw a slight jump in the number of respondents that self-identify as a Rust user, from 91% in 2022 to 93% in 2023.</p>
<div>
<div class="bar-chart" id="do-you-use-rust" style="height: 300px; width: 100%;"><noscript>
<img alt="do-you-use-rust" height="300" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/do-you-use-rust.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/do-you-use-rust.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/do-you-use-rust.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>Of those who used Rust in 2023, 49% did so on a daily (or nearly daily) basis — a small increase of 2pp from the previous year.</p>
<div>
<div class="bar-chart" id="how-often-do-you-use-rust" style="height: 300px; width: 100%;"><noscript>
<img alt="how-often-do-you-use-rust" height="300" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-often-do-you-use-rust.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-often-do-you-use-rust.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-often-do-you-use-rust.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>31% of those who did not identify as Rust users cited the perception of difficulty as the primary reason for not having used it, with 67% reporting that they simply haven’t had the chance to prioritize learning Rust yet, which was once again the most common reason.</p>
<div>
<div class="bar-chart" id="why-dont-you-use-rust" style="height: 500px; width: 100%;"><noscript>
<img alt="why-dont-you-use-rust" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-dont-you-use-rust.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-dont-you-use-rust.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-dont-you-use-rust.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-dont-you-use-rust-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<p>Of the former Rust users who participated in the 2023 survey, 46% cited factors outside their control (a decrease of 1pp from 2022), 31% stopped using Rust due to preferring another language (an increase of 9pp from 2022), and 24% cited difficulty as the primary reason for giving up (a decrease of 6pp from 2022).</p>
<div>
<div class="bar-chart" id="why-did-you-stop-using-rust" style="height: 500px; width: 100%;"><noscript>
<img alt="why-did-you-stop-using-rust" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-did-you-stop-using-rust.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-did-you-stop-using-rust.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-did-you-stop-using-rust.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-did-you-stop-using-rust-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<p>Rust expertise has generally increased amongst our respondents over the past year! 23% can write (only) simple programs in Rust (a decrease of 6pp from 2022), 28% can write production-ready code (an increase of 1pp), and 47% consider themselves productive using Rust — up from 42% in 2022. While the survey is just one tool to measure the changes in Rust expertise overall, these numbers are heartening as they represent knowledge growth for many Rustaceans returning to the survey year over year.</p>
<div>
<div class="bar-chart" id="how-would-you-rate-your-rust-expertise" style="height: 500px; width: 100%;"><noscript>
<img alt="how-would-you-rate-your-rust-expertise" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-would-you-rate-your-rust-expertise.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-would-you-rate-your-rust-expertise.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-would-you-rate-your-rust-expertise.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>In terms of operating systems used by Rustaceans, the situation is very similar to the results from 2022, with Linux being the most popular choice of Rust users, followed by macOS and Windows, which have a very similar share of usage.</p>
<div>
<div class="bar-chart" id="which-os-do-you-use" style="height: 400px; width: 100%;"><noscript>
<img alt="which-os-do-you-use" height="400" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-os-do-you-use.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-os-do-you-use.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-os-do-you-use.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-os-do-you-use-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<p>Rust programmers target a diverse set of platforms with their Rust programs, even though the most popular target by far is still a Linux machine. We can see a slight uptick in users targeting WebAssembly, embedded and mobile platforms, which speaks to the versatility of Rust.</p>
<div>
<div class="bar-chart" id="which-os-do-you-target" style="height: 500px; width: 100%;"><noscript>
<img alt="which-os-do-you-target" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-os-do-you-target.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-os-do-you-target.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-os-do-you-target.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-os-do-you-target-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<p>We cannot of course forget the favourite topic of many programmers: which IDE (developer environment) do they use. Visual Studio Code still seems to be the most popular option, with RustRover (which was released last year) also gaining some traction.</p>
<div>
<div class="bar-chart" id="what-ide-do-you-use" style="height: 500px; width: 100%;"><noscript>
<img alt="what-ide-do-you-use" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-ide-do-you-use.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-ide-do-you-use.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-ide-do-you-use.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-ide-do-you-use-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<blockquote>
<p>You can also take a look at the linked <a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-ide-do-you-use-wordcloud.png">wordcloud</a> that summarizes open answers to this question (the "Other" category), to see what other editors are also popular.</p>
</blockquote>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html#rust-at-work" id="rust-at-work"></a>Rust at Work</h3>
<p>We were excited to see a continued upward year-over-year trend of Rust usage at work. 34% of 2023 survey respondents use Rust in the majority of their coding at work — an increase of 5pp from 2022. Of this group, 39% work for organizations that make non-trivial use of Rust.</p>
<div>
<div class="bar-chart" id="do-you-personally-use-rust-at-work" style="height: 500px; width: 100%;"><noscript>
<img alt="do-you-personally-use-rust-at-work" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/do-you-personally-use-rust-at-work.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/do-you-personally-use-rust-at-work.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/do-you-personally-use-rust-at-work.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>Once again, the top reason employers of our survey respondents invested in Rust was the ability to build relatively correct and bug-free software at 86% — a 4pp increase from 2022 responses. The second most popular reason was Rust’s performance characteristics at 83%.</p>
<div>
<div class="bar-chart" id="why-you-use-rust-at-work" style="height: 500px; width: 100%;"><noscript>
<img alt="why-you-use-rust-at-work" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-you-use-rust-at-work.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-you-use-rust-at-work.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/why-you-use-rust-at-work.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>We were also pleased to see an increase in the number of people who reported that Rust helped their company achieve its goals at 79% — an increase of 7pp from 2022. 77% of respondents reported that their organization is likely to use Rust again in the future — an increase of 3pp from the previous year. Interestingly, we saw a decrease in the number of people who reported that using Rust has been challenging for their organization to use: 34% in 2023 and 39% in 2022. We also saw an increase of respondents reporting that Rust has been worth the cost of adoption: 64% in 2023 and 60% in 2022.</p>
<div>
<div class="bar-chart" id="which-statements-apply-to-rust-at-work" style="height: 500px; width: 100%;"><noscript>
<img alt="which-statements-apply-to-rust-at-work" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-statements-apply-to-rust-at-work.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-statements-apply-to-rust-at-work.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-statements-apply-to-rust-at-work.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>There are many factors playing into this, but the growing awareness around Rust has likely resulted in the proliferation of resources, allowing new teams using Rust to be better supported.</p>
<p>In terms of technology domains, it seems that Rust is especially popular for creating server backends, web and networking services and cloud technologies.</p>
<div>
<div class="bar-chart" id="technology-domain" style="height: 600px; width: 100%;"><noscript>
<img alt="technology-domain" height="600" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/technology-domain.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/technology-domain.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/technology-domain.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/technology-domain-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<blockquote>
<p>You can scroll the chart to the right to see more domains. Note that the Database implementation and Computer Games domains were not offered as closed answers in the 2022 survey (they were merely submitted as open answers), which explains the large jump.</p>
</blockquote>
<p>It is exciting to see the continued growth of professional Rust usage and the confidence so many users feel in its performance, control, security and safety, enjoyability, and more!</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html#challenges" id="challenges"></a>Challenges</h3>
<p>As always, one of the main goals of the State of Rust survey is to shed light on challenges, concerns, and priorities on Rustaceans’ minds over the past year.</p>
<p>Of those respondents who shared their main worries for the future of Rust (9,374), the majority were concerned about Rust becoming too complex at 43% — a 5pp increase from 2022. 42% of respondents were concerned about a low level of Rust usage in the tech industry. 32% of respondents in 2023 were most concerned about Rust developers and maintainers not being properly supported — a 6pp increase from 2022.</p>
<p>We saw a notable decrease in respondents who were not at all concerned about the future of Rust, 18% in 2023 and 30% in 2022.</p>
<p>Thank you to all participants for your candid feedback which will go a long way toward improving Rust for everyone.</p>
<div>
<div class="bar-chart" id="what-are-your-biggest-worries-about-rust" style="height: 500px; width: 100%;"><noscript>
<img alt="what-are-your-biggest-worries-about-rust" height="500" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-are-your-biggest-worries-about-rust.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-are-your-biggest-worries-about-rust.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-are-your-biggest-worries-about-rust.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/what-are-your-biggest-worries-about-rust-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<blockquote>
<p>Closed answers marked with N/A were not present in the previous (2022) version of the survey.</p>
</blockquote>
<p>In terms of features that Rust users want to be implemented, stabilized or improved, the most desired improvements are in the areas of traits (trait aliases, associated type defaults, etc.), const execution (generic const expressions, const trait methods, etc.) and async (async closures, coroutines).</p>
<div>
<div class="matrix-chart" id="which-features-do-you-want-stabilized" style="height: 600px; width: 100%;"><noscript>
<img alt="which-features-do-you-want-stabilized" height="600" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-features-do-you-want-stabilized.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-features-do-you-want-stabilized.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-features-do-you-want-stabilized.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-features-do-you-want-stabilized-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<p>It is interesting that 20% of respondents answered that they wish Rust to slow down the development of new features, which likely goes hand in hand with the previously mentioned worry that Rust becomes too complex.</p>
<p>The areas of Rust that Rustaceans seem to struggle with the most seem to be asynchronous Rust, the traits and generics system and also the borrow checker.</p>
<div>
<div class="bar-chart" id="which-problems-do-you-remember-encountering" style="height: 400px; width: 100%;"><noscript>
<img alt="which-problems-do-you-remember-encountering" height="400" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-problems-do-you-remember-encountering.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-problems-do-you-remember-encountering.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-problems-do-you-remember-encountering.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/which-problems-do-you-remember-encountering-wordcloud.png" target="_href_" title="Download open answers as wordcloud PNG">Wordcloud of open answers</a>]</span>
</div>
</div>
<p>Respondents of the survey want the Rust maintainers to mainly prioritize fixing compiler bugs (68%), improving the runtime performance of Rust programs (57%) and also improving compile times (45%).</p>
<div>
<div class="matrix-chart" id="how-should-work-be-prioritized" style="height: 800px; width: 100%;"><noscript>
<img alt="how-should-work-be-prioritized" height="800" src="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-should-work-be-prioritized.png" />
</noscript></div>
<div style="display: flex; margin-bottom: 10px;">
<span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-should-work-be-prioritized.png" target="_href_" title="Download chart as PNG">PNG</a>]</span> <span>[<a href="https://blog.rust-lang.org/images/2024-02-rust-survey-2023/how-should-work-be-prioritized.svg" target="_href_" title="Download chart as SVG">SVG</a>]</span>
</div>
</div>
<p>Same as in recent years, respondents noted that compilation time is one of the most important areas that should be improved. However, it is interesting to note that respondents also seem to consider runtime performance to be more important than compile times.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html#looking-ahead" id="looking-ahead"></a>Looking ahead</h3>
<p>Each year, the results of the State of Rust survey help reveal the areas that need improvement in many areas across the Rust Project and ecosystem, as well as the aspects that are working well for our community.</p>
<p>We are aware that the survey has contained some confusing questions, and we will try to improve upon that in the next year's survey.
If you have any suggestions for the Rust Annual survey, please <a href="https://github.com/rust-lang/surveys/issues">let us know</a>!</p>
<p>We are immensely grateful to those who participated in the 2023 State of Rust Survey and facilitated its creation. While there are always challenges associated with developing and maintaining a programming language, this year we were pleased to see a high level of survey participation and candid feedback that will truly help us make Rust work better for everyone.</p>
<p>If you’d like to dig into more details, we recommend you to browse through the full <a href="https://raw.githubusercontent.com/rust-lang/surveys/main/surveys/2023-annual-survey/report/annual-survey-2023-report.pdf">survey report</a>.</p>2024-02-19T00:00:00+00:00The Rust Survey TeamAnne van Kesteren: WebKit and web-platform-tests
https://annevankesteren.nl/2023/05/webkit-wpt
<p>Let me state upfront that this strategy of keeping WebKit synchronized with parts of web-platform-tests has worked quite well for me, but I’m not at all an expert in this area so you might want to take advice from someone else.</p>
<p>Once I've identified what tests will be impacted by my changes to WebKit, including what additional coverage might be needed, I create a branch in my local web-platform-tests checkout to make the necessary changes to increase coverage. I try to be a little careful here so it'll result in a nice pull request against web-platform-tests later. I’ve been a web-platform-tests contributor quite a while longer than I’ve been a WebKit contributor so perhaps it’s not surprising that my approach to test development starts with web-platform-tests.</p>
<p>I then run <code>import-w3c-tests web-platform-tests/[testsDir] -s [wptParentDir] --clean-dest-dir</code> on the WebKit side to ensure it has the latest tests, including any changes I made. And then I usually run them and revise, as needed.</p>
<p>This has worked surprisingly well for a number of changes I made to date and hasn’t let me down. Two things to be mindful of:</p>
<ul>
<li>On macOS, don’t put development work, especially WebKit, inside <code>~/Documents</code>. You might not have a good time.</li>
<li><code>[wptParentDir]</code> above needs to contain a directory named <code>web-platform-tests</code>, not <code>wpt</code>. This is annoyingly different from the default you get when cloning web-platform-tests (the repository was renamed to wpt at some point). Perhaps something to address in <code>import-w3c-tests</code>.</li>
</ul>2024-02-16T13:20:06+00:00Firefox Nightly: Monitor, Plus More Improvements – These Weeks in Firefox: Issue 154
https://blog.nightly.mozilla.org/2024/02/15/monitor-plus-more-improvements-these-weeks-in-firefox-issue-154/
<h3>Highlights</h3>
<ul>
<li><a href="https://blog.mozilla.org/en/mozilla/introducing-mozilla-monitor-plus-a-new-tool-to-automatically-remove-your-personal-information-from-data-broker-sites/">Mozilla Monitor Plus has been launched</a>! This is a new subscription product (available only in the US for now) that will search for and scrub your personal information from data brokers.
<ul>
<li>
<p></p><div class="wp-caption aligncenter" id="attachment_1556" style="width: 1549px;"><a href="https://blog.nightly.mozilla.org/files/2024/02/image4.png"><img alt="A screenshot of the Mozilla Monitor Plus dashboard for US customers. The dashboard shows that 16 exposures of user data have been manually fixed, and that 240 are in progress. At the bottom, a list of data brokers are listed for which data scrubbing is in progress. Those data brokers are "arivify.com" and "beenverified.com", and the user data is listed as being for sale." class="size-full wp-image-1556" height="786" src="https://blog.nightly.mozilla.org/files/2024/02/image4.png" width="1539" /></a><p class="wp-caption-text" id="caption-attachment-1556">Mozilla Monitor Plus lets you take back control over your personal information.</p></div></li>
</ul>
</li>
<li>The new clear history dialog has been enabled by default at Nightly! The dialog now has a more modern look, consolidated clearing options, and shows the amount of data you clear based on time range. Additionally, all the entry points for clearing data have been unified to point to the same dialog. Congratulations to :harshitsohaney for getting the new dialog to this point!
<ul>
<li>
<p></p><div class="wp-caption aligncenter" id="attachment_1557" style="width: 1314px;"><a href="https://blog.nightly.mozilla.org/files/2024/02/image5.png"><img alt="The new "Clear browsing data and cookies" dialog is shown. A dropdown for when to remove data for has "Last hour" selected. There are 4 checkboxes shown with the following labels: "History", "Cookies and site data (23.5 MB)", "Temporary cached files and pages (464 MB)", "Site settings". The first three are checked." class="size-full wp-image-1557" height="908" src="https://blog.nightly.mozilla.org/files/2024/02/image5.png" width="1304" /></a><p class="wp-caption-text" id="caption-attachment-1557">Much cleaner than before!</p></div></li>
</ul>
</li>
<li>Nicolas added support for <a href="https://developer.mozilla.org/en-US/docs/Web/API/CSS_Properties_and_Values_API/guide">registered properties</a> (@property/CSS.registerProperty) in the DevTools Rules view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1841023">bug</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876455">bug</a>). The registered properties are displayed in var() autocomplete (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867589">bug</a>), as well as in property name autocomplete too (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867595">bug</a>)
<ul>
<li>Check it out by setting the pref layout.css.properties-and-values.enabled to true</li>
<li><a href="https://blog.nightly.mozilla.org/files/2024/02/image2.png"><img alt="4 different sections of the Firefox DevTools are shown. All are demonstrating that custom CSS properties are more easily inspected. The top-left quadrant shows the property being inspected in the Style pane of the Inspector. The bottom-left quadrant shows an animated custom property listed in the CSS animation inspector. The top-right quadrant shows the CSS property in the Style pane of the Inspector being offered in an autofill tooltip, and showing what the CSS value resolves to (the colour "gold"). The bottom most pane shows the rule being included in the autofill tooltip when setting a style property in a selector." class="aligncenter size-full wp-image-1554" height="1384" src="https://blog.nightly.mozilla.org/files/2024/02/image2.png" width="1806" /></a></li>
</ul>
</li>
<li>In Firefox 124 a new runtime.onPerformanceWarning API event has been introduced (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1861445">Bug 1861445</a>) for WebExtensions. This event will be emitted when Firefox detects that a content script is impacting a web page responsiveness. It is meant to allow WebExtension developers to detect when their content scripts are slowing down pages.
<ul>
<li>This new API has been previously proposed through the W3C WebExtensions Community Group and tracked by <a href="https://github.com/w3c/webextensions/issues/456">this ticket</a>.</li>
<li>Thanks to Dave Vandyke for contributing this new WebExtensions API!</li>
</ul>
</li>
</ul>
<h3>Friends of the Firefox team</h3>
<h4>Introductions/Shout-Outs</h4>
<ul>
<li>Welcome to Nathan Barrett (:nbarrett), who is joining the New Tab team!</li>
</ul>
<h4><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20%28excluding%20employees%29&quicksearch=1869574%2C1806255%2C1864447%2C1837747%2C1842804%2C1872922%2C1724089%2C328707%2C1863223%2C1869830%2C1633456%2C1876496%2C1861445%2C1845797%2C1876934%2C1708289%2C1877890%2C1874952&list_id=16889010">Resolved bugs (excluding employees)</a></h4>
<p><a href="https://github.com/niklasbaumgardner/NewContributorScraper">Script to find new contributors from bug list</a></p>
<h4>Volunteers that fixed more than one bug</h4>
<ul>
<li>Gregory Pappas [:gregp]</li>
<li>Itiel</li>
</ul>
<h4>New contributors (🌟 = first patch)</h4>
<ul>
<li>🌟 Oliver Schramm <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877890">updated geometry editor</a> to consider zoom</li>
<li>Jing Zhu <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1633456">removed the `TelemetryStorage.addPendingPing`</a> method</li>
<li>Richard Cole <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1845797">removed reload-default-prefs observer notification</a></li>
<li>🌟 Jaydeep Das fixed Proxy Config to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=328707">only allow valid IP/Hostname</a></li>
</ul>
<h3>Project Updates</h3>
<h4>Accessibility</h4>
<ul>
<li>Ongoing High Contrast Mode Project – We’re reevaluating all occurrences of @media (prefers-contrast) to make sure they’re targeting BOTH Windows HCM and macOS Increase Contrast. If the code within the query is only for Windows (as often is the case 😁) the query should be switched to @media (forced-colors).</li>
<li>New revisions that use these queries will be blocked for review by the HCM-reviewers review group in phabricator.</li>
<li>You can read more about using these queries in our <a href="https://firefox-source-docs.mozilla.org/accessible/HCMMediaQueries.html">new documentation</a>, and play around with this <a href="https://mreschenberg.com/MediaQueryChecker.html">live site</a> Morgan made. If you have any questions, please reach out to Morgan or Anna 🙂 Thanks!</li>
</ul>
<h4>Add-ons / Web Extensions</h4>
<h5>Addon Manager & about:addons</h5>
<ul>
<li>Thanks to :arai for having converted the last 3 jsm files from the XPIProvider internals to ES modules – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1836480">Bug 1836480</a>.
<ul>
<li>WebExtensions and AOM/XPIProvider internals are now 100% migrated away from legacy jsm files! 🎉</li>
</ul>
</li>
<li>Thanks to :masayuki for fixing a bug related to keyboard shortcuts using non-english keyboard layouts (fixed as part of <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874727">Bug 1874727</a> and tracked for WebExtensions keyboard shortcuts in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1782660">Bug 1782660</a>).</li>
</ul>
<h4>Developer Tools</h4>
<h5>DevTools</h5>
<ul>
<li>Oliver Schramm reported <i>and</i> fixed the geometry editor when the page is zoomed in (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877890">bug</a>)</li>
<li>Nicolas added a preference to control the behavior of the Enter key when editing properties in the Rules view (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876694">bug</a>), and reverted the behavior to what we had in Firefox 121 (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877457">bug</a>, <a href="https://fxdx.dev/rules-view-enter-key/#2024-02-03-update">blog post update</a>)</li>
<li>Alex made the console up to 70% faster (<a href="https://treeherder.mozilla.org/perfherder/alerts?id=41236">perf alert</a>) when it reaches the limit of messages we show (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875045">bug</a>)</li>
<li>Alex improved the tracer, by allowing it to trace on next reload or navigation (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1848159">bug</a>)
<ul>
<li>This relies on a new option in the context menu:
<ul>
<li><a href="https://blog.nightly.mozilla.org/files/2024/02/image1.png"><img alt="A menu popup for the Tracer tool in the Firefox DevTools. A new item has been added with a checkbox next to it: "Trace only on next page load (reload or navigation)"." class="aligncenter size-full wp-image-1553" height="270" src="https://blog.nightly.mozilla.org/files/2024/02/image1.png" width="599" /></a></li>
</ul>
</li>
</ul>
</li>
<li>Nicolas fixed an issue where ServiceWorker file where not displayed in the debugger when using an URL with a port (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876533">bug</a>)
<ul>
<li>If you’re working with Service Worker, please flip devtools.debugger.features.windowless-service-workers so you can debug them directly in the page tab toolbox (not via about:debugging). We’re looking for feedback on this before we enable it by default</li>
</ul>
</li>
<li>Bomsy made the debugger no longer use Babel to detect if watch expressions have syntax errors (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878061">bug</a>). This is part of a bigger project where we’re trying to completely remove Babel, which can be pretty slow on very large files</li>
<li>Alex fixed a bug in the Debugger where watch expressions and variable tooltip could show wrong values (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876297">bug</a>)</li>
</ul>
<h5>WebDrive BiDi</h5>
<ul>
<li>Contributors
<ul>
<li>James Hendry updated the “WebDriver:SwitchToFrame” command to make the “id” parameter mandatory and raise an exception if it is missing (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1847875">bug</a>)</li>
</ul>
</li>
<li>Sasha added support for the contexts attribute to the script.addPreloadScript command (BiDi), which allows to assign a preload script to specific browsing contexts (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1858458">bug</a>)</li>
<li>Henrik fixed the “WebDriver:NewWindow” command to always fallback to opening new tabs on Android, even if a new “window” was requested (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875085">bug</a>)</li>
<li>Henrik updated our vendored Puppeteer version to v21.10.0, which comes with updated tests and support for BiDi features. The ./mach puppeteer-test command was also updated to run in headful mode by default (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877214">bug</a>)</li>
<li>Henrik improved browsingContext.close to allow closing the last tab of a window (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873948">bug</a>)</li>
<li>Julian implemented several commands to handle user contexts (containers) in WebDriver BiDi;
<ul>
<li>browser.createUserContext allows to create a new user context (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870848">bug</a>)</li>
<li>browser.getUserContexts allows to list all the available user contexts (including the default one and contexts created outside of WebDriver BiDi) (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870847">bug</a>)</li>
<li>browser.removeUserContexts allows to remove a user context and close all the related tabs (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870849">bug</a>)</li>
</ul>
</li>
<li>Julian added partial support for two network interception commands, network.continueRequest and network.continueResponse. At the moment they only allow to resume an intercepted request, but additional parameters will later allow to modify the request/response (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874206">bug</a>)</li>
</ul>
<h4>ESMification status</h4>
<ul>
<li>Aria transitioned <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1836480">extensions related modules</a> and found some more modules under <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878457">devtools’ performance-new</a> to transition.</li>
<li>See also the New Tab Page update below.</li>
<li>ESMified status:
<ul>
<li>browser: 96.43%</li>
<li>toolkit: 99.83%</li>
<li>Total: 98.48% (+2% from last week)</li>
</ul>
</li>
<li>#esmification on Matrix</li>
</ul>
<h4>Lint, Docs and Workflow</h4>
<ul>
<li>Removed <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877676">.ini file support from ESLint</a>, now that the transition to .toml is largely complete.</li>
<li>Removed <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878009">Babel integration from ESLint</a>.
<ul>
<li>This helps to speed up ESLint.</li>
<li>Originally integrated due to wanting to use JavaScript features that were at stage 3, whereas ESLint only supports them at stage 4.</li>
<li>We can/will reintroduce the integration later if need be, but for now let’s enjoy the slightly faster linting.</li>
</ul>
</li>
</ul>
<h4>Migration Improvements</h4>
<ul>
<li>Welcome to fchasen and kpatenio, who are going to be joining us on making device migration smoother for our users!</li>
<li>The team has been mostly prototyping, consulting and building up their expertise on the various data stored in user profile directories, and how it can be safely copied during runtime.</li>
</ul>
<h4>New Tab Page</h4>
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877196">The rest of the ASRouter code</a> has been moved out from New Tab, and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876104">the remaining JSMs were all converted to ESMs</a>.</li>
</ul>
<h4>Performance</h4>
<ul>
<li>The <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877174">new off-main-thread Windows Jump List backend is being tested by QA on Nightly right now</a>. So far, no major issues have been found. If all goes well, we’re aiming to let this ride the trains. This should help reduce jank – especially when the user is running with an HDD or the disk is under load.</li>
</ul>
<h4>Screenshots</h4>
<ul>
<li>HCM mode improvements <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874380">bug 1874380</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874671">bug 1874671</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874663">bug 1874663</a></li>
<li>Niklas fixed a rounding issue that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875034">caused screenshots to be blurry</a> when an image location was at a half pixel</li>
<li>Niklas update the screenshots flow so cancel/escape from the overlay will now go <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873882">back to the initial state</a> instead of exiting</li>
<li>Niklas added a feature where the <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876779">last screenshot method is focused</a>
<ul>
<li>If a full page screenshot was copied, then the full page button and the copy button will be focused on the next screenshot.</li>
<li>This will help improve taking multiple screenshots in a row from the keyboard</li>
</ul>
</li>
</ul>
<h4>Search and Navigation</h4>
<ul>
<li>Marc has implemented the UX spec for switch to tab across containers @ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1871980">1871980</a> and added voice support @ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876759">1876759</a> (will be <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876743">enabled in Nightly soon</a>)</li>
<li>Anna has fixed various accessibility issues around the urlbar, including providing interactive roles to search bar button (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1871980">1871980</a>), fixing TAB behaviour @ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874277">1874277</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875654">1875654</a> and various test fixes</li>
<li>Trending suggestions are now enabled on Bing (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1872409">1872409</a>) for Nightly users.</li>
<li>Drew fixed the Weather suggestions UI @ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1878190">1878190</a></li>
<li>Dao fixed top pick alignment @ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876020">1876020</a></li>
<li>Mandy and Mark have done a lot of work towards search-config-v2 that allows us to share search configuration across desktop and mobile, tracking bug @ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1833829">1833829</a></li>
</ul>
<h4>Storybook/Reusable Components</h4>
<ul>
<li>Hanna <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874505">fixed a text centering issue in our new infobars in certain case</a></li>
<li>Hanna <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1877416">fixed an issue where the “installing components” infobar would appear multiple times</a></li>
<li>Team is making progress with creating<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1850611"> a design tokens JSON source of truth</a>
<ul>
<li><a href="https://github.com/FirefoxUX/gecko-dev/tree/json-design-tokens">Most of this work is happening over on GitHub </a></li>
</ul>
</li>
</ul>2024-02-15T19:51:01+00:00Mike ConleyThe Mozilla Blog: Activist Chris Smalls reflects on taking on Amazon, forming worker unions and digital activism in 2024
https://blog.mozilla.org/en/internet-culture/chris-smalls-rise25-amazon-labor-union-activism/
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<p><em>At Mozilla, we know we can’t create a better future alone, that is why each year we will be highlighting the work of 25 digital leaders using technology to amplify voices, effect change, and build new technologies globally through our <a href="https://rise25.mozilla.org/?_gl=1*585km0*_ga*MTY1MDQ4MTg2NC4xNjk5NDc0NTE5*_ga_X4N05QV93S*MTcwNzE4MDk3Ny40NC4wLjE3MDcxODA5NzcuMC4wLjA." rel="noreferrer noopener" target="_blank">Rise 25 Awards.</a> These storytellers, innovators, activists, advocates. builders and artists are helping make the internet more diverse, ethical, responsible and inclusive.</em></p>
<p><em>This week, we chatted with winner Chris Smalls, an activist using technology to effect change and advocate for a better world. He’s the founder and president of the Amazon Labor Union in Staten Island that advocates for workers’ rights and conditions. In 2020, he was fired by Amazon after leading protests against its working conditions during the COVID-19 pandemic. We talk with Smalls about the early days of the union fight, his work in the community and how the digital world has impacted organizing efforts.</em></p>
<p><strong>When people are fighting against Amazon, there are a lot of different fights — wages, time-off, to even remote work now. What was the main thing that you wanted to fight for like during that time? When you began to fight for the union</strong>.</p>
<p>The pandemic, for sure. It was COVID-19. That initially was the reason why I spoke up. You know, after working there for a number of years — five years — and realizing that we weren’t prepared for the virus on a local level, it was a very alarming situation to be in, and this was before the vaccine, before mask testing, before we even really understood what the virus was doing. We knew it was wiping people out, so my fear was that it would spread like wildfire within the warehouse and within the whole Amazon network. So initially, I was just trying to go through the proper channels. And one thing led to another, you know, when I wasn’t met with an answer that I felt was sustainable for not just myself, but for everybody, that’s when I started to pretty much rebel. I try to still do that in a respectable manner, but unfortunately, the company decided to take an aggressive route by just quarantining myself out of the thousands of people, and I felt that wasn’t right at all. So initially it was over COVID-19, but as things unfolded, the demands changed over time. And it wasn’t until 2021 — the end of 2021, spring — was when we decided that we were going to form this independent Amazon labor union.</p>
<p><strong>How did you get people on board with this? How did you convince people to buy into it?</strong></p>
<p>I used Amazon’s principles — really, to be honest with you — earning the trust, building the relationships. One of my favorite principles out of the 14 was, <a href="https://www.amazon.jobs/content/en/our-workplace/leadership-principles">have backbone, disagree and commit,</a> so that’s exactly what I did. I disagreed with the way they were responding. I had a backbone to stand up to it, and I committed myself to the movement and committed myself to building relationships and earning the trust of the workers. So, over the course of 11 months, you know, organizing outside across the street, meeting people, having conversations, having barbecues, giving out free food — and yes, we did give out free weed — we did all these things, little things that mattered the most. Things that Amazon overlooked all the time – the little things. How do people get to work? How do they eat lunch every day? How do they get a ride to and from work in a snowstorm? We were there for them during those times, and we did those little bit of things with a little bit of money that we had from donations, and that’s ultimately how we defeated them, which is bringing people together from all different backgrounds.</p>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img alt="" class="wp-image-74252" height="1024" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2024/02/Mozilla_rise25_Chris-Smalls_1-683x1024.jpg" width="683" /><figcaption class="wp-element-caption">Chris Smalls at Mozilla’s Rise25 award ceremony in October 2023.</figcaption></figure></div>
<p><strong>When you reflect on your time at Amazon, what do you remember most about that period in your life in terms of the work that you did there?</strong></p>
<p>What I remember most is really just being allowed to be exactly who people see today. When I worked there, I was so well respected because I was a good employee, that I was allowed to pretty much create my culture within my own little department no matter what building I was in. I opened up 3 buildings for Amazon — one in New Jersey, Connecticut and Staten Island — and for me to go to each of these buildings and be able to have the respect of upper management and have the morale of the people underneath me to make them productive, and my team go number one in our department. I think people respected the fact that I was always siding with the workers, no matter what position I was in, and I was a supervisor. To have the morale that I had, I had to understand where people came from, and I understood where they came from because I was them at one point in time. I was an entry level worker on the line, picking and packing boxes just like the rest of them. So for me, I never forgot where I came from, and by having those types of skill sets, along with learning those principles, that’s what made me the best organizer I can possibly be.</p>
<p><strong>You’ve gotten a lot of different spotlights — <a href="https://www.youtube.com/watch?v=BduzkjBdw_o">being on The Daily Show,</a> <a href="https://www.youtube.com/shorts/s71difXgRtM">meeting President Joe Biden, </a><a href="https://nymag.com/intelligencer/article/chris-smalls-amazon-profile.html">magazine features</a> — which experience from the last few years has kind of made you stop and realize the magnitude of what you did?</strong></p>
<p>The Daily Show is definitely up there, that was a cool one. <a href="https://www.youtube.com/watch?v=_ktmxT-rh2U">The Breakfast Club,</a> that was a cool one for me. <a href="https://www.youtube.com/watch?v=nQC_tMeZ9GI">Desus and Mero</a> was a cool one for me. And of course, the White House. I’m not fond of the President, but to go to the White House as a young black man from where I came from is unheard of, so, that’s always going to be a highlight of my life, regardless of who the President is. </p>
<p><strong>Where do you draw inspiration from to continue the work that you do today?</strong></p>
<p>I draw definitely from the youth, the younger generation. I try to stay young and hip — I’m still 35 years old and I have kids already, I have kids about to be in high school. My kids are 11 going on 12, and they’re watching me on YouTube, especially on TikTok. I’m in their classroom. They’re talking to their friends about their dad. So for me, my inspiration is being a good role model, being a good father and understanding that the youth is paying attention now, and because of my uniqueness and our style, our swag, the way my union is so different, I want to continue to build off of that. I want to make sure that we’re making unionizing cool because before it was boring, you know, to talk about it. But now we’re trying to change the culture of what labor looks like.</p>
<p><strong>What do you think is the biggest challenge that we face right now in the world, on and offline? How do you think we combat it?</strong></p>
<p>Well, the biggest challenge is the opposition. The system that’s been in place is still operating against us, and they got a lot more money and power than we do. The reason why they continue to get away with the things that they do is because we’re still divided. </p>
<p>I’m a fast learner in my few years of organizing, the labor movement itself is in a small bubble. If you talk about social injustice, it’s in a small bubble. You talk about women’s rights, it’s in the small bubble. Climate is in a different bubble. We’re not really, truly connected until we see something like a George Floyd where everybody’s out in the streets, and that’s the problem with America. We all go out in the streets when we see things like George Floyd. But then, after a while, we forget about it, and then we go back to work. And then it’s like, “Oh well, I can’t, because of my own individual problems that I have, and it’s not everybody’s fault. It’s the system that we live in that is designed to keep us distracted and not together.” So I think that’s the biggest issue that we got to overcome is, how do we connect all these different movements? Because at the end of the day, we’re all a part of the working class, no matter what movement, we’re all part of the working class. And if you’re in the labor movement, everybody here is a worker, no matter what job you work for or what industry you work for, you’re a worker. My goal one day is to connect trade unions to all the different movements and make this a class struggle, This is a class struggle. It’s 99.9% of us versus the one percent class, the billionaires. And I think if we all realize — that we’re all poor compared to these billionaires that are the ones who make the decisions for the rest of us and control these corporations — then we’ll be way better off than we are as a country.</p>
<p><strong>What gives you hope about the future of our world to reach a place where we’re all much better?</strong></p>
<p>What gives me hope now is that I’m walking into middle schools now and these 10-year-olds are telling me that Jeff Bezos is a bad man. Back in the day I didn’t go to class, and on Career Day, there was no Chris Small walking into a classroom on Career Day. There was always police officers, firefighters or nurses and doctors. But there was never a young, Black, cool-looking, Urban-like, brother to come in and say “Yo, you could be a trade union leader and still be as cool as a rapper. It was none of that. So for me, that’s what gives me hope is that the young generation — it’s a gift and curse they have access to iPads because they get access to everything — but they’re much more conscious than we were. They’re much more smarter and advanced and I know that could be a little scary, because they do have access to a lot of things at a younger age, but these kids are so smart now that they’re able to make decisions at a younger age. The younger generation is paying attention to the major issues of the world right now. I think we’re in a time that we’ve never seen before and that’s what gives me hope is that the younger generation is going to lead the way instead of us passing the torch, they’re going to lead it.</p>
<a class="ft-c-inline-cta" href="https://www.mozilla.org/en-US/firefox/new?utm_medium=mozilla-websites&utm_source=blog.mozilla.org&utm_content=inline-cta">
<div class="ft-c-inline-cta__media">
<img alt="" class="attachment-1x1 size-1x1" height="512" src="https://blog.mozilla.org/wp-content/blogs.dir/278/files/2020/12/Fx-Browser-icon-fullColor-512-512x512.png" width="512" /> </div>
<div class="ft-c-inline-cta__content">
<h3>Get Firefox</h3> <span>Get the browser that protects what’s important</span> </div>
</a>
<p>The post <a href="https://blog.mozilla.org/en/internet-culture/chris-smalls-rise25-amazon-labor-union-activism/">Activist Chris Smalls reflects on taking on Amazon, forming worker unions and digital activism in 2024</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-02-15T17:44:34+00:00Aron YohannesMozilla Thunderbird: Thunderbird for Android / K-9 Mail: January 2024 Progress Report
https://blog.thunderbird.net/2024/02/thunderbird-for-android-k-9-mail-january-2024-progress-report/
<p><img alt="a dark background with Thunderbird and K-9 Mail logos centered, with the text "Thunderbird for Android, January 2024 dev digest"" class="attachment-640x360 size-640x360 wp-post-image" height="360" src="https://blog.thunderbird.net/files/2024/02/K9-Mail-Dev-Digest-Feb-2024-768x432.jpg" width="640" /></p>
<p>A new year, a new progress report! Learn what we did in January on our journey to transform K-9 Mail into Thunderbird for Android. If you’re new here or you forgot where we left off last year, check out the <a href="https://blog.thunderbird.net/2023/12/thunderbird-for-android-k-9-mail-november-december-2023-progress-report/">previous progress report</a>.</p>
<h3>Account setup</h3>
<p>In January most of our work went into polishing the user interface and user experience of the new and improved account setup. However, there was still one feature missing that we really wanted to get in there: the ability to configure special folders.</p>
<h4>Special folders</h4>
<p>K-9 Mail supports the following special folders:</p>
<ul>
<li><strong>Archive</strong>: When configured, an <em>Archive</em> action will be available that moves a message to the designated archive folder.</li>
<li><strong>Drafts</strong>: When configured, the <em>Save as draft</em> action will be available in the compose screen.</li>
<li><strong>Sent</strong>: Messages that have been successfully submitted to the outgoing server will be uploaded to this folder. If this special folder is set to <em>None</em>, the app won’t save a copy of sent messages.<br />Note: There’s also the setting <em>Upload sent messages</em> that can be disabled to prevent sent messages from being uploaded, e.g. if your email provider automatically saves a copy of outgoing messages.</li>
<li><strong>Spam</strong>: When configured, a <em>Spam</em> action will be available that moves a message to the designated spam folder. (Please note that K-9 Mail currently does not include spam detection. So besides moving the message, this doesn’t do anything on its own. However, moving a message to and from the spam folder often trains the server-side spam filter available at many email providers.)</li>
<li><strong>Trash</strong>: When configured, deleting a message in the app will move it to the designated trash folder. If the special folder is set to <em>None</em>, emails are deleted permanently right away.</li>
</ul>
<p>In the distant past, K-9 Mail was simply using common names for these folders and created them on the server if they didn’t exist yet. But some email clients were using different names. And so a user could end up with e.g. multiple folders for sent messages. Of course there was an option to manually change the special folder assignment. But usually people only noticed when it was too late and the new folder already contained a couple of messages. Manually cleaning this up and making sure all email clients are configured to use the same folders is not fun.</p>
<p>To solve this problem, <a href="https://datatracker.ietf.org/doc/html/rfc6154">RFC 6154</a> introduced the SPECIAL-USE IMAP extension. That’s a mechanism to save this special folder mapping on an IMAP server. Having this information on the server means all email clients can simply fetch that mapping and then there should be no disagreement on e.g. which folder is used for sent messages.</p>
<p>Unfortunately, there’s still some email providers that don’t support this extension. There’s also cases where the server supports the feature, but none of the special roles are assigned to any folder. When K-9 Mail added support for the SPECIAL-USE extension, it simply used the data from the server, even if it meant not using any special folders. Unfortunately, that could be even worse than creating new folders, because you might end up e.g. not having a copy of sent messages.</p>
<p>So now the app is displaying a screen to ask the user to assign special folders when setting up an account. </p>
<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_account_setup_special_folders_mapping.png"><img alt="" class="wp-image-1547" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_account_setup_special_folders_mapping-600x1270.png" style="width: 400px;" width="600" /></a></figure></div>
<p>This screen is skipped if the app receives a full mapping from the server, i.e. all special roles are assigned to a folder. Of course you’ll still be able to change the special folder assignment after the account has been created.</p>
<h4>Splitting account options</h4>
<p>We split what used to be the <em>account options</em> screen into two different screens: <em>display options</em> and <em>sync options</em>.</p>
<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-6 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_account_options_old.png"><img alt="" class="wp-image-1550" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_account_options_old-600x1270.png" width="600" /></a><figcaption class="wp-element-caption">Before: Account options</figcaption></figure>
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_display_options.png"><img alt="" class="wp-image-1549" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_display_options-600x1270.png" width="600" /></a><figcaption class="wp-element-caption">After: Display options</figcaption></figure>
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_sync_options.png"><img alt="" class="wp-image-1548" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_sync_options-600x1270.png" width="600" /></a><figcaption class="wp-element-caption">After: Sync options</figcaption></figure>
</figure>
<h4>Improved server certificate error screen</h4>
<p>The screen to display server certificate errors during account setup has received an overhaul.</p>
<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-8 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_certificate_error_old.png"><img alt="" class="wp-image-1554" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_certificate_error_old-600x1270.png" width="600" /></a><figcaption class="wp-element-caption">Before: Certificate error screen</figcaption></figure>
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_certificate_error_1.png"><img alt="" class="wp-image-1552" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_certificate_error_1-600x1270.png" width="600" /></a><figcaption class="wp-element-caption">After: Initial certificate error screen</figcaption></figure>
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/02/k9mail_certificate_error_2.png"><img alt="" class="wp-image-1553" height="1270" src="https://blog.thunderbird.net/files/2024/02/k9mail_certificate_error_2-600x1270.png" width="600" /></a><figcaption class="wp-element-caption">After: Advanced certificate error screen</figcaption></figure>
</figure>
<h4>Polishing the user experience</h4>
<p>With the special folders screen done, we’re now feature complete. So we took a step back to look at the whole experience of setting up an account. And we’ve found several areas where we could improve the app. </p>
<p>Here’s an (incomplete) list of things we’ve changed:</p>
<ul>
<li>We reduced the font weight of the header text to be less distracting.</li>
<li>In some parts of the flow there’s enough content on the screen that a user has to scroll. The area between the header and the navigation buttons at the bottom can be very small depending on the device size. So we included the header in the scrollable area to improve the experience on devices with a small screen.</li>
<li>There are a couple of transient screens, e.g. when checking server settings. Previously the app first displayed a progress indicator when checking server settings, then a success message for 2 seconds, but allowed the user to skip this screen by pressing the <em>Next</em> button. This turned out to be annoying and confusing. Annoying because the user has to wait longer than necessary; and confusing because it looked like user input was required, but by the time the user realizes that, the app will have most likely switched to the next screen automatically.<br />We updated these transient screens to always show a progress indicator and hide the <em>Next</em> button, so users know something is happening and there’s currently nothing for them to do.</li>
<li>We also fixed a couple of smaller issues, like the inbox not being synchronized during setup when an account was configured for manual synchronization.</li>
</ul>
<h3>Fixing bugs</h3>
<p>Some of the more interesting bugs we fixed in January:</p>
<ul>
<li>When rotating the screen while selecting a notification sound in settings, some of the notification settings were accidentally disabled (<a href="https://github.com/thunderbird/thunderbird-android/issues/7468">#7468</a>). </li>
<li>When importing settings a <em>preview lines</em> value of 0 was ignored and the default of 2 was used instead (<a href="https://github.com/thunderbird/thunderbird-android/issues/7493">#7493</a>).</li>
<li>When viewing a message and long-pressing an image that is also a link, only menu items relevant for images were displayed, but not ones relevant for links (<a href="https://github.com/thunderbird/thunderbird-android/issues/7457">#7457</a>).</li>
<li>Opening an attachment from K-9 Mail’s message view in an external app and then sharing the content to K-9 Mail opened the compose screen for a new message but didn’t add an attachment (<a href="https://github.com/thunderbird/thunderbird-android/issues/7557">#7557</a>).</li>
</ul>
<h3>Community Contributions</h3>
<p><a href="https://github.com/new-sashok724">new-sashok724</a> fixed a bug that prevented the use of IP addresses for incoming or outgoing servers (<a href="https://github.com/thunderbird/thunderbird-android/pull/7483">#7483</a>).</p>
<p>Thank you <img alt="❤" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/2764.png" style="height: 1em;" /></p>
<h3>Releases</h3>
<ul>
<li><a href="https://github.com/thunderbird/thunderbird-android/releases/tag/6.714">K-9 Mail v6.714 (beta)</a> (2024-01-04)</li>
</ul>
<p><strong>If you want to help shape Thunderbird for Android, </strong><a href="https://forum.k9mail.app/t/how-do-i-become-a-beta-tester/68"><strong>become a beta tester</strong></a><strong> and provide feedback on new features while they are still in development.</strong></p>
<figure class="wp-block-image size-full"><a href="https://mzla.link/3MIFAKe"><img alt="" class="wp-image-1444" height="630" src="https://blog.thunderbird.net/files/2023/11/EOY-FB-Mastodon-Lanscape.jpg" width="1200" /></a></figure>
<p>The post <a href="https://blog.thunderbird.net/2024/02/thunderbird-for-android-k-9-mail-january-2024-progress-report/">Thunderbird for Android / K-9 Mail: January 2024 Progress Report</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p>2024-02-15T17:21:18+00:00ckettiCameron Kaiser: One less Un*xy option for 32-bit PowerPC
http://tenfourfox.blogspot.com/2024/02/one-less-unxy-option-for-32-bit-powerpc.html
Most of you still using a Power Mac as a daily or occasional driver are probably either running Linux, Tiger or Leopard, and a minority on OS 9. Despite many distributions no longer shipping 32-bit PPC installs, Gentoo Linux still has <a href="https://wiki.gentoo.org/wiki/PPC/FAQ">specific support</a> along with a few others, as does <a href="https://www.adelielinux.org/">Adélie Linux</a> if you like <tt>musl</tt> for breakfast. Still, for server duties, where I come from, you bring on the BSDs. In this blog you've already met my long-suffering <a href="http://tenfourfox.blogspot.com/2018/11/and-now-for-something-completely.html">NetBSD Macintosh IIci</a> which is still trucking to this day and more recently <a href="http://tenfourfox.blogspot.com/2019/06/and-now-for-something-completely.html">my also-NetBSD G4 Mac mini</a> (which later needed, effectively, <a href="https://oldvcr.blogspot.com/2020/07/refurb-weekend-mac-mini-g4.html">a logic board swap</a>), but I also have a Quadra 605 with a full '040 running NetBSD I use for utility tasks and at one time I ran an intermediate incarnation of <tt>gopher.floodgap.com</tt> on a Power Macintosh 7300 with a Sonnet G3 running NetBSD too. I stuffed that system full with a gig of RAM and a SATA card and it did very well until I got the current POWER6 server in 2010.
<p>
NetBSD has the widest support, continuing to run on <a href="http://wiki.netbsd.org/ports/mac68k/">most 68Ks</a> and <a href="http://wiki.netbsd.org/ports/macppc/">PCI Power Macs</a> to this day (leaving out only the NuBus Power Macs which aren't really supported by much of anything anymore, sadly). However, <a href="http://www.openbsd.org/macppc.html">OpenBSD</a> works fine on New World Macs, and FreeBSD has a very mature 32-bit PowerPC port — or, should I say, soon will have had one, since starting in FreeBSD 15 (13.x is the current release), ARMv6, 32-bit Intel and 32-bit PowerPC support will <a href="https://lists.freebsd.org/archives/freebsd-announce/2024-February/000117.html">likely be removed</a>. No new 32-bit support will be added, including for RISC-V.
</p><p>
Even though I have a large number of NetBSD systems, I still like FreeBSD, and one of my remote "island" systems runs it. The differences between BSDs are more subtle than with Linux distributions, but you can still enjoy the different flavours that result, and I even ported a little FreeBSD code to the NetBSD kernel so I could support automatic restarts after a power failure on the G4 mini. The fact that the userland and kernel are better matched together probably makes the BSDs better desktop clients, too, especially since on big-endian we're already used to some packages just not building right, so we don't lose a whole lot by running it. (Usually those are the same packages that wouldn't build on anything but Linux anyway.)
</p><p>
This isn't the end for the G5, which should still be able to run the 64-bit version of FreeBSD, and OpenBSD hasn't voiced any firm plans to cut 32-bit loose. However, NetBSD supports the widest range of Macs, including Macs far older than any Power Mac, and frankly if you want to use a Un*x on a Power Mac and have reasonable confidence it will still be running on it for years to come, it's undeniably the one with the best track record.</p>2024-02-15T03:09:23+00:00ClassicHasClassMozilla Thunderbird: February 2024 Community Office Hours: All About Add-Ons!
https://blog.thunderbird.net/2024/02/february-2024-thunderbird-office-hours-add-ons/
<p><img alt="A graphic with an icon representing community, set inside the Thunderbird logo, with the text "Thunderbird Community Office Hours for February 2024: Add-Ons"" class="attachment-640x360 size-640x360 wp-post-image" height="320" src="https://blog.thunderbird.net/files/2024/02/community-office-hours-FEB-2024.png" width="640" /></p>
<p>The topic for this month’s Thunderbird Community Office Hours takes a short break from the core of Thunderbird and takes us into the world of extensions we call <a href="https://addons.thunderbird.net/thunderbird/">Add-ons</a>. These allow our users to add features and options beyond the customization already available in Thunderbird by default.</p>
<h3>UPDATE: Video Replay Now Available</h3>
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<h3>February Office Hours Topic: Add-ons</h3>
<div class="wp-block-image">
<figure class="alignleft size-full is-resized"><a href="https://blog.thunderbird.net/files/2024/02/JohnBieling.jpg"><img alt="" class="wp-image-1538" height="400" src="https://blog.thunderbird.net/files/2024/02/JohnBieling.jpg" style="width: 244px; height: auto;" width="400" /></a><figcaption class="wp-element-caption">John Bieling: Sr. Software Engineer, Add-ons Ecosystem</figcaption></figure></div>
<p>We want it to be easy to make Thunderbird yours, and so does our community. The Thunderbird <a href="https://addons.thunderbird.net/en-US/thunderbird/">Add-on page</a> shows the power of community-driven extensions. There are Add-ons for everything, from themes to integrations, that add even more customization to Thunderbird.</p>
<p>Our guest for this month’s Thunderbird Community Office Hours is John Bieling, who is the person responsible for Thunderbird’s add-on component. This includes the WebExtension APIs, add-on documentation, as well as community support. He hosts a frequent open call about Add-on development and is welcoming to any developers seeking help. Come join us to learn about Add-on development and meet a key developer in the space.</p>
<h3>Catch Up On Last Month’s Thunderbird Community Office Hours</h3>
<p>Before you join us on February 22 at 18:00 UTC, watch last month’s office hours with UX Engineer Elizabeth Mitchell. We had some great discussion around the Message Context Menu and testing beta and daily images. Watch the video and read more about our guest at <a href="https://blog.thunderbird.net/2024/01/january-2024-thunderbird-community-office-hours-how-to-join-us/">last month’s blog post</a>.</p>
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div><figcaption class="wp-element-caption">Watch January’s Office Hours session, all about the message context menu</figcaption></figure>
<h3>Join Us On Zoom</h3>
<p>(Yes, we’re still on Zoom for now, but a Jitsi server for future office hours is in the works!)</p>
<p><strong>When</strong>: <strong><a href="https://time.is/1800_22_Feb_2024_in_UTC?February_2024_Thunderbird_Community_Office_Hours">February 22 at 18:00 UTC</a></strong> (10am PST / 1pm EST / 7pm CET)</p>
<p><strong>Direct URL To Join:</strong> <a href="https://mozilla.zoom.us/j/92739888755?pwd=c1pDVkJVVitwK3ZhMVdOYVk3dlZiQT09">https://mozilla.zoom.us/j/97506306527</a><br />Meeting ID: 97506306527<br />Password: 319424</p>
<p><strong>Dial by your location:</strong></p>
<ul>
<li>+1 646 518 9805 US (New York)</li>
<li>+1 669 219 2599 US (San Jose)</li>
<li>+1 647 558 0588 Canada</li>
<li>+33 1 7095 0103 France</li>
<li>+49 69 7104 9922 Germany</li>
<li>+44 330 088 5830 United Kingdom</li>
<li>Find your local number:<a href="https://mozilla.zoom.us/u/adkUNXc0FO"> https://mozilla.zoom.us/u/adkUNXc0FO</a></li>
</ul>
<p>The call will be recorded and this post will be updated with a link to the recording afterwards.</p>
<figure class="wp-block-image size-full"><a href="https://mzla.link/3MIFAKe"><img alt="" class="wp-image-1444" height="630" src="https://blog.thunderbird.net/files/2023/11/EOY-FB-Mastodon-Lanscape.jpg" width="1200" /></a></figure>
<p>The post <a href="https://blog.thunderbird.net/2024/02/february-2024-thunderbird-office-hours-add-ons/">February 2024 Community Office Hours: All About Add-Ons!</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p>2024-02-14T17:27:03+00:00Monica Ayhens-MadonMozilla Thunderbird: Thunderbird In 2023: The Milestones and The Lessons We Learned
https://blog.thunderbird.net/2024/02/thunderbird-in-2023-the-milestones-and-the-lessons-we-learned/
<p><img alt="A dark background with the old and new Thunderbird logos side by side, with the text "Thunderbird 2023 Recap"" class="attachment-640x360 size-640x360 wp-post-image" height="320" src="https://blog.thunderbird.net/files/2024/02/milestones-blog-1.jpg" width="640" /></p>
<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=de&u=https://blog.thunderbird.net/2024/02/thunderbird-in-2023-the-milestones-and-the-lessons-we-learned/" rel="noreferrer noopener" target="_blank">Auf Deutsch übersetzen</a></div>
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=es&u=https://blog.thunderbird.net/2024/02/thunderbird-in-2023-the-milestones-and-the-lessons-we-learned/" rel="noreferrer noopener" target="_blank">Traducir al español</a></div>
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=fr&u=https://blog.thunderbird.net/2024/02/thunderbird-in-2023-the-milestones-and-the-lessons-we-learned/" rel="noreferrer noopener" target="_blank">Traduire en français</a></div>
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=it&u=https://blog.thunderbird.net/2024/02/thunderbird-in-2023-the-milestones-and-the-lessons-we-learned/" rel="noreferrer noopener" target="_blank">Traduci in italiano</a></div>
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=ja&u=https://blog.thunderbird.net/2024/02/thunderbird-in-2023-the-milestones-and-the-lessons-we-learned/">日本語に翻訳</a></div>
</div>
<p>The Thunderbird Project enjoyed a fantastic 2023. From my point of view – as someone who regularly engages with both the community and our team on a daily basis – the past year brought a renewed sense of purpose, sustainability, and excitement to Thunderbird. Let’s talk about a few of the awesome milestones Thunderbird achieved, but let’s also discuss where we stumbled and what lessons we learned along the way. </p>
<h3 class="wp-block-heading">Our 2023 Milestones</h3>
<p>The biggest milestone of 2023 was <strong>Thunderbird 115 “Supernova.”</strong> This release marked <a href="https://blog.thunderbird.net/2023/02/the-future-of-thunderbird-why-were-rebuilding-from-the-ground-up/">the first step</a> towards a more flexible, reliable, and customizable Thunderbird that will accommodate different needs and workflows. Work has been long underway to modernize huge amounts of old code, with the aim of modernizing Thunderbird to deliver new features even faster. The “Supernova” release represented the first fruits of those efforts, and there’s a lot more in the pipeline! </p>
<p>Alongside Supernova came a <a href="https://blog.thunderbird.net/2023/05/introducing-the-brand-new-thunderbird-logo/">brand new Thunderbird logo</a> to signal the revitalization of the project. We finally (even a bit reluctantly) said goodbye to our beloved “wig on an envelope” and ushered in a new era of Thunderbird with a refreshed, redesigned logo. But it was important to honor our roots, which is why we hired Jon Hicks – the designer of the original Firefox and Thunderbird logos – to help us bring it to life. <em>(Now that you’ve all been living with it for the last several months, has it grown on you? Let us know in the comments of this post!)</em></p>
<figure class="wp-block-image"><img alt="" class="wp-image-1532" height="1120" src="https://blog.thunderbird.net/files/2024/02/image.png" width="1600" /></figure>
<p>One 2023 milestone that deserves more attention is that we hired a dedicated User Support Specialist! Roland Tanglao has been working enthusiastically towards removing “documentation debt” and updating the 100s of Thunderbird support articles at <a href="https://support.mozilla.org/products/thunderbird">support.mozilla.org</a> (which you’ll see us refer to internally as “SUMO”). Beyond that, he keeps a watchful eye on our <a href="https://matrix.to/#/#thunderbird:mozilla.org">Matrix community support channel</a> for emerging issues, and is in the forums answering as many help questions as humanly possible, alongside our amazing support volunteers. In a nutshell, Roland is doing everything he can to improve the experience of asking for and receiving support, modernize existing documentation, and create new guides and articles that make using Thunderbird easier.</p>
<p>These are some – not all – of our accomplishments from last year. But it’s time to shift focus to where we stumbled, and how we’ll do better. </p>
<h3 class="wp-block-heading">The Lessons We Learned In 2023</h3>
<p>In 2023, we failed to finish some of the great features we wanted to bring to Thunderbird, including Sync and Account Hub (both of which, however, are still in development). We also missed our target release window for Thunderbird on Android, <a href="https://blog.thunderbird.net/2023/12/when-will-thunderbird-for-android-be-released/">after deciding</a> it was worth the extra development time to add the kind of functionality and flexibility you expect from Thunderbird software. </p>
<p>Speaking of functionality you expect, we hear you loud and clear: you want Exchange support in Thunderbird. We’ve already done some exploratory work, and have enabled the <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-2469-thunderbird-how-to-exchange-rot-for-rust/">usage of Rust in Thunderbird</a>. This is a complex topic, but the short version is that this opens the doors for us to start implementing native support for the Exchange protocol. It’s officially <a href="https://developer.thunderbird.net/planning/roadmap">on our roadmap</a>!</p>
<p>We also believe our communication with you has fallen short of where it needs to be. There are times when we get so excited about things we’re working on that it seems like marketing hype. In other situations, we have over-promised and under-delivered because these projects haven’t been extensively scoped out.</p>
<p>We’re beginning to solve the latter issue with the recent hiring of Kelly McSweeney, Senior Technical PM. She joined our team late last year and brings 20 years of valuable experience to Thunderbird. In a nutshell, Kelly is building processes and tools to accurately gauge how long development time will realistically take, from extensive projects to the tiniest tasks. Basically, she’s getting us very organized and making things run much more efficiently! This not only means smoother operations across the organization, but also clearer communication with you going forward. </p>
<p>And communication is our biggest area of opportunity right now, specifically with our global Thunderbird community. We haven’t been as transparent as an open source project should be, nor have we discussed our future plans frequently enough. We’ve had several meetings about this over the past few weeks, and we’re taking immediate steps to do better. </p>
<p>To begin with, you’ll start seeing monthly Developer Digests <a href="https://blog.thunderbird.net/2024/01/thunderbird-monthly-development-digest-january-2024/">like this one</a> from Alex, aimed at giving you a closer look at the work currently being planned. We’re also increasing our activity on the <a href="https://thunderbird.topicbox.com/latest">Thunderbird mailing lists</a>, where you can give us direct feedback about future improvements and features. </p>
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<p>In 2024 you can also look forward to monthly community <a href="https://blog.thunderbird.net/2024/01/january-2024-thunderbird-community-office-hours-how-to-join-us/">Office Hours sessions</a>. This is where you can get some face time (or just voice time) with our team, and watch presentations about upcoming features and improvements by the developer(s) working on them. </p>
<p>One last thing: In 2023, Thunderbird’s Marketing & Communications team consisted of myself and Wayne Mery. This year Wayne and I are fortunate to be working alongside new team members Heather Ellsworth, Monica Ayhens-Madon, and Natalia Ivanova. Together, we’re going to work diligently to create more tutorials on the blog, more <a href="https://youtube.com/@thunderbirdproject">video guides</a>, and more content to help you get the most out of Thunderbird – with a focus on productivity. </p>
<h3 class="wp-block-heading">How To Stay Updated</h3>
<p>Thank you for being on this journey with us! If you want to get more involved and stay in touch, here are the best places to keep up with what’s happening at Thunderbird:</p>
<ul>
<li>We will be more active right here on this blog, so come back once or twice per month to see what’s new.</li>
<li>If you enjoy the technical bits, want to help test Thunderbird, or you’re part of our contributor community, these <a href="https://thunderbird.topicbox.com">mailing lists at Topicbox</a> are ideal. </li>
<li>Follow us on <a href="https://mastodon.online/@thunderbird">Mastodon</a> or <a href="https://twitter.com/mozthunderbird">X/Twitter</a> for more frequent – and fun – updates!</li>
<li>Join our <a href="https://matrix.to/#/#thunderbird:mozilla.org">Thunderbird Community Support</a> room on Matrix if you need some help.</li>
</ul>
<figure class="wp-block-image size-full"><a href="https://mzla.link/3MIFAKe"><img alt="" class="wp-image-1444" height="630" src="https://blog.thunderbird.net/files/2023/11/EOY-FB-Mastodon-Lanscape.jpg" width="1200" /></a></figure>
<p>The post <a href="https://blog.thunderbird.net/2024/02/thunderbird-in-2023-the-milestones-and-the-lessons-we-learned/">Thunderbird In 2023: The Milestones and The Lessons We Learned</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p>2024-02-12T16:38:54+00:00Jason EvangelhoPaul Bone: The right amount of poison
https://paul.bone.id.au/blog/2024/02/13/poisoning-firefox-memory/
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Oh, you don’t want any poison in your porridge.
But how about in your computer’s memory?</p>
</div>
</div>
</div>
<div class="sect1">
<h3>Papa Bear - too much poison</h3>
<div class="sectionbody">
<div class="paragraph">
<p>Papa Bear likes his chair hard, his porridge hot and his browser written in
a memory safe language that helps engineers avoid memory bugs like
<em>buffer overruns</em> and <em>use after frees</em>.</p>
</div>
<div class="paragraph">
<p>But even Papa Bear has to compromise, part of Firefox is written in a
memory safe language and the rest is written in C++. When using
C++ there are a variety of defenses programmers can take to help
catch memory errors. One of those is called <em>memory poisoning</em>.</p>
</div>
<div class="paragraph">
<p><code>mozjemalloc</code> the memory allocator built into Firefox will <em>poison</em> memory
by calling <code>memset(aPtr, 0xE5, size);</code> before freeing it.
Any memory containing the pattern <code>0xE5E5E5E5</code> is therefore very likely to be
memory that’s already been freed.
This has two and a half benefits:
If some code were to free <strong>and then dereference</strong> some memory
(<em>a use after free bug</em>)
it would most likely cause the browser to crash, which is much better
than a potentially exploitable bug allowing Goldilocks to steal Papa Bear’s
banking credentials!
The other benefit is that when Firefox does crash due to such a
use-after-free, the presence of this pattern in the crash report allows
engineers to see the type of error that occurred and hopefully fix the
mistake.</p>
</div>
<div class="paragraph">
<p>Note that back in March 2023 we
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1609478">moved the poison
operation outside of the arena lock’s critical section</a>;
which improved performance in some tests.</p>
</div>
</div>
</div>
<div class="sect1">
<h3>Mama Bear - no poisoning</h3>
<div class="sectionbody">
<div class="paragraph">
<p>You probably figured out by now that I’m going to persist with this
metaphor.
Mama Bear likes her chair soft, her porridge cold (and congealed (yuck)),
and her browser fast.</p>
</div>
<div class="paragraph">
<p>But how much faster is Mama Bear’s experience?
This is the question that was raised recently when
Randell Jesup was benchmarking various memory allocators in Firefox.
He noted that while mozjemalloc performs poisoning, many of the other
allocators do not and to compare the performance of the allocators more
fairly they should either all perform poisoning or none of them should.</p>
</div>
<div class="paragraph">
<p>And so Randell noted that, depending on the test,
Firefox could be
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1850008#c3">between 0.5% and 4%
faster</a>
with poisoning disabled.</p>
</div>
<div class="paragraph">
<p>There are some results I collected. The "sp2" (Speedometer 2) and "sp3"
(Speedometer 3) tests are browser benchmarks - larger numbers indicate
better performance.
The amazon and instagram tests are pageload tests measured in seconds with
the <em>ContentfulSpeedIndex</em> metric - smaller numbers indicate better
performance.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 20%;" />
<col style="width: 20%;" />
<col style="width: 20%;" />
<col style="width: 20%;" />
<col style="width: 20%;" />
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"></th>
<th class="tableblock halign-left valign-top">sp2 (score)</th>
<th class="tableblock halign-left valign-top">sp3 (score)</th>
<th class="tableblock halign-left valign-top">amazon (sec)</th>
<th class="tableblock halign-left valign-top">instagram (sec)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Poison</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">178.84 ± 0.84</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13.32 ± 1.03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">243.2 ± 1.96</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">419.43 ± 1.04</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">No poisoning</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">179.42 ± 0.48</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13.39 ± 0.31</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">237.55 ± 2.6</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">414.5 ± 0.8</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The speedometer figures are pretty close and these are the best pageload
figures (the others showed very little difference but nothing regressed, yes
I’m aware I’ve cherry-picked data).</p>
</div>
<div class="paragraph">
<p>This means that if it weren’t for the lack of security and debugability
Mama Bear would have the right approach.</p>
</div>
</div>
</div>
<div class="sect1">
<h3>Baby Bear</h3>
<div class="sectionbody">
<div class="paragraph">
<p>Baby Bear loves a compromise, they want their computer to be safe from
Goldilocks' hacking attempts but also love performance improvements.</p>
</div>
<div class="paragraph">
<p>One compromise may be to probabilistic poison memory some of the time, e.g.
a roughly 5% chance of poisoning.
That’s more complex and involves a memory write anyway to keep the "time
until poison" counter updated.
We didn’t investigate it.
But it’s worth noting that it would be similar in spirit to the
<a href="https://groups.google.com/g/mozilla.dev.platform/c/AyECjDNsqUE/m/Jd7Jr4cXAgAJ?pli=1">Probabilistic Heap Checker (PHC)</a>
that’s
<a href="https://groups.google.com/a/mozilla.org/g/dev-platform/c/C1LcRpii-cI">rolling out</a>
in Firefox or the similar <a href="https://arxiv.org/abs/2311.09394">GWP-ASan</a>
capability in Chrome.</p>
</div>
<div class="paragraph">
<p>Instead we tested "what if we poison only the first cache line of a memory
cell".
Andrew McCreight and Olli Pettay
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1850008#c9">pointed out that</a>
Element, a common DOM structure, is 128 bytes long and poisoning it is
useful to detect memory errors in DOM code, as a lot of DOM code will
involve Element.</p>
</div>
<div class="paragraph">
<p>We tested poisoning the first 64, 128 and 256 bytes of each structure.
We assume that management of cache and writing cache lines back to RAM is
going to be the dominant cost. Therefore we round-up our writes to the next
cache line boundary..</p>
</div>
<div class="paragraph">
<p>For example, on a computer with 64-byte cache lines, if a 96-byte object is
allocated so that the first 32-bytes is in one cache-line, while the next
64-bytes is in another. Our 64-byte write would cover two halves of
different cache lines. In this case we will poison all 96-bytes because
doing so writes to the same number of cache lines as the original 64-byte
write.</p>
</div>
<div class="paragraph">
<p>Let’s add these options to our table of results.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 20%;" />
<col style="width: 20%;" />
<col style="width: 20%;" />
<col style="width: 20%;" />
<col style="width: 20%;" />
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"></th>
<th class="tableblock halign-left valign-top">sp2 (score)</th>
<th class="tableblock halign-left valign-top">sp3 (score)</th>
<th class="tableblock halign-left valign-top">amazon (sec)</th>
<th class="tableblock halign-left valign-top">instagram (sec)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Poison</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">178.84 ± 0.84</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13.32 ± 1.03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">243.20 ± 1.96</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">419.43 ± 1.04</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Poison 256</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">179.50 ± 0.55</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13.35 ± 0.33</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">240.47 ± 2.82</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">415.28 ± 1.30</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Poison 128</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">179.19 ± 0.43</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13.35 ± 0.59</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">241.62 ± 3.05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">414.95 ± 1.15</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Poison 64</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">179.09 ± 0.87</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13.33 ± 0.83</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">242.13 ± 2.56</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">414.11 ± 0.91</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">No poisoning</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">179.42 ± 0.48</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13.39 ± 0.31</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">237.55 ± 2.60</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">414.5 ± 0.8</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>As above, sp2 and sp3 are scores - bigger numbers are better. While amazon
and instagram are page load tests where smaller numbers are better.</p>
</div>
<div class="paragraph">
<p>As expected the partial poisoning results fall between full and no
poisoning. But what’s a little bit surprising is that in some tests (sp2 and
amazon) poisoning a larger amount of memory made things faster.
This could be because the <code>memset()</code> routine or the hardware itself is able
to optimise larger writes more effectively.
That said it’s important to acknowledge that the standard deviation is
fairly high and doing the right statistical analysis is beyond this blog post.</p>
</div>
</div>
</div>
<div class="sect1">
<h3>Just right</h3>
<div class="sectionbody">
<div class="paragraph">
<p>Since poisoning more memory isn’t <em>much</em> slower and in some
cases is faster than poisoning a little memory, then we might as well choose to
poison
<a href="https://searchfox.org/mozilla-central/rev/9013524d23da6523a7ec4479b5682407a1323f6c/memory/build/mozjemalloc.cpp#1484">256 bytes</a>
which comfortably covers the Element object and most
others and for the others it likely covers many of their most-often accessed
fields.
We’re confident that this is enough to help us catch many errors that can be
caught with poisoning.
While also performing well enough, especially for the pageload tests where
it is closer to the performance available with poisoning disabled.
We think that Baby Bear would agree, it is <em>Just Right</em>.</p>
</div>
</div>
</div>
<div class="sect1">
<h3>It gets better</h3>
<div class="sectionbody">
<div class="paragraph">
<p>With the
<a href="https://groups.google.com/g/mozilla.dev.platform/c/AyECjDNsqUE/m/Jd7Jr4cXAgAJ?pli=1">Probablistic Heap Checker (PHC)</a>
rolling out soon we will have an even greater ability to catch information
related to memory errors.
I’ll be writing about this in the future.</p>
</div>
</div>
</div>
<div class="sect1">
<h3>Why Papa Bear is safe and Mama Bear is secure?</h3>
<div class="sectionbody">
<div class="paragraph">
<p>In some ways it feels more natural to lean in to (negative) gender
stereotypes where Papa Bear wants things fast and Mama Bear is the
cautious one. I considered this however to make comprehension easier it’s
easier to explain poisoning before explaining turning poisoning off and the
nursery tale describes Papa Bear’s preferences first,
so that’s the order I introduced them here.
Flipping the script on gender stereotypes was accidental.</p>
</div>
</div>
</div>2024-02-12T13:00:00+00:00Tiger Oakes: Tricks for writing CSS in Fluent UI React v9
https://tigeroakes.com/posts/fluent-ui-css-tricks/
Advanced features for clean & performant CSS.2024-02-12T00:00:00+00:00Adrian Gaudebert: Dawnmaker a une page Steam ET un trailer
http://adrian.gaudebert.fr/blog/post/Dawnmaker-a-une-page-Steam-ET-un-trailer
<p>Dawnmaker, le jeu sur lequel je travaille dans le cadre d'<a href="https://arpentor.studio/fr/" hreflang="fr">Arpentor Studio</a>, depuis plus de deux ans, a désormais une <a href="https://store.steampowered.com/app/2749100?utm_source=adrian.gaudebert.fr&utm_campaign=announcement">page Steam</a> et <a href="https://www.youtube.com/watch?v=gJpfUVW-IWo">un trailer</a>. Je vous laisse découvrir ça :</p>
<p></p>
<p>Ça vous a plu ? N'hésitez pas à <strong><a href="https://store.steampowered.com/app/2749100?utm_source=adrian.gaudebert.fr&utm_campaign=announcement">ajouter le jeu à votre liste de souhaits sur Steam</a></strong> !</p>2024-02-08T14:50:27+00:00AdrianThe Mozilla Blog: A New Chapter for Mozilla: Focused Execution and an Expanded Role in Charting the Internet’s Future
https://blog.mozilla.org/en/mozilla/a-new-chapter-for-mozilla-laura-chambers-expanded-role/
<p>Today marks a significant moment in our journey, and I am thrilled to share some important news with you. After much thoughtful consideration, I have decided to transition from the role of CEO of Mozilla Corporation back to the position of Mozilla Corporation Executive Chairwoman, a role I held with great passion for many years. </p>
<p>During my 25 years at Mozilla, I’ve worn many hats, and this move is driven by a desire to streamline our focus and leadership for the challenges ahead. I’ve been leading the Mozilla business through a transformative period, while also overseeing Mozilla’s broader mission. It’s become evident that both endeavors need dedicated full-time leadership. </p>
<p>Enter <a href="https://www.linkedin.com/in/chamberslaura/">Laura Chambers</a>, a dynamic board member who will step into the CEO role for the remainder of this year. Laura brings a wealth of experience, having been an active and impactful member of the Mozilla board for three years. With an impressive background leading product organization at Airbnb, PayPal, eBay, and most recently as CEO of Willow Innovations, Laura is well-equipped to guide Mozilla through this transitional period. </p>
<p>Her focus will be on delivering successful products that advance our mission and building platforms that accelerate momentum. Laura and I will be working closely together throughout February to ensure a seamless transition, and in my role as Exec Chair I’ll continue to provide advice and engage in areas that touch on our unique history and Mozilla characteristics. </p>
<p>Laura’s focus will be on Mozilla Corporation with two key goals: </p>
<p><strong>1. Vision and Strategy for the Future: </strong>Refining the company’s vision and aligning the corporate and product strategy behind it. This will be grounded in our mission and unique strengths and shaped by our point of view on technology’s future and our role in it. </p>
<p><strong>2. Outstanding Execution: Focus, Processes, Capabilities: </strong>Doubling down on our core products, like Firefox, and building out our capabilities and innovation pipeline to bring new compelling products to market. </p>
<p>While Laura takes on the reins as CEO of Mozilla Corporation, I will return to supporting the CEO and leadership team as I have done previously as Exec Chair. In addition, I will expand my work in two critical areas: </p>
<p><strong>1. More consistently representing Mozilla in the public</strong> – With a focus on policy, open source, and community — through speaking and direct engagement with the community.</p>
<p><strong>2. Representing Mozilla as a unified entity </strong>– bigger than the sum of our parts — as we continue to strengthen and refine how all the entities work together to advance our policy and community goals with greater urgency and speed. </p>
<p>We’re at a critical juncture where public trust in institutions, governments, and the fabric of the internet has reached unprecedented lows. There’s a tectonic shift underway as everyone battles to own the future of AI. It is Mozilla’s opportunity and imperative to forge a better future. I’m excited about Laura’s day-to-day involvement and the chance for Mozilla to achieve more. Our power lies in the collective effort of people contributing to something better and I’m eager for Mozilla to meet the needs of this era more fully. </p>
<p>Thank you to everyone who participates in Mozilla, supports us, cheers us on, and works towards similar goals. Your dedication is the driving force behind Mozilla’s impact and success. Here’s to a future filled with innovation, collaboration, and continued success! </p>
<p>The post <a href="https://blog.mozilla.org/en/mozilla/a-new-chapter-for-mozilla-laura-chambers-expanded-role/">A New Chapter for Mozilla: Focused Execution and an Expanded Role in Charting the Internet’s Future</a> appeared first on <a href="https://blog.mozilla.org/en/">The Mozilla Blog</a>.</p>2024-02-08T14:30:00+00:00Mitchell BakerThe Rust Programming Language Blog: Announcing Rust 1.76.0
https://blog.rust-lang.org/2024/02/08/Rust-1.76.0.html
<p>The Rust team is happy to announce a new version of Rust, 1.76.0. Rust is a programming language empowering everyone to build reliable and efficient software.</p>
<p>If you have a previous version of Rust installed via rustup, you can get 1.76.0 with:</p>
<pre><code class="language-console">$ rustup update stable
</code></pre>
<p>If you don't have it already, you can <a href="https://www.rust-lang.org/install.html">get <code>rustup</code></a> from the appropriate page on our website, and check out the <a href="https://doc.rust-lang.org/nightly/releases.html#version-1760-2024-02-08">detailed release notes for 1.76.0</a>.</p>
<p>If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (<code>rustup default beta</code>) or the nightly channel (<code>rustup default nightly</code>). Please <a href="https://github.com/rust-lang/rust/issues/new/choose">report</a> any bugs you might come across!</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/08/Rust-1.76.0.html#whats-in-1760-stable" id="whats-in-1760-stable"></a>What's in 1.76.0 stable</h3>
<p>This release is relatively minor, but as always, even incremental improvements lead to a greater whole. A few of those changes are highlighted in this post, and others may yet fill more niche needs.</p>
<h4><a class="anchor" href="https://blog.rust-lang.org/2024/02/08/Rust-1.76.0.html#abi-compatibility-updates" id="abi-compatibility-updates"></a>ABI compatibility updates</h4>
<p>A new <a href="https://doc.rust-lang.org/stable/std/primitive.fn.html#abi-compatibility">ABI Compatibility</a> section in the function pointer documentation describes what it means for function signatures to be ABI-compatible. A large part of that is the compatibility of argument types and return types, with a list of those that are currently considered compatible in Rust. For the most part, this documentation is not adding any new guarantees, only describing the existing state of compatibility.</p>
<p>The one new addition is that it is now guaranteed that <code>char</code> and <code>u32</code> are ABI compatible. They have always had the same size and alignment, but now they are considered equivalent even in function call ABI, consistent with the documentation above.</p>
<h4><a class="anchor" href="https://blog.rust-lang.org/2024/02/08/Rust-1.76.0.html#type-names-from-references" id="type-names-from-references"></a>Type names from references</h4>
<p>For debugging purposes, <a href="https://doc.rust-lang.org/stable/std/any/fn.type_name.html"><code>any::type_name::<T>()</code></a> has been available since Rust 1.38 to return a string description of the type <code>T</code>, but that requires an explicit type parameter. It is not always easy to specify that type, especially for unnameable types like closures or for opaque return types. The new <a href="https://doc.rust-lang.org/stable/std/any/fn.type_name_of_val.html"><code>any::type_name_of_val(&T)</code></a> offers a way to get a descriptive name from any reference to a type.</p>
<pre><code class="language-rust">fn get_iter() -> impl Iterator<Item = i32> {
[1, 2, 3].into_iter()
}
fn main() {
let iter = get_iter();
let iter_name = std::any::type_name_of_val(&iter);
let sum: i32 = iter.sum();
println!("The sum of the `{iter_name}` is {sum}.");
}
</code></pre>
<p>This currently prints:</p>
<pre><code class="language-text">The sum of the `core::array::iter::IntoIter<i32, 3>` is 6.
</code></pre>
<h4><a class="anchor" href="https://blog.rust-lang.org/2024/02/08/Rust-1.76.0.html#stabilized-apis" id="stabilized-apis"></a>Stabilized APIs</h4>
<ul>
<li><a href="https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.unwrap_or_clone"><code>Arc::unwrap_or_clone</code></a></li>
<li><a href="https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.unwrap_or_clone"><code>Rc::unwrap_or_clone</code></a></li>
<li><a href="https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.inspect"><code>Result::inspect</code></a></li>
<li><a href="https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.inspect_err"><code>Result::inspect_err</code></a></li>
<li><a href="https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.inspect"><code>Option::inspect</code></a></li>
<li><a href="https://doc.rust-lang.org/stable/std/any/fn.type_name_of_val.html"><code>type_name_of_val</code></a></li>
<li><a href="https://doc.rust-lang.org/stable/std/hash/index.html#structs"><code>std::hash::{DefaultHasher, RandomState}</code></a>
These were previously available only through <code>std::collections::hash_map</code>.</li>
<li><a href="https://doc.rust-lang.org/stable/std/ptr/fn.from_ref.html"><code>ptr::{from_ref, from_mut}</code></a></li>
<li><a href="https://doc.rust-lang.org/stable/std/ptr/fn.addr_eq.html"><code>ptr::addr_eq</code></a></li>
</ul>
<h4><a class="anchor" href="https://blog.rust-lang.org/2024/02/08/Rust-1.76.0.html#other-changes" id="other-changes"></a>Other changes</h4>
<p>Check out everything that changed in <a href="https://github.com/rust-lang/rust/releases/tag/1.76.0">Rust</a>, <a href="https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-176-2024-02-08">Cargo</a>, and <a href="https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-176">Clippy</a>.</p>
<h3><a class="anchor" href="https://blog.rust-lang.org/2024/02/08/Rust-1.76.0.html#contributors-to-1760" id="contributors-to-1760"></a>Contributors to 1.76.0</h3>
<p>Many people came together to create Rust 1.76.0. We couldn't have done it without all of you. <a href="https://thanks.rust-lang.org/rust/1.76.0/">Thanks!</a></p>2024-02-08T00:00:00+00:00The Rust Release TeamMozilla Localization (L10N): A Deep Dive Into the Evolution of Pretranslation in Pontoon
https://blog.mozilla.org/l10n/2024/02/07/a-deep-dive-into-the-evolution-of-pretranslation-in-pontoon/
<p>Quite often, an imperfect translation is better than no translation. So why even publish untranslated content when high-quality machine translation systems are fast and affordable? Why not immediately machine-translate content and progressively ship enhancements as they are submitted by human translators?</p>
<p>At Mozilla, we call this process <i>pretranslation</i>. We began implementing it in Pontoon before COVID-19 hit, thanks to <a href="https://www.linkedin.com/in/vishalol/">Vishal</a> who landed the first patches. Then we caught some headwinds and didn’t make much progress until 2022 after receiving a significant development boost and finally launched it for the general audience in September 2023.</p>
<p>So far, 20 of our localization teams (locales) have opted to use pretranslation across 15 different localization projects. Over 20,000 pretranslations have been submitted and none of the teams have opted out of using it. These efforts have resulted in a higher translation completion rate, which was one of our main goals.</p>
<p>In this article, we’ll take a look at how we developed pretranslation in Pontoon. Let’s start by exploring how it actually works.</p>
<h3>How does pretranslation work?</h3>
<p>Pretranslation is enabled upon a team’s request (it’s off by default). When a new string is added to a project, it gets automatically pretranslated using a 100% match from translation memory (TM), which also includes translations of glossary entries. If a perfect match doesn’t exist, a locale-specific machine translation (MT) engine is used, trained on the locale’s translation memory.</p>
<div class="wp-caption alignnone" id="attachment_1656" style="width: 2052px;"><a href="https://blog.mozilla.org/l10n/files/2024/02/Screenshot-2024-01-31-at-20.35.08.png"><img alt="Pretranslation opt-in form" class="wp-image-1656 size-full" height="2266" src="https://blog.mozilla.org/l10n/files/2024/02/Screenshot-2024-01-31-at-20.35.08.png" width="2042" /></a><p class="wp-caption-text" id="caption-attachment-1656"><i>Pretranslation </i><a href="https://pontoon.mozilla.org/sl/"><i>opt-in form</i></a><i>.</i></p></div>
<p>After pretranslations are retrieved and saved in Pontoon, they get synced to our primary localization storage (usually a GitHub repository) and hence immediately made available for shipping. Unless they fail our quality checks. In that case, they don’t propagate to repositories until errors or warnings are fixed during the review process.</p>
<p>Until reviewed, pretranslations are visually distinguishable from user-submitted suggestions and translations. This makes post-editing much easier and more efficient. Another key factor that influences pretranslation review time is, of course, the quality of pretranslations. So let’s see how we picked our machine translation provider.</p>
<h3>Choosing a machine translation engine</h3>
<p>We selected the machine translation provider based on two primary factors: quality of translations and the number of supported locales. To make translations match the required terminology and style as much as possible, we were also looking for the ability to fine-tune the MT engine by training it on our translation data.</p>
<p>In March 2022, we compared Bergamot, Google’s Cloud Translation API (generic), and Google’s AutoML Translation (with custom models). Using these services we translated a collection of 1,000 strings into 5 locales (it, de, es-ES, ru, pt-BR), and used automated scores (<a href="https://en.wikipedia.org/wiki/BLEU">BLEU</a>, <a href="https://github.com/m-popovic/chrF">chrF++</a>) as well as manual evaluation to compare them with the actual translations.</p>
<div class="wp-caption alignnone" id="attachment_1658" style="width: 1788px;"><a href="https://blog.mozilla.org/l10n/files/2024/02/performance.png"><img alt="Performance of tested MT engines for Italian (it)." class="wp-image-1658 size-full" height="1056" src="https://blog.mozilla.org/l10n/files/2024/02/performance.png" width="1778" /></a><p class="wp-caption-text" id="caption-attachment-1658"><i>Performance of tested MT engines for Italian (it).</i></p></div>
<p>Google’s AutoML Translation outperformed the other two candidates in virtually all tested scenarios and metrics, so it became the clear choice. It supports over 60 locales. Google’s Generic Translation API supports twice as many, but we currently don’t plan to use it for pretranslation in locales not supported by Google’s AutoML Translation.</p>
<h3>Making machine translation actually work</h3>
<p>Currently, around 50% of pretranslations generated by Google’s AutoML Translation get approved without any changes. For some locales, the rate is around 70%. Keep in mind however that machine translation is only used when a perfect translation memory match isn’t available. For pretranslations coming from translation memory, the approval rate is 90%.</p>
<div class="wp-caption alignnone" id="attachment_1657" style="width: 1970px;"><a href="https://blog.mozilla.org/l10n/files/2024/02/Posnetek-zaslona-2024-01-31-ob-20.29.29.png"><img alt="Comparison of pretranslation approval rate between teams." class="wp-image-1657 size-full" height="910" src="https://blog.mozilla.org/l10n/files/2024/02/Posnetek-zaslona-2024-01-31-ob-20.29.29.png" width="1960" /></a><p class="wp-caption-text" id="caption-attachment-1657"><i>Comparison of </i><a href="https://pontoon.mozilla.org/insights/"><i>pretranslation approval rate</i></a><i> between teams.</i></p></div>
<p>To reach that approval rate, we had to make a series of adjustments to the way we use machine translation.</p>
<p>For example, we convert multiline messages to single-line messages before machine-translating them. Otherwise, each line is treated as a separate message and the resulting translation is of poor quality.</p>
<p><i>Multiline message:</i><br />
<code></code></p>
<pre style="background: #dfdfdf; padding: 15px; border-radius: 10px;">Make this password unique and different from any others you use.
A good strategy to follow is to combine two or more unrelated
words to create an entire pass phrase, and include numbers and symbols.</pre>
<p><i>Multiline message converted to a single-line message:</i><br />
<code></code></p>
<p style="background: #dfdfdf; padding: 15px; border-radius: 10px;">Make this password unique and different from any others you use. A good strategy to follow is to combine two or more unrelated words to create an entire pass phrase, and include numbers and symbols.</p>
<p>Let’s take a closer look at two of the more time-consuming changes.</p>
<p>The first one is specific to our machine translation provider (Google’s AutoML Translation). During initial testing, we noticed it would often take a long time for the MT engine to return results, up to a minute. Sometimes it even timed out! Such a long response time not only slows down pretranslation, it also makes machine translation suggestions in the translation editor less useful – by the time they appear, the localizer has already moved to translate the next string.</p>
<p>After further testing, we began to suspect that our custom engine shuts down after a period of inactivity, thus requiring a cold start for the next request. We contacted support and our assumption was confirmed. To overcome the problem, we were advised to send a dummy query to the service every 60 seconds just to keep the system alive.</p>
<div class="wp-caption aligncenter" id="attachment_1655" style="width: 280px;"><a href="https://blog.mozilla.org/l10n/files/2024/02/giphy.gif"><img alt="Giphy: Oh No Wow GIF by Little Princess Ember" class="wp-image-1655 size-full" height="480" src="https://blog.mozilla.org/l10n/files/2024/02/giphy.gif" width="270" /></a><p class="wp-caption-text" id="caption-attachment-1655">Image source: <a href="https://giphy.com/gifs/xQyL1JfcCjGu3hUm1A">Giphy</a>.</p></div>
<p>Of course, it’s reasonable to shut down inactive services to free up resources, but the way to keep them alive isn’t. We have to make (paid) requests to each locale’s machine translation engines every minute just to make sure they work when we need them. And sometimes even that doesn’t help – we still see about a dozen <i>ServiceUnavailable</i> errors every day. It would be so much easier if we could just customize the default inactivity period or pay extra for an always-on service.</p>
<p>The other issue we had to address is quite common in machine translation systems: they are not particularly good at <a href="https://issuetracker.google.com/issues/119256504?pli=1">preserving placeholders</a>. In particular, extra space often gets added to variables or markup elements, resulting in broken translations.</p>
<p><i>Message with variables:</i></p>
<pre style="background: #dfdfdf; padding: 15px; border-radius: 10px;">{ $partialSize } of { $totalSize }</pre>
<p><i>Message with variables machine-translated to Slovenian (adding space after $ breaks the variable):</i></p>
<pre style="background: #dfdfdf; padding: 15px; border-radius: 10px;">{$ partialSize} od {$ totalSize}</pre>
<p>We tried to mitigate this issue by wrapping placeholders in <span translate=”no”>…</span>, which tells Google’s AutoML Translation to <a href="https://cloud.google.com/translate/troubleshooting">not translate the wrapped text</a>. This approach requires the source text to be submitted as HTML (rather than plain text), which triggers a whole new set of issues — from adding spaces in other places to escaping quotes — and we couldn’t circumvent those either. So this was a dead-end.</p>
<p>The solution was to store every placeholder in the <a href="https://cloud.google.com/translate/docs/advanced/glossary">Glossary</a> with the same value for both source string and translation. That approach worked much better and we still use it today. It’s not perfect, though, so we only use it to pretranslate strings for which the default (non-glossary) machine translation output fails our placeholder quality checks.</p>
<h3>Making pretranslation work with Fluent messages</h3>
<p>On top of the machine translation service improvements we also had to account for the complexity of Fluent messages, which are used by most of the projects we localize at Mozilla. <a href="https://projectfluent.org/">Fluent</a> is capable of expressing virtually any imaginable message, which means it is the localization system you want to use if you want your software translations to sound natural.</p>
<p>As a consequence, Fluent message format comes with a syntax that allows for expressing such complex messages. And since machine translation systems (as seen above) already have trouble with simple variables and markup elements, their struggles multiply with messages like this:<br />
<code></code></p>
<pre style="background: #dfdfdf; padding: 15px; border-radius: 10px;">shared-photos =
{ $photoCount ->
[one]
{ $userGender ->
[male] { $userName } added a new photo to his stream.
[female] { $userName } added a new photo to her stream.
*[other] { $userName } added a new photo to their stream.
}
*[other]
{ $userGender ->
[male] { $userName } added { $photoCount } new photos to his stream.
[female] { $userName } added { $photoCount } new photos to her stream.
*[other] { $userName } added { $photoCount } new photos to their stream.
}
}</pre>
<p>That means Fluent messages need to be pre-processed before they are sent to the pretranslation systems. Only relevant parts of the message need to be pretranslated, while syntax elements need to remain untouched. In the example above, we extract the following message parts, pretranslate them, and replace them with pretranslations in the original message:</p>
<ul>
<li><i>{ $userName } added a new photo to his stream.</i></li>
<li><i>{ $userName } added a new photo to her stream.</i></li>
<li><i>{ $userName } added a new photo to their stream.</i></li>
<li><i>{ $userName } added { $photoCount } new photos to his stream.</i></li>
<li><i>{ $userName } added { $photoCount } new photos to her stream.</i></li>
<li><i>{ $userName } added { $photoCount } new photos to their stream.</i></li>
</ul>
<p>To be more accurate, this is what happens for languages like German, which uses the same <a href="https://cldr.unicode.org/index/cldr-spec/plural-rules">CLDR plural forms</a> as English. For locales without plurals, like Chinese, we drop plural forms completely and only pretranslate the remaining three parts. If the target language is Slovenian, two additional plural forms need to be added (two, few), which in this example results in a total of 12 messages needing pretranslation (four plural forms, with three gender forms each).</p>
<p>Finally, Pontoon translation editor uses <a href="https://pontoon.mozilla.org/sl/firefox/all-resources/?string=192297">custom UI for translating access keys</a>. That means it’s capable of detecting which part of the message is an access key and which is a label the access key belongs to. The access key should ideally be one of the characters included in the label, so the editor generates a list of candidates that translators can choose from. In pretranslation, the first candidate is directly used as an access key, so no TM or MT is involved.</p>
<div class="wp-caption aligncenter" id="attachment_1654" style="width: 526px;"><a href="https://blog.mozilla.org/l10n/files/2024/02/inter-keyboard-image3.png"><img alt="A screenshot of Notepad showing access keys in the menu." class="wp-image-1654 size-full" height="319" src="https://blog.mozilla.org/l10n/files/2024/02/inter-keyboard-image3.png" width="516" /></a><p class="wp-caption-text" id="caption-attachment-1654"><i>Access keys (not to be confused with shortcut keys) are used for accessibility to interact with all controls or menu items using the keyboard. Windows indicates access keys by underlining the access key assignment when the Alt key is pressed. Source: </i><a href="https://learn.microsoft.com/en-us/windows/win32/uxguide/inter-keyboard"><i>Microsoft Learn</i></a><i>.</i></p></div>
<h3>Looking ahead</h3>
<p>With every enhancement we shipped, the case for publishing untranslated text instead of pretranslations became weaker and weaker. And there’s still room for improvements in our pretranslation system.</p>
<p><a href="https://www.linkedin.com/in/ayanaa-rahman/">Ayanaa</a> has done extensive research on the impact of Large Language Models (LLMs) on translation efficiency. She’s now working on integrating LLM-assisted translations into Pontoon’s Machinery panel, from which localizers will be able to request alternative translations, including formal and informal options.</p>
<p>If the target locale could set the tone to formal or informal on the project level, we could benefit from this capability in pretranslation as well. We might also improve the quality of machine translation suggestions by providing existing translations into other locales as references in addition to the source string.</p>
<p>If you are interested in using pretranslation or already use it, we’d love to hear your thoughts! Please leave a comment, reach out to us on <a href="https://chat.mozilla.org/#/room/#pontoon:mozilla.org">Matrix</a>, or <a href="https://github.com/mozilla/pontoon/issues">file an issue</a>.</p>2024-02-07T10:55:23+00:00Matjaž HorvatFirefox Nightly: A Preview of Tab Previews – These Weeks in Firefox: Issue 153
https://blog.nightly.mozilla.org/2024/02/06/a-preview-of-tab-previews-these-weeks-in-firefox-issue-153/
<h3 dir="ltr" id="m_-438439088843320476m_140113856401291886gmail-docs-internal-guid-4276a0d3-7fff-4b15-1315-59ffd8e3e151">Highlights</h3>
<ul>
<li>
<p>Tab Previews! Congratulations to DJ for getting these landed. Currently disabled by default, but you can test them by setting `browser.tabs.cardPreview.enabled` to true</p>
</li>
</ul>
<p><img alt="A tab preview showing the page contents of another background tab" class="aligncenter size-full wp-image-1541" height="600" src="https://blog.nightly.mozilla.org/files/2024/01/image4.png" width="1074" /></p>
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1869928" rel="noopener" target="_blank">sfoster landed a patch</a> that improves the performance of restoring many tabs all at once, especially on older machines</li>
<li><a href="https://blog.mozilla.org/l10n/2024/01/18/advancing-mozillas-mission-through-our-work-on-localization-standards/" rel="noopener" target="_blank">Here’s a great blog post</a> from the Localization team on how they’re working to advance Mozilla’s mission through localization standards</li>
<li>Irene fixed a bunch of bugs on Reader Mode: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1589007" rel="noopener" target="_blank">disabled Slack in Reader View</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1852366" rel="noopener" target="_blank">made images easier on the eyes in the dark theme</a>, and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1795317" rel="noopener" target="_blank">updated the formatting of reading time</a></li>
</ul>
<div class="wp-caption aligncenter" id="attachment_1544" style="width: 725px;"><img alt="A comparison showing increased contrast and lower brightness for images displayed in dark theme Reader Mode" class="size-full wp-image-1544" height="247" src="https://blog.nightly.mozilla.org/files/2024/01/image1.png" width="715" /><p class="wp-caption-text" id="caption-attachment-1544">Increased contrast and reduced brightness make images easier on the eyes (right: old changes, left: new changes)</p></div>
<h3 dir="ltr">Friends of the Firefox team</h3>
<h4 dir="ltr"><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20%28excluding%20employees%29&quicksearch=1869574%2C1806255%2C1864447%2C1837747%2C1842804%2C1872922%2C1724089&list_id=16869353" rel="noopener" target="_blank">Resolved bugs (excluding employees)</a></h4>
<p dir="ltr"><a href="https://github.com/niklasbaumgardner/NewContributorScraper" rel="noopener" target="_blank">Script to find new contributors from bug list</a></p>
<h4 dir="ltr">Volunteers that fixed more than one bug</h4>
<ul>
<li dir="ltr">
<p dir="ltr">Gregory Pappas [:gregp]</p>
</li>
</ul>
<h4 dir="ltr">New contributors (🌟 = first patch)</h4>
<ul>
<li dir="ltr">🌟 creweclinton <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1864447" rel="noopener" target="_blank">updated privacy notice</a> URL in DiscoveryStreamFeed.jsm</li>
<li dir="ltr">mattheww <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1842804" rel="noopener" target="_blank">added a fix to update lang attribute</a> after translating page</li>
<li dir="ltr">🌟 toe_head2001 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1872457" rel="noopener" target="_blank">improved performance</a> of HTMLSelectElement::RemoveOptionsFromList</li>
</ul>
<h3 dir="ltr">Project Updates</h3>
<h4 dir="ltr">Add-ons / Web Extensions</h4>
<h5 dir="ltr">Addon Manager & about:addons</h5>
<ul>
<li dir="ltr">Thanks to Anna Yeddi, a missing label to the remove shortcut icon from the extensions shortcuts management view part of the about:addons page has been identified and added. Another accessibility issue caught by the a11y jobs 🥳 – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873304" rel="noopener" target="_blank">Bug 1873304</a></li>
</ul>
<h5 dir="ltr">WebExtensions Framework</h5>
<ul>
<li dir="ltr">As part of follow ups to the work on the new taskcluster jobs to run webextensions tp6 and tp6m perftests jobs (landed as tier-3 jobs as part of <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1859549" rel="noopener" target="_blank">Bug 1859549</a> in December):
<ul>
<li dir="ltr">A new linter named condprof-addons has been landed, this new linter makes sure that xpi files referenced in condprof customization files and the firefox-addons.tar archive (fetched through the related CI fetch task) are not going out of sync with each other – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1868144" rel="noopener" target="_blank">Bug 1868144</a>
<ul>
<li dir="ltr">The condprof-addons linter is documented <a href="https://firefox-source-docs.mozilla.org/code-quality/lint/linters/condprof-addons.html" rel="noopener" target="_blank">here</a></li>
<li dir="ltr">Thanks to ahal and sparky for their help and support on introducing this new linter</li>
</ul>
</li>
<li dir="ltr">A new doc section has been added to the Raptor Browsertime doc page, to briefly provide a description of the webextensions tp6/tp6m perftests jobs and examples for how to run these tests locally and in try pushes – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874487" rel="noopener" target="_blank">Bug 1874487</a>
<ul>
<li dir="ltr">The new section is already available <a href="https://firefox-source-docs.mozilla.org/testing/perfdocs/browsertime.html#running-page-load-tests-with-third-party-webextensions" rel="noopener" target="_blank">here</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 dir="ltr">Developer Tools</h4>
<h5 dir="ltr">DevTools</h5>
<ul>
<li dir="ltr">Alex added a notice at the bottom of the Debugger editor when the source map file is invalid or unavailable (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1834725" rel="noopener" target="_blank">bug</a>)</li>
</ul>
<p><img alt="Notification about a Source Map Error due to an unexpected non-whitespace character" class="aligncenter size-full wp-image-1543" height="320" src="https://blog.nightly.mozilla.org/files/2024/01/image2.png" width="937" /></p>
<ul>
<li dir="ltr">Hubert delayed getting information about sources functions until we need to display them, which made opening files faster (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1859531" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Hubert fixed an issue where the Debugger would crash (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874382" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Alex added options to the console :trace command limit depth and number of top level frames being traced (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870801" rel="noopener" target="_blank">bug</a>)
<ul>
<li dir="ltr">(still behind devtools.debugger.features.javascript-tracing)</li>
<li dir="ltr">:trace –max-depth N –max-records M</li>
</ul>
</li>
<li dir="ltr">Alex improved performance of the console when it’s receiving a very large number of messages (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874696" rel="noopener" target="_blank">bug</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873066" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Nicolas made Ctrl+Enter (Cmd+Enter on MacOS) on Rules view input advance the focus to the next editable property, i.e. like the Tab key (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873416" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Nicolas added a hint about the new Enter key behavior in Rules view input, linking to an <a href="https://fxdx.dev/rules-view-enter-key/" rel="noopener" target="_blank">explanatory blog post</a> (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1871806" rel="noopener" target="_blank">bug</a>)</li>
</ul>
<p><img alt="Notification explaining that Enter key no longer changes focus in Rules view" class="aligncenter size-full wp-image-1542" height="420" src="https://blog.nightly.mozilla.org/files/2024/01/image3.png" width="1069" /></p>
<h5 dir="ltr">WebDrive BiDi</h5>
<ul>
<li dir="ltr">Julian added support the the network.fetchError event, which is emitted when a request ends in an error state (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1790375" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Julian implemented the network.failRequets command, which forces an intercepted request to fail, and will fire a network.fetchError event (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1853883" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Sasha made script.evaluate, script.callFunction and script.disown ignore the realm argument when a context argument is passed (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873688" rel="noopener" target="_blank">bug</a>)</li>
<li dir="ltr">Henrik fixed an issue with the browsingContext.create command, aligning with Chrome for a consistent cross-browser experience (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875086" rel="noopener" target="_blank">bug</a>)</li>
</ul>
<h4 dir="ltr">ESMification status</h4>
<ul>
<li dir="ltr">Some changes landed after today’s numbers were generated (see new tab page section below) – that brings us to the 90% mark on browser/</li>
<li dir="ltr">ESMified status:
<ul>
<li dir="ltr">browser: 89%</li>
<li dir="ltr">toolkit: 99%</li>
<li dir="ltr">Total: 96.48% (no change)</li>
</ul>
</li>
<li dir="ltr">#esmification on Matrix</li>
</ul>
<h4 dir="ltr">Lint, Docs and Workflow</h4>
<ul>
<li dir="ltr">We have now added an ESLint rule <a href="https://groups.google.com/a/mozilla.org/g/firefox-dev/c/su0q77h4gM4/m/rV1WveEzAgAJ" rel="noopener" target="_blank">to reject new uses of Console.sys.mjs and Log.sys.mjs</a>.
<ul>
<li dir="ltr">We have three different module logging mechanisms available to our JavaScript code, and want to reduce those down to one.</li>
<li dir="ltr">For new code please use <a href="https://firefox-source-docs.mozilla.org/toolkit/javascript-logging.html#logging-using-the-console-web-api" rel="noopener" target="_blank">console.createInstance</a>.</li>
<li dir="ltr">We will start with the migration away from Console.sys.mjs as that is closest to console.createInstance, and will look at Log.sys.mjs later. However, if teams want to investigate moving away sooner, and find issues, please file bugs blocking the appropriate metas (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1430810" rel="noopener" target="_blank">Console.sys.mjs</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1828156" rel="noopener" target="_blank">Log.sys.mjs</a>)</li>
</ul>
</li>
<li dir="ltr">The license linter has been fixed to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1568873" rel="noopener" target="_blank">not report an error when it has successfully fixed a file</a>. It will also now <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874607" rel="noopener" target="_blank">automatically fix .mjs files</a>.</li>
<li dir="ltr"><a href="https://groups.google.com/a/mozilla.org/g/firefox-dev/c/pVESEgi4vpo/m/wStFqqRHAgAJ" rel="noopener" target="_blank">XPCOMUtils.defineLazyGetter has now been replaced by ChromeUtils.defineLazyGetter</a>. An ESLint rule has also been added to reject uses of the former.</li>
<li dir="ltr">The whitespace and file permission linters <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874828" rel="noopener" target="_blank">now run on .mn files</a> (e.g. <a href="http://jar.mn" rel="noopener" target="_blank">jar.mn</a>).</li>
<li dir="ltr">ESlint has <a href="https://eslint.org/docs/latest/rules/no-return-await" rel="noopener" target="_blank">deprecated the no-return-await rule</a>. We have therefore <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875027" rel="noopener" target="_blank">stopped enforcing it on mozilla-central</a>.</li>
</ul>
<h4 dir="ltr">Migration Improvements</h4>
<ul>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1875112" rel="noopener" target="_blank">The next wave of spotlight messages</a> to encourage users without accounts to create one to aid in device migration should be going out in a week or so.</li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1869060" rel="noopener" target="_blank">The infrastructure</a> that allows for doing backups of active SQLite databases has landed. We’re hoping this can be part of the foundations for a backup-to-local-file utility.</li>
</ul>
<h4 dir="ltr">New Tab Page</h4>
<ul>
<li dir="ltr"><a href="https://groups.google.com/a/mozilla.org/g/governance/c/evhTIa_f8zw" rel="noopener" target="_blank">Mardak sent a message</a> to the governance mailing list with some proposed updates on ownership for New Tab, Onboarding and In Product Messaging</li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1868838" rel="noopener" target="_blank">A bunch of patches are up for review</a> to move the majority of ASRouter out from the newtab codebase</li>
<li dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1868194" rel="noopener" target="_blank">TelemetryFeed.jsm</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873969" rel="noopener" target="_blank">HighlightsFeed.jsm</a> have now been converted to ESMs. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874276" rel="noopener" target="_blank">PlacesFeed.jsm</a> is next, and that’ll unblock ESMifying a lot of the other modules under the newtab folder.</li>
</ul>
<h4 dir="ltr">Picture-in-Picture</h4>
<ul>
<li dir="ltr">
<p dir="ltr">emilio landed some patches that fix a regression with kde/wayland window rules for the PiP window not working as intended (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874766" rel="noopener" target="_blank">bug</a>)</p>
</li>
</ul>
<h4 dir="ltr">Performance</h4>
<ul>
<li dir="ltr">
<p dir="ltr"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1649696#c23" rel="noopener" target="_blank">We’re seeing a nice boost in performance</a> on Linux due to a change that disabled some Spectre / Meltdown mitigations, now that Fission has shipped.</p>
</li>
</ul>
<h4 dir="ltr">Reader Mode</h4>
<ul>
<li dir="ltr">
<p dir="ltr">Fred landed a patch to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1871140" rel="noopener" target="_blank">vendor the Readability library</a>, making it a lot easier to update</p>
</li>
</ul>
<h4 dir="ltr">Search and Navigation</h4>
<ul>
<li dir="ltr">On top of ongoing projects, the search team collectively worked on closing as many “Dragon Slayer” bugs (small story point effort bugs) over the last two weeks, which included fixing visual and functional errors in the address bar, updating documentation, adding additional test coverage, and addressing tech debt. One such bug:
<ul>
<li dir="ltr">:mcheang made a change<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1667639" rel="noopener" target="_blank"> where initiating a keyword search and ending it with a question mark</a> no longer switches the search back to the default search engine. This could be helpful for users who use keyword queries to shortcut usage of chatbots as queries can naturally end with a question mark.</li>
</ul>
</li>
<li dir="ltr">mseibert<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1858994" rel="noopener" target="_blank"> enabled the ability for the address bar to display a URL with special characters in the heuristic result</a> (e.g. <a href="https://xn--d1aholi.xn--90a3ac/" rel="noopener" target="_blank">https://рнидс.срб/</a>) instead of showing the URL in its Punycode form.</li>
</ul>2024-02-06T16:58:54+00:00Katherine PatenioNick Fitzgerald: Garbage Collection Without Unsafe Code
http://fitzgeraldnick.com/2024/02/06/safe-gc.html
<p>Many people, including myself, have implemented garbage collection (GC)
libraries for Rust. Manish Goregaokar wrote up a <a href="https://manishearth.github.io/blog/2021/04/05/a-tour-of-safe-tracing-gc-designs-in-rust/">fantastic survey</a> of this
space a few years ago. These libraries aim to provide a safe API for their users
to consume: an <code>unsafe</code>-free interface which soundly encapsulates and hides the
library’s internal <code>unsafe</code> code. The one exception is their mechanism to
enumerate the outgoing GC edges of user-defined GC types, since failure to
enumerate all edges can lead the collector to believe that an object is
unreachable and collect it, despite the fact that the user still has a reference
to the reclaimed object, leading to use-after-free bugs.<sup id="fnref:edges"><a class="footnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fn:edges" rel="footnote">1</a></sup> This
functionality is generally exposed as an <code>unsafe</code> trait for the user to
implement because it is the user’s responsibility, not the library’s, to uphold
this particular critical safety invariant.</p>
<p>However, despite providing safe interfaces, all of these libraries make
extensive use of <code>unsafe</code> code in their internal implementations. I’ve always
believed it was possible to write a garbage collection library without any
<code>unsafe</code> code, and no one I’ve asserted this to has disagreed, but there has
never been a proof by construction.</p>
<p>So, finally, I created the <a href="https://github.com/fitzgen/safe-gc"><code>safe-gc</code></a> crate: a garbage collection library for
Rust with zero <code>unsafe</code> code. No <code>unsafe</code> in the API. No <code>unsafe</code> in the
implementation. It even has a <code>forbid(unsafe_code)</code> pragma at the top.</p>
<p>That said, <code>safe-gc</code> is not a particularly high-performance garbage collector.</p>
<h3 id="using-safe-gc">Using <code>safe-gc</code></h3>
<p>To use <code>safe-gc</code>, first we define our GC-managed types, using <code>Gc<T></code> to define
references to other GC-managed objects, and implement the <code>Trace</code> trait to
report each of those GC edges to the collector:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">use</span> <span class="nn">safe_gc</span><span class="p">::{</span><span class="n">Collector</span><span class="p">,</span> <span class="nb">Gc</span><span class="p">,</span> <span class="n">Trace</span><span class="p">};</span>
<span class="c1">// Define a GC-managed object.</span>
<span class="k">struct</span> <span class="n">List</span> <span class="p">{</span>
<span class="n">value</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="c1">// GC-managed references to the next and previous links in the list.</span>
<span class="n">prev</span><span class="p">:</span> <span class="nb">Option</span><span class="o"><</span><span class="nb">Gc</span><span class="o"><</span><span class="n">List</span><span class="o">>></span><span class="p">,</span>
<span class="n">next</span><span class="p">:</span> <span class="nb">Option</span><span class="o"><</span><span class="nb">Gc</span><span class="o"><</span><span class="n">List</span><span class="o">>></span><span class="p">,</span>
<span class="p">}</span>
<span class="c1">// Report GC edges to the collector.</span>
<span class="k">impl</span> <span class="n">Trace</span> <span class="k">for</span> <span class="n">List</span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">trace</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">collector</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="n">Collector</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">prev</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span><span class="py">.prev</span> <span class="p">{</span>
<span class="n">collector</span><span class="nf">.edge</span><span class="p">(</span><span class="n">prev</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">next</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span><span class="py">.next</span> <span class="p">{</span>
<span class="n">collector</span><span class="nf">.edge</span><span class="p">(</span><span class="n">next</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>This looks pretty similar to other GC libraries in Rust, although it could
definitely benefit from an implementation of <code>Trace</code> for <code>Option<T></code> and a
<code>derive(Trace)</code> macro. The big difference from existing GC libraries is that
<code>Trace</code> is safe to implement; more on this later.</p>
<p>Next, we create one or more <code>Heap</code>s to allocate our objects within. Each heap is
independently garbage collected.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">use</span> <span class="nn">safe_gc</span><span class="p">::</span><span class="n">Heap</span><span class="p">;</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">heap</span> <span class="o">=</span> <span class="nn">Heap</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span></code></pre></figure>
<p>And with a <code>Heap</code> in hand, we can allocate objects:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">let</span> <span class="n">a</span> <span class="o">=</span> <span class="n">heap</span><span class="nf">.alloc</span><span class="p">(</span><span class="n">List</span> <span class="p">{</span>
<span class="n">value</span><span class="p">:</span> <span class="mi">42</span><span class="p">,</span>
<span class="n">prev</span><span class="p">:</span> <span class="nb">None</span><span class="p">,</span>
<span class="n">next</span><span class="p">:</span> <span class="nb">None</span><span class="p">,</span>
<span class="p">});</span>
<span class="k">let</span> <span class="n">b</span> <span class="o">=</span> <span class="n">heap</span><span class="nf">.alloc</span><span class="p">(</span><span class="n">List</span> <span class="p">{</span>
<span class="n">value</span><span class="p">:</span> <span class="mi">36</span><span class="p">,</span>
<span class="n">prev</span><span class="p">:</span> <span class="nf">Some</span><span class="p">(</span><span class="n">a</span><span class="nf">.into</span><span class="p">()),</span>
<span class="n">next</span><span class="p">:</span> <span class="nb">None</span><span class="p">,</span>
<span class="p">});</span>
<span class="c1">// Create a bunch of garbage! Who cares! It'll all be cleaned</span>
<span class="c1">// up eventually!</span>
<span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mi">0</span><span class="o">..</span><span class="mi">100</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">_</span> <span class="o">=</span> <span class="n">heap</span><span class="nf">.alloc</span><span class="p">(</span><span class="n">List</span> <span class="p">{</span>
<span class="n">value</span><span class="p">:</span> <span class="n">i</span><span class="p">,</span>
<span class="n">prev</span><span class="p">:</span> <span class="nb">None</span><span class="p">,</span>
<span class="n">next</span><span class="p">:</span> <span class="nb">None</span><span class="p">,</span>
<span class="p">});</span>
<span class="p">}</span></code></pre></figure>
<p>The heap will automatically trigger garbage collections, as necessary, but we
can also force a collection if we want:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="c1">// Force a garbage collection!</span>
<span class="n">heap</span><span class="nf">.gc</span><span class="p">()</span></code></pre></figure>
<p>Rather than deref’ing <code>Gc<T></code> pointers directly, we must index into the <code>Heap</code>
to access the referenced <code>T</code> object. This contrasts with other GC libraries and
is the key that unlocks <code>safe-gc</code>’s lack of <code>unsafe</code> code, allowing the
implementation to abide by Rust’s ownership and borrowing discipline.<sup id="fnref:gc-arena"><a class="footnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fn:gc-arena" rel="footnote">2</a></sup></p>
<figure class="highlight"><pre><code class="language-rust"><span class="c1">// Read from a GC object in the heap.</span>
<span class="k">let</span> <span class="n">b_value</span> <span class="o">=</span> <span class="n">heap</span><span class="p">[</span><span class="o">&</span><span class="n">b</span><span class="p">]</span><span class="py">.value</span><span class="p">;</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">b_value</span><span class="p">,</span> <span class="mi">36</span><span class="p">);</span>
<span class="c1">// Write to a GC object in the heap.</span>
<span class="n">heap</span><span class="p">[</span><span class="o">&</span><span class="n">b</span><span class="p">]</span><span class="py">.value</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">heap</span><span class="p">[</span><span class="o">&</span><span class="n">b</span><span class="p">]</span><span class="py">.value</span><span class="p">,</span> <span class="mi">37</span><span class="p">);</span></code></pre></figure>
<p>Finally, there are actually two types for indexing into <code>Heap</code>s to access GC
objects:</p>
<ol>
<li><code>Gc<T></code>, which we have seen already, and</li>
<li><code>Root<T></code>, which we have also seen in action, but which was hidden from us by
type inference.</li>
</ol>
<p>The <code>Gc<T></code> type is <code>Copy</code> and should be used when referencing other GC-managed
objects from within a GC-managed object’s type definition, or when you can prove
that a garbage collection will not happen (i.e. you have a shared borrow of its
heap). A <code>Gc<T></code> does <em>not</em> root its referenced <code>T</code>, keeping it alive across
garbage collections, and therefore <code>Gc<T></code> should not be used to hold onto GC
references across any operation that can trigger a garbage collection.</p>
<p>A <code>Root<T></code>, on the other hand, does indeed root its associated <code>T</code> object,
preventing the object from being reclaimed during garbage collection. This makes
<code>Root<T></code> suitable for holding references to GC-managed objects across
operations that can trigger garbage collections. <code>Root<T></code> is not <code>Copy</code> because
dropping it must remove its entry from the heap’s root set. Allocation returns
rooted references; all the <code>heap.alloc(...)</code> calls from our earlier examples
returned <code>Root<T></code>s.</p>
<h3 id="peeking-under-the-hood">Peeking Under the Hood</h3>
<p>A <code>safe_gc::Heap</code> is more similar to <a href="https://docs.rs/id-arena">an arena newtype over a
<code>Vec</code></a> than an engineered heap with hierarchies of
regions like
<a href="http://users.cecs.anu.edu.au/~steveb/pubs/papers/immix-pldi-2008.pdf">Immix</a>. Its
main storage is a hash map from <code>std::any::TypeId</code> to uniform arenas of the
associated type. This lets us ultimately use <code>Vec</code> as the storage for
heap-allocated objects, and we don’t need to do any unsafe pointer arithmetic or
worry about splitting large blocks in our free lists. In fact, the free lists
only manage indices, not blocks of raw memory.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">pub</span> <span class="k">struct</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="c1">// A map from `type_id(T)` to `Arena<T>`. The `ArenaObject`</span>
<span class="c1">// trait facilitates crossing the boundary from an untyped</span>
<span class="c1">// heap to typed arenas.</span>
<span class="n">arenas</span><span class="p">:</span> <span class="n">HashMap</span><span class="o"><</span><span class="n">TypeId</span><span class="p">,</span> <span class="nb">Box</span><span class="o"><</span><span class="k">dyn</span> <span class="n">ArenaObject</span><span class="o">>></span><span class="p">,</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="k">struct</span> <span class="n">Arena</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="n">elements</span><span class="p">:</span> <span class="n">FreeList</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">,</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="k">enum</span> <span class="n">FreeListEntry</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="cd">/// An occupied entry holding a `T`.</span>
<span class="nf">Occupied</span><span class="p">(</span><span class="n">T</span><span class="p">),</span>
<span class="cd">/// A free entry that is also part of a linked list</span>
<span class="cd">/// pointing to the next free entry, if any.</span>
<span class="nf">Free</span><span class="p">(</span><span class="nb">Option</span><span class="o"><</span><span class="nb">u32</span><span class="o">></span><span class="p">),</span>
<span class="p">}</span>
<span class="k">struct</span> <span class="n">FreeList</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="c1">// The actual backing storage for our `T`s.</span>
<span class="n">entries</span><span class="p">:</span> <span class="nb">Vec</span><span class="o"><</span><span class="n">FreeListEntry</span><span class="o"><</span><span class="n">T</span><span class="o">>></span><span class="p">,</span>
<span class="cd">/// The index of the first free entry in the free list.</span>
<span class="n">free</span><span class="p">:</span> <span class="nb">Option</span><span class="o"><</span><span class="nb">u32</span><span class="o">></span><span class="p">,</span>
<span class="c1">// ...</span>
<span class="p">}</span></code></pre></figure>
<p>To allocate a new <code>T</code> in the heap, we first get the <code>T</code> object arena out of the
heap’s hash map, or create it if it doesn’t exist yet. Then, we check if the
arena has capacity to allocate our new <code>T</code>. If it does, we push the object onto
the arena and return a rooted reference. If it does not, we fall back to an
out-of-line slow path where we trigger a garbage collection to ensure that we
have space for the new object, and then try again.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="nd">#[inline]</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="n">alloc</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="k">-></span> <span class="n">Root</span><span class="o"><</span><span class="n">T</span><span class="o">></span>
<span class="k">where</span>
<span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="p">,</span>
<span class="p">{</span>
<span class="k">let</span> <span class="n">heap_id</span> <span class="o">=</span> <span class="k">self</span><span class="py">.id</span><span class="p">;</span>
<span class="k">let</span> <span class="n">arena</span> <span class="o">=</span> <span class="k">self</span><span class="py">.ensure_arena</span><span class="p">::</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">();</span>
<span class="c1">// Fast path for when we have available capacity for</span>
<span class="c1">// allocating into.</span>
<span class="k">match</span> <span class="n">arena</span><span class="nf">.try_alloc</span><span class="p">(</span><span class="n">heap_id</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">Ok</span><span class="p">(</span><span class="n">root</span><span class="p">)</span> <span class="k">=></span> <span class="n">root</span><span class="p">,</span>
<span class="nf">Err</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">=></span> <span class="k">self</span><span class="nf">.alloc_slow</span><span class="p">(</span><span class="n">value</span><span class="p">),</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// Out-of-line slow path for when we need to GC to free</span>
<span class="c1">// up or allocate additional space.</span>
<span class="nd">#[inline(never)]</span>
<span class="k">fn</span> <span class="n">alloc_slow</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="k">-></span> <span class="n">Root</span><span class="o"><</span><span class="n">T</span><span class="o">></span>
<span class="k">where</span>
<span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="p">,</span>
<span class="p">{</span>
<span class="k">self</span><span class="nf">.gc</span><span class="p">();</span>
<span class="k">let</span> <span class="n">heap_id</span> <span class="o">=</span> <span class="k">self</span><span class="py">.id</span><span class="p">;</span>
<span class="k">let</span> <span class="n">arena</span> <span class="o">=</span> <span class="k">self</span><span class="py">.ensure_arena</span><span class="p">::</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">();</span>
<span class="n">arena</span><span class="nf">.alloc_slow</span><span class="p">(</span><span class="n">heap_id</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p><code>Arena<T></code> allocation bottoms out in allocating from a <code>FreeList<T></code>, which will
attempt to use existing capacity by popping off its internal list of empty
entries when possible, or otherwise fall back to reserving additional capacity.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="n">FreeList</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">try_alloc</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="k">-></span> <span class="nb">Result</span><span class="o"><</span><span class="nb">u32</span><span class="p">,</span> <span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">index</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span><span class="py">.free</span> <span class="p">{</span>
<span class="c1">// We have capacity. Pop the first free entry off</span>
<span class="c1">// the free list and put the value in there.</span>
<span class="k">let</span> <span class="n">index</span> <span class="o">=</span> <span class="nn">usize</span><span class="p">::</span><span class="nf">try_from</span><span class="p">(</span><span class="n">index</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="k">let</span> <span class="n">next_free</span> <span class="o">=</span> <span class="k">match</span> <span class="k">self</span><span class="py">.entries</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">{</span>
<span class="nn">Entry</span><span class="p">::</span><span class="nf">Free</span><span class="p">(</span><span class="n">next_free</span><span class="p">)</span> <span class="k">=></span> <span class="n">next_free</span><span class="p">,</span>
<span class="nn">Entry</span><span class="p">::</span><span class="n">Occupied</span> <span class="p">{</span> <span class="o">..</span> <span class="p">}</span> <span class="k">=></span> <span class="nd">unreachable!</span><span class="p">(),</span>
<span class="p">};</span>
<span class="k">self</span><span class="py">.free</span> <span class="o">=</span> <span class="n">next_free</span><span class="p">;</span>
<span class="k">self</span><span class="py">.entries</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="nn">Entry</span><span class="p">::</span><span class="nf">Occupied</span><span class="p">(</span><span class="n">value</span><span class="p">);</span>
<span class="nf">Ok</span><span class="p">(</span><span class="n">index</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="c1">// No capacity to hold the value; give it back.</span>
<span class="nf">Err</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="nf">alloc</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="k">-></span> <span class="nb">u32</span> <span class="p">{</span>
<span class="k">self</span><span class="nf">.try_alloc</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="nf">.unwrap_or_else</span><span class="p">(|</span><span class="n">value</span><span class="p">|</span> <span class="p">{</span>
<span class="c1">// Reserve additional capacity, since we didn't have</span>
<span class="c1">// space for the allocation.</span>
<span class="k">self</span><span class="nf">.double_capacity</span><span class="p">();</span>
<span class="c1">// After which the allocation will succeed.</span>
<span class="k">self</span><span class="nf">.try_alloc</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="nf">.ok</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">()</span>
<span class="p">})</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Accessing objects in the heap is straightforward: look up the arena for <code>T</code> and
index into it.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="cd">/// Get a shared borrow of the referenced `T`.</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="n">get</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">gc</span><span class="p">:</span> <span class="k">impl</span> <span class="nb">Into</span><span class="o"><</span><span class="nb">Gc</span><span class="o"><</span><span class="n">T</span><span class="o">>></span><span class="p">)</span> <span class="k">-></span> <span class="o">&</span><span class="n">T</span>
<span class="k">where</span>
<span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="p">,</span>
<span class="p">{</span>
<span class="k">let</span> <span class="n">gc</span> <span class="o">=</span> <span class="n">gc</span><span class="nf">.into</span><span class="p">();</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="k">self</span><span class="py">.id</span><span class="p">,</span> <span class="n">gc</span><span class="py">.heap_id</span><span class="p">);</span>
<span class="k">let</span> <span class="n">arena</span> <span class="o">=</span> <span class="k">self</span><span class="py">.arena</span><span class="p">::</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="n">arena</span><span class="py">.elements</span><span class="nf">.get</span><span class="p">(</span><span class="n">gc</span><span class="py">.index</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// Get an exclusive borrow of the referenced `T`.</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="n">get_mut</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">gc</span><span class="p">:</span> <span class="k">impl</span> <span class="nb">Into</span><span class="o"><</span><span class="nb">Gc</span><span class="o"><</span><span class="n">T</span><span class="o">>></span><span class="p">)</span> <span class="k">-></span> <span class="o">&</span><span class="k">mut</span> <span class="n">T</span>
<span class="k">where</span>
<span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="p">,</span>
<span class="p">{</span>
<span class="k">let</span> <span class="n">gc</span> <span class="o">=</span> <span class="n">gc</span><span class="nf">.into</span><span class="p">();</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="k">self</span><span class="py">.id</span><span class="p">,</span> <span class="n">gc</span><span class="py">.heap_id</span><span class="p">);</span>
<span class="k">let</span> <span class="n">arena</span> <span class="o">=</span> <span class="k">self</span><span class="py">.arena_mut</span><span class="p">::</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="n">arena</span><span class="py">.elements</span><span class="nf">.get_mut</span><span class="p">(</span><span class="n">gc</span><span class="py">.index</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Before we get into how <code>safe-gc</code> actually performs garbage collection, we need
to look at how it implements the root set. The root set are the set of things
that are definitely alive; things that the application is actively using right
now or planning to use in the future. The goal of the collector is to identify
all objects transitively referenced by these roots, since these are the objects
that can still be used in the future, and recycle all others.</p>
<p>Each <code>Arena<T></code> has its own <code>RootSet<T></code>. For simplicity a <code>RootSet<T></code> is a
wrapper around a <code>FreeList<Gc<T>></code>. When we add new roots, we insert them into
the <code>FreeList</code>, and when we drop a root, we remove it from the <code>FreeList</code>. This
does mean that the root set can contain duplicates and is therefore not a proper
set. The root set’s <code>FreeList</code> is additionally wrapped in an <code>Rc<RefCell<...>></code>
so that we can implement <code>Clone</code> for <code>Root<T></code>, which adds another entry in the
root set, and don’t need to explicitly pass around a <code>Heap</code> to hold additional
references to a rooted object.</p>
<p>Finally, I took care to design <code>Root<T></code> and <code>RootSet<T></code> such that <code>Root<T></code>
doesn’t directly hold a <code>Gc<T></code>. This allows for updating rooted GC pointers
after a collection, which is necessary for moving GC algorithms like
generational GC and compaction. In fact, I originally intended to implement a
copying collector, which is a moving GC algorithm, for <code>safe-gc</code> but ran into
some issues. More on those later. For now, we retain the possibility of
introducing moving GC at a later date.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">struct</span> <span class="n">Arena</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="c1">// Each arena has a root set.</span>
<span class="n">roots</span><span class="p">:</span> <span class="n">RootSet</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">,</span>
<span class="p">}</span>
<span class="c1">// The set of rooted `T`s in an arena.</span>
<span class="k">struct</span> <span class="n">RootSet</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="n">inner</span><span class="p">:</span> <span class="nb">Rc</span><span class="o"><</span><span class="n">RefCell</span><span class="o"><</span><span class="n">FreeList</span><span class="o"><</span><span class="nb">Gc</span><span class="o"><</span><span class="n">T</span><span class="o">>>>></span><span class="p">,</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o"><</span><span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="o">></span> <span class="n">RootSet</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="c1">// Rooting a `Gc<T>` adds an entry to the root set.</span>
<span class="k">fn</span> <span class="nf">insert</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">gc</span><span class="p">:</span> <span class="nb">Gc</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">)</span> <span class="k">-></span> <span class="n">Root</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">inner</span> <span class="o">=</span> <span class="k">self</span><span class="py">.inner</span><span class="nf">.borrow_mut</span><span class="p">();</span>
<span class="k">let</span> <span class="n">index</span> <span class="o">=</span> <span class="n">inner</span><span class="nf">.alloc</span><span class="p">(</span><span class="n">gc</span><span class="p">);</span>
<span class="n">Root</span> <span class="p">{</span>
<span class="n">roots</span><span class="p">:</span> <span class="k">self</span><span class="nf">.clone</span><span class="p">(),</span>
<span class="n">index</span><span class="p">,</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="nf">remove</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">index</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">inner</span> <span class="o">=</span> <span class="k">self</span><span class="py">.inner</span><span class="nf">.borrow_mut</span><span class="p">();</span>
<span class="n">inner</span><span class="nf">.dealloc</span><span class="p">(</span><span class="n">index</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">pub</span> <span class="k">struct</span> <span class="n">Root</span><span class="o"><</span><span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="o">></span> <span class="p">{</span>
<span class="c1">// Each `Root<T>` holds a reference to the root set.</span>
<span class="n">roots</span><span class="p">:</span> <span class="n">RootSet</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">,</span>
<span class="c1">// Index of this root in the root set.</span>
<span class="n">index</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="p">}</span>
<span class="c1">// Dropping a `Root<T>` removes its entry from the root set.</span>
<span class="k">impl</span><span class="o"><</span><span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="o">></span> <span class="nb">Drop</span> <span class="k">for</span> <span class="n">Root</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">drop</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="py">.roots</span><span class="nf">.remove</span><span class="p">(</span><span class="k">self</span><span class="py">.index</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>With all that out of the way, we can finally look at the core garbage collection
algorithm.</p>
<p><code>safe-gc</code> implements simple mark-and-sweep garbage collection. We begin by
resetting the mark bits for each arena, and making sure that there are enough
bits for all of our allocated objects, since we keep the mark bits in an
out-of-line compact bitset rather than in each object’s header word or something
like that.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="nd">#[inline(never)]</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="nf">gc</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Reset/pre-allocate the mark bits.</span>
<span class="k">for</span> <span class="p">(</span><span class="n">ty</span><span class="p">,</span> <span class="n">arena</span><span class="p">)</span> <span class="k">in</span> <span class="o">&</span><span class="k">self</span><span class="py">.arenas</span> <span class="p">{</span>
<span class="k">self</span><span class="py">.collector</span>
<span class="py">.mark_bits</span>
<span class="nf">.entry</span><span class="p">(</span><span class="o">*</span><span class="n">ty</span><span class="p">)</span>
<span class="nf">.or_default</span><span class="p">()</span>
<span class="nf">.reset</span><span class="p">(</span><span class="n">arena</span><span class="nf">.capacity</span><span class="p">());</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Next we begin the mark phase. This starts by iterating over each root and then
setting its mark bit and enqueuing it in the mark stack by calling
<code>collector.edge(root)</code>.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="nd">#[inline(never)]</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="nf">gc</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="c1">// Mark all roots.</span>
<span class="k">for</span> <span class="n">arena</span> <span class="k">in</span> <span class="k">self</span><span class="py">.arenas</span><span class="nf">.values</span><span class="p">()</span> <span class="p">{</span>
<span class="n">arena</span><span class="nf">.trace_roots</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="py">.collector</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">trait</span> <span class="n">ArenaObject</span><span class="p">:</span> <span class="n">Any</span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">trace_roots</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">collector</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="n">Collector</span><span class="p">);</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o"><</span><span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="o">></span> <span class="n">ArenaObject</span> <span class="k">for</span> <span class="n">Arena</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">trace_roots</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">collector</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="n">Collector</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="py">.roots</span><span class="nf">.trace</span><span class="p">(</span><span class="n">collector</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o"><</span><span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="o">></span> <span class="n">RootSet</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">trace</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="p">,</span> <span class="n">collector</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="n">Collector</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">inner</span> <span class="o">=</span> <span class="k">self</span><span class="py">.inner</span><span class="nf">.borrow</span><span class="p">();</span>
<span class="k">for</span> <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="n">root</span><span class="p">)</span> <span class="k">in</span> <span class="n">inner</span><span class="nf">.iter</span><span class="p">()</span> <span class="p">{</span>
<span class="n">collector</span><span class="nf">.edge</span><span class="p">(</span><span class="o">*</span><span class="n">root</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>The mark phase continues by marking everything transitively reachable from those
roots in a fixed-point loop. If we discover an unmarked object, we mark it and
enqueue it for tracing. Whenever we see an already-marked object, we ignore it.</p>
<p>What is kind of unusual is that we don’t have a single mark stack. The <code>Heap</code>
has no <code>T</code> type parameter, and contains many different types of objects, so the
heap itself doesn’t know how to trace any particular object. However, each of
the heap’s <code>Arena<T></code>s holds only a single type of object, and an arena <em>does</em>
know how to trace its objects. So we have a mark stack for each <code>T</code>, or
equivalently, each arena. This means that our fixed-point loop has two levels:
an outer loop that continues while any mark stack has work enqueued, and an
inner loop to drain a particular mark stack.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="nd">#[inline(never)]</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="nf">gc</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="c1">// Mark everything transitively reachable from the roots.</span>
<span class="k">while</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">type_id</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span>
<span class="py">.collector</span>
<span class="nf">.next_non_empty_mark_stack</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">while</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">index</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span>
<span class="py">.collector</span>
<span class="nf">.pop_mark_stack</span><span class="p">(</span><span class="n">type_id</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">self</span><span class="py">.arenas</span>
<span class="nf">.get_mut</span><span class="p">(</span><span class="o">&</span><span class="n">type_id</span><span class="p">)</span>
<span class="nf">.unwrap</span><span class="p">()</span>
<span class="nf">.trace_one</span><span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="py">.collector</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>While the driver loop for marking is inside the <code>Heap::gc</code> method, the actual
edge tracing and mark bit setting happens inside <code>Collector</code> and the arena
which, because it has a <code>T</code> type parameter, can call the correct <code>Trace</code>
implementation for each object.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">trait</span> <span class="n">ArenaObject</span><span class="p">:</span> <span class="n">Any</span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">trace_one</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">index</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span> <span class="n">collector</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="n">Collector</span><span class="p">);</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o"><</span><span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="o">></span> <span class="n">ArenaObject</span> <span class="k">for</span> <span class="n">Arena</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="k">fn</span> <span class="nf">trace_one</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">index</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span> <span class="n">collector</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="n">Collector</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="py">.elements</span><span class="nf">.get</span><span class="p">(</span><span class="n">index</span><span class="p">)</span><span class="nf">.trace</span><span class="p">(</span><span class="n">collector</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="k">pub</span> <span class="k">struct</span> <span class="n">Collector</span> <span class="p">{</span>
<span class="n">heap_id</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="c1">// The mark stack for each type in the heap.</span>
<span class="n">mark_stacks</span><span class="p">:</span> <span class="n">HashMap</span><span class="o"><</span><span class="n">TypeId</span><span class="p">,</span> <span class="nb">Vec</span><span class="o"><</span><span class="nb">u32</span><span class="o">>></span><span class="p">,</span>
<span class="c1">// The mark bits for each type in the heap.</span>
<span class="n">mark_bits</span><span class="p">:</span> <span class="n">HashMap</span><span class="o"><</span><span class="n">TypeId</span><span class="p">,</span> <span class="n">MarkBits</span><span class="o">></span><span class="p">,</span>
<span class="p">}</span>
<span class="k">impl</span> <span class="n">Collector</span> <span class="p">{</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="n">edge</span><span class="o"><</span><span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="nb">Gc</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">)</span> <span class="p">{</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">to</span><span class="py">.heap_id</span><span class="p">,</span> <span class="k">self</span><span class="py">.heap_id</span><span class="p">);</span>
<span class="c1">// Get the mark bits for `T` objects.</span>
<span class="k">let</span> <span class="n">ty</span> <span class="o">=</span> <span class="nn">TypeId</span><span class="p">::</span><span class="nn">of</span><span class="p">::</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="p">();</span>
<span class="k">let</span> <span class="n">mark_bits</span> <span class="o">=</span> <span class="k">self</span><span class="py">.mark_bits</span><span class="nf">.get_mut</span><span class="p">(</span><span class="o">&</span><span class="n">ty</span><span class="p">)</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="c1">// Set `to`'s mark bit. If the bit was already set, we're</span>
<span class="c1">// done.</span>
<span class="k">if</span> <span class="n">mark_bits</span><span class="nf">.set</span><span class="p">(</span><span class="n">to</span><span class="py">.index</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Otherwise this is the first time visiting this GC</span>
<span class="c1">// object so enqueue it for further marking.</span>
<span class="k">let</span> <span class="n">mark_stack</span> <span class="o">=</span> <span class="k">self</span><span class="py">.mark_stacks</span><span class="nf">.entry</span><span class="p">(</span><span class="n">ty</span><span class="p">)</span><span class="nf">.or_default</span><span class="p">();</span>
<span class="n">mark_stack</span><span class="nf">.push</span><span class="p">(</span><span class="n">to</span><span class="py">.index</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Once our mark stacks are all empty, we’ve reached our fixed point, and that
means we’ve finished marking all objects reachable from the root set. Now we
transition to the sweep phase.</p>
<p>Sweeping iterates over each object in each arena. If that object’s mark bit is
not set, then it is unreachable from the GC roots, i.e. it is not a member of
the live set, i.e. it is garbage. We drop such objects and push their slots into
their arena’s free list, making the slot available for future allocations.</p>
<p>After sweeping each arena we check whether the arena is still close to running
out of capacity and, if so, reserve additional space for the arena. This
amortizes the cost of garbage collection and avoids a scenario that could
otherwise trigger a full GC on every object allocation:</p>
<ul>
<li>The arena has zero available capacity.</li>
<li>The user tries to allocate, triggering a GC.</li>
<li>The GC is able to reclaim only one slot in the arena.</li>
<li>The user’s pending allocation fills the reclaimed slot.</li>
<li>Now the arena is out of capacity again, and the process repeats from the top.</li>
</ul>
<p>By reserving additional space in the arena after sweeping, we avoid this failure
mode.</p>
<p>We could also compact the arena and release excess space back to the global
allocator if there was too much available capacity. This would additionally
require a method for updating incoming edges to the compacted objects, and
<code>safe-gc</code> does not implement compaction at this time.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="nd">#[inline(never)]</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="nf">gc</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="c1">// Sweep.</span>
<span class="k">for</span> <span class="p">(</span><span class="n">ty</span><span class="p">,</span> <span class="n">arena</span><span class="p">)</span> <span class="k">in</span> <span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="py">.arenas</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">mark_bits</span> <span class="o">=</span> <span class="o">&</span><span class="k">self</span><span class="py">.collector.mark_bits</span><span class="p">[</span><span class="n">ty</span><span class="p">];</span>
<span class="n">arena</span><span class="nf">.sweep</span><span class="p">(</span><span class="n">mark_bits</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">trait</span> <span class="n">ArenaObject</span><span class="p">:</span> <span class="n">Any</span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="k">fn</span> <span class="nf">sweep</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">mark_bits</span><span class="p">:</span> <span class="o">&</span><span class="n">MarkBits</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o"><</span><span class="n">T</span><span class="p">:</span> <span class="n">Trace</span><span class="o">></span> <span class="n">ArenaObject</span> <span class="k">for</span> <span class="n">Arena</span><span class="o"><</span><span class="n">T</span><span class="o">></span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="k">fn</span> <span class="nf">sweep</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">mark_bits</span><span class="p">:</span> <span class="o">&</span><span class="n">MarkBits</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Reclaim garbage slots.</span>
<span class="k">let</span> <span class="n">capacity</span> <span class="o">=</span> <span class="k">self</span><span class="py">.elements</span><span class="nf">.capacity</span><span class="p">();</span>
<span class="k">for</span> <span class="n">index</span> <span class="k">in</span> <span class="mi">0</span><span class="o">..</span><span class="n">capacity</span> <span class="p">{</span>
<span class="k">if</span> <span class="o">!</span><span class="n">mark_bits</span><span class="nf">.get</span><span class="p">(</span><span class="n">index</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="py">.elements</span><span class="nf">.dealloc</span><span class="p">(</span><span class="n">index</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// Amortize the cost of GC across allocations.</span>
<span class="k">let</span> <span class="n">len</span> <span class="o">=</span> <span class="k">self</span><span class="py">.elements</span><span class="nf">.len</span><span class="p">();</span>
<span class="k">let</span> <span class="n">available</span> <span class="o">=</span> <span class="n">capacity</span> <span class="o">-</span> <span class="n">len</span><span class="p">;</span>
<span class="k">if</span> <span class="n">available</span> <span class="o"><</span> <span class="n">capacity</span> <span class="o">/</span> <span class="mi">4</span> <span class="p">{</span>
<span class="k">self</span><span class="py">.elements</span><span class="nf">.double_capacity</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>After every arena is swept, garbage collection is complete!</p>
<h3 id="preventing-classic-footguns">Preventing Classic Footguns</h3>
<p>Now that we know how <code>safe-gc</code> is implemented, we can explore a couple classic
GC footguns and analyze how <code>safe-gc</code> either completely nullifies them or
downgrades them from critical security vulnerabilities to plain old bugs.</p>
<p>Often an object might represent some external resource that should be cleaned up
when the object is no longer in use, like an open file descriptor. This
functionality is typically supported with <em>finalizers</em>, the GC-equivalent of C++
destructors and Rust’s <code>Drop</code> trait. Finalization of GC objects is usually
tricky because of the risks of either accessing objects that have already been
reclaimed by the collector (which is a use-after-free bug) or accidentally
entrenching objects and making them live again (which leads to memory
leaks). Because of these risks, Rust GC libraries often make finalization an
<code>unsafe</code> trait and even forbid allocating types that implement <code>Drop</code> in their
heaps.</p>
<p>However, <code>safe-gc</code> doesn’t need an <code>unsafe</code> finalizer trait, or even any
additional finalizer trait: it can just use <code>Drop</code>. <code>Drop</code> implementations
simply do not have access to a <code>Heap</code>, which is required to deref GC pointers,
so they <em>cannot</em> suffer from those finalization footguns.</p>
<p>Next up: why isn’t <code>Trace</code> an <code>unsafe</code> trait? And what happens if you don’t root
a <code>Gc<T></code> and then index into a <code>Heap</code> with it after a garbage collection? These
are actually the same question: what happens if I use a dangling <code>Gc<T></code>? As
mentioned at the start, if a <code>Trace</code> implementation fails to report all edges to
the collector, the collector may believe an object is unreachable and reclaim
it, and now the unreported edge is dangling. Similarly, if the user holds an
unrooted <code>Gc<T></code>, rather than a <code>Root<T></code>, across a garbage collection then the
collector might believe that the referenced object is garbage and reclaim it,
leaving the unrooted reference dangling.</p>
<p>Indexing into a <code>Heap</code> with a potentially-dangling <code>Gc<T></code> will result in one of
three possibilities:</p>
<ol>
<li>
<p>We got “lucky” and something else happened to keep the object alive. The
access succeeds as it otherwise would have and the potentially-dangling bug
is hidden.</p>
</li>
<li>
<p>The associated slot in the arena’s free list is empty and contains a
<code>FreeListEntry::Free</code> variant. This scenario will raise a panic.</p>
</li>
<li>
<p>A new object has since been allocated in the same arena slot. The access will
succeed, but it will be to the wrong object. This is an instance of <a href="https://en.wikipedia.org/wiki/ABA_problem">the ABA
problem</a>. We could, at the cost of
some runtime overhead, turn this into a loud panic instead of silent action
at a distance by <a href="https://docs.rs/generational-arena/latest/generational_arena/">adding a generation counter to our arenas</a>.</p>
</li>
</ol>
<p>Of course, it would be best if users always rooted GC references they held
across collections and correctly implemented the <code>Trace</code> trait but, should they
fail to do that, all three potential outcomes are 100% memory
safe.<sup id="fnref:sm-rooting-analysis"><a class="footnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fn:sm-rooting-analysis" rel="footnote">3</a></sup> These failures can’t lead to memory corruption or
use-after-free bugs, which would be the typical results of this kind of thing
with an unsafe GC implementation.</p>
<h3 id="copying-collector-false-start">Copying Collector False Start</h3>
<p>I initially intended to implement a copying collector rather than
mark-and-sweep, but ultimately the borrowing and ownership didn’t pan out. That
isn’t to say it is impossible to implement a copying collector in safe Rust, but
it ended up feeling like more of a headache than it was worth. I spent several
hours trying to jiggle things around to experiment with different ownership
hierarchies and didn’t get anything satisfactory. When I decided to try
mark-and-sweep, it only took me about half an hour to get an initial prototype
working. I found this really surprising, since I had a strong intuition that a
copying collector, with its separate from- and to-spaces, should play well with
Rust’s ownership and borrowing.</p>
<p>Briefly, the algorithm works as follows:</p>
<ul>
<li>
<p>We equally divide the heap into two <em>semi-spaces</em>.</p>
</li>
<li>
<p>At any given time in between collections, all objects live in one semi-space
and the other is sitting idle.</p>
</li>
<li>
<p>We <a href="https://fitzgeraldnick.com/2019/11/01/always-bump-downwards.html">bump allocate</a> within the active semi-space, slowly filling it up, and
when the bump pointer reaches the end of the semi-space, we trigger a
collection.</p>
</li>
<li>
<p>During collection, as we trace the live set, we copy objects from the old
semi-space that has been active, to the other new semi-space that has been
idle. At the same time, we maintain a map from the live objects’ location in
the old semi-space to their location in the new semi-space. When we trace an
object’s edges, we also <em>update</em> those edges to point to their new
locations. Once tracing reaches a fixed-point, we’ve copied the whole live set
to the new semi-space, it becomes the active semi-space, and the
previously-active semi-space now sits idle until the next collection.</p>
</li>
</ul>
<p>Copying collection has a number of desirable properties:</p>
<ul>
<li>
<p>The algorithm is relatively simple and easy to understand.</p>
</li>
<li>
<p>Allocating new objects is fast: just bumping a pointer and checking that space
isn’t exhausted yet.</p>
</li>
<li>
<p>The act of copying objects to the new semi-space compacts the heap, defeating
fragmentation.</p>
</li>
<li>
<p>It also eliminates the need for a sweep phase, since the whole of the old
semi-space is garbage after the live set has been moved to the new semi-space.</p>
</li>
</ul>
<p>Copying collection’s primary disadvantage is the memory overhead it imposes: we
can only ever use at most half of the heap to store objects.</p>
<p>When I think about a copying collector, I tend to imagine Lisp cons cells, as I
was first introduced to this algorithm in that context by <a href="https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/index.html">SICP</a>. Here is what a
very naive implementation of the core copying collection algorithm might look
like in safe Rust:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">fn</span> <span class="nf">copy_collect</span><span class="p">(</span>
<span class="n">roots</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="p">[</span><span class="nb">usize</span><span class="p">],</span>
<span class="n">from</span><span class="p">:</span> <span class="o">&</span><span class="p">[</span><span class="nb">Cons</span><span class="p">],</span>
<span class="n">to</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="nb">Vec</span><span class="o"><</span><span class="nb">Cons</span><span class="o">></span><span class="p">,</span>
<span class="p">)</span> <span class="p">{</span>
<span class="c1">// Contains a work list of the new indices of cons cells</span>
<span class="c1">// that have been been copied to `to` but haven't had their</span>
<span class="c1">// edges traced and updated yet.</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">stack</span> <span class="o">=</span> <span class="nn">vec</span><span class="p">::</span><span class="nf">with_capacity</span><span class="p">(</span><span class="n">roots</span><span class="nf">.len</span><span class="p">());</span>
<span class="c1">// The map from each live object's old location, to its new one.</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">old_to_new</span> <span class="o">=</span> <span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
<span class="c1">// Copy each root to the to-space, enqueue it for tracing, and</span>
<span class="c1">// update its pointer to its new index in the to-space.</span>
<span class="k">for</span> <span class="n">root</span> <span class="k">in</span> <span class="n">roots</span> <span class="p">{</span>
<span class="nf">visit_edge</span><span class="p">(</span><span class="n">from</span><span class="p">,</span> <span class="n">to</span><span class="p">,</span> <span class="o">&</span><span class="k">mut</span> <span class="n">old_to_new</span><span class="p">,</span> <span class="o">&</span><span class="k">mut</span> <span class="n">stack</span><span class="p">,</span> <span class="n">root</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// Now do the same for everything transitively reachable from</span>
<span class="c1">// the roots.</span>
<span class="k">while</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">index</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span><span class="nf">.pop</span><span class="p">()</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">cons</span> <span class="o">=</span> <span class="o">&</span><span class="k">mut</span> <span class="n">to</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">car</span><span class="p">)</span> <span class="o">=</span> <span class="o">&</span><span class="k">mut</span> <span class="n">cons</span><span class="py">.car</span> <span class="p">{</span>
<span class="nf">visit_edge</span><span class="p">(</span><span class="n">from</span><span class="p">,</span> <span class="n">to</span><span class="p">,</span> <span class="o">&</span><span class="k">mut</span> <span class="n">old_to_new</span><span class="p">,</span> <span class="o">&</span><span class="k">mut</span> <span class="n">stack</span><span class="p">,</span> <span class="n">car</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">cdr</span><span class="p">)</span> <span class="o">=</span> <span class="o">&</span><span class="k">mut</span> <span class="n">cons</span><span class="py">.cdr</span> <span class="p">{</span>
<span class="nf">visit_edge</span><span class="p">(</span><span class="n">from</span><span class="p">,</span> <span class="n">to</span><span class="p">,</span> <span class="o">&</span><span class="k">mut</span> <span class="n">old_to_new</span><span class="p">,</span> <span class="o">&</span><span class="k">mut</span> <span class="n">stack</span><span class="p">,</span> <span class="n">cdr</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// Visit one edge. If the edge's referent has already been copied</span>
<span class="c1">// to the to-space, just update the edge's pointer so that it points</span>
<span class="c1">// to the new location. If it hasn't been copied yet, additionally</span>
<span class="c1">// copy it over and enqueue it in the stack for future tracing.</span>
<span class="k">fn</span> <span class="nf">visit_edge</span><span class="p">(</span>
<span class="n">from</span><span class="p">:</span> <span class="o">&</span><span class="p">[</span><span class="nb">Cons</span><span class="p">],</span>
<span class="n">to</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="nb">Vec</span><span class="o"><</span><span class="nb">Cons</span><span class="o">></span><span class="p">,</span>
<span class="n">old_to_new</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="n">HashMap</span><span class="o"><</span><span class="nb">usize</span><span class="p">,</span> <span class="nb">usize</span><span class="o">></span><span class="p">,</span>
<span class="n">stack</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="nb">Vec</span><span class="o"><</span><span class="nb">usize</span><span class="o">></span><span class="p">,</span>
<span class="n">edge</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="nb">usize</span><span class="p">,</span>
<span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">new_location</span> <span class="o">=</span> <span class="n">old_to_new</span>
<span class="nf">.entry</span><span class="p">(</span><span class="o">*</span><span class="n">edge</span><span class="p">)</span>
<span class="nf">.or_insert</span><span class="p">(||</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">new</span> <span class="o">=</span> <span class="n">to</span><span class="nf">.len</span><span class="p">();</span>
<span class="c1">// Copy the object over.</span>
<span class="n">to</span><span class="nf">.push</span><span class="p">(</span><span class="n">from</span><span class="p">[</span><span class="o">*</span><span class="n">edge</span><span class="p">]);</span>
<span class="c1">// Enqueue it for tracing.</span>
<span class="n">stack</span><span class="nf">.push</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
<span class="n">new</span>
<span class="p">});</span>
<span class="o">*</span><span class="n">edge</span> <span class="o">=</span> <span class="n">new_location</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<p>As written, this works and is 100% safe!<sup id="fnref:works"><a class="footnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fn:works" rel="footnote">4</a></sup> So where do things start to
break down? We’ll get there, but first…</p>
<p>The old-to-new-location map needn’t be an additional, separate allocation. We
don’t need that hash map. Instead, we can reuse the from-space’s storage and
write the address of each copied object’s new location inline into its old
location. These are referred to as <em>forwarding pointers</em>. This is a super
standard optimization for copying collection; so much so that it’s rare to see a
copying collector without it.</p>
<p>Let’s implement inline forwarding pointers for our safe copying
collector. Because we are mutating the from-space to write the forwarding
pointers, we will need to change it from a shared borrow into an exclusive
borrow. Additionally, to differentiate between forwarding pointers and actual
cons cells, our semi-spaces must become slices of an <code>enum</code> rather than slices
of cons cells directly.</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">enum</span> <span class="n">SemiSpaceEntry</span> <span class="p">{</span>
<span class="c1">// The cons cell. If we see this during tracing, that means</span>
<span class="c1">// we haven't copied it over to the to-space yet.</span>
<span class="nf">Occupied</span><span class="p">(</span><span class="nb">Cons</span><span class="p">),</span>
<span class="c1">// This cons cell has already been moved, here is its new</span>
<span class="c1">// location.</span>
<span class="nf">Forwarded</span><span class="p">(</span><span class="nb">usize</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="nf">copy_collect</span><span class="p">(</span>
<span class="n">roots</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="p">[</span><span class="nb">usize</span><span class="p">],</span>
<span class="n">from</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="p">[</span><span class="n">SemiSpaceEntry</span><span class="p">],</span>
<span class="n">to</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="nb">Vec</span><span class="o"><</span><span class="n">SemiSpaceEntry</span><span class="o">></span><span class="p">,</span>
<span class="p">)</span> <span class="p">{</span>
<span class="c1">// Same as before, but without `old_to_new`...</span>
<span class="p">}</span>
<span class="k">fn</span> <span class="nf">visit_edge</span><span class="p">(</span>
<span class="n">from</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="p">[</span><span class="n">SemiSpaceEntry</span><span class="p">],</span>
<span class="n">to</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="nb">Vec</span><span class="o"><</span><span class="n">SemiSpaceEntry</span><span class="o">>></span><span class="p">,</span>
<span class="n">stack</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="nb">Vec</span><span class="o"><</span><span class="nb">usize</span><span class="o">></span><span class="p">,</span>
<span class="n">edge</span><span class="p">:</span> <span class="o">&</span><span class="k">mut</span> <span class="nb">usize</span><span class="p">,</span>
<span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">new</span> <span class="o">=</span> <span class="k">match</span> <span class="o">&</span><span class="k">mut</span> <span class="n">from</span><span class="p">[</span><span class="o">*</span><span class="n">edge</span><span class="p">]</span> <span class="p">{</span>
<span class="nn">SemiSpaceEntry</span><span class="p">::</span><span class="nf">Forwarded</span><span class="p">(</span><span class="n">new</span><span class="p">)</span> <span class="k">=></span> <span class="n">new</span><span class="p">,</span>
<span class="nn">SemiSpaceEntry</span><span class="p">::</span><span class="nf">Occupied</span><span class="p">(</span><span class="n">cons</span><span class="p">)</span> <span class="k">=></span> <span class="p">{</span>
<span class="k">let</span> <span class="n">new</span> <span class="o">=</span> <span class="n">to</span><span class="nf">.len</span><span class="p">();</span>
<span class="c1">// Copy the object over.</span>
<span class="n">to</span><span class="nf">.push</span><span class="p">(</span><span class="n">cons</span><span class="p">);</span>
<span class="c1">// Enqueue it for tracing.</span>
<span class="n">stack</span><span class="nf">.push</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
<span class="c1">// !!! Write the forwarding pointer. !!!</span>
<span class="n">from</span><span class="p">[</span><span class="n">edge</span><span class="p">]</span> <span class="o">=</span> <span class="nn">SemiSpaceEntry</span><span class="p">::</span><span class="nf">Forwarded</span><span class="p">(</span><span class="n">new</span><span class="p">);</span>
<span class="n">new</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="o">*</span><span class="n">edge</span> <span class="o">=</span> <span class="n">new</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<p>Again, this copying collector with forwarding pointers works and is still 100%
safe code.</p>
<p>Things break down when we move away from a homogeneously-typed heap that only
contains cons cells towards a heterogeneously-typed heap that can contain any
type of GC object.</p>
<p>Recall how <code>safe_gc::Heap</code> organizes its underlying storage with a hash map
keyed by type id to get the <code>Arena<T></code> storage for that associated type:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">pub</span> <span class="k">struct</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="c1">// A map from `type_id(T)` to `Arena<T>`.</span>
<span class="n">arenas</span><span class="p">:</span> <span class="n">HashMap</span><span class="o"><</span><span class="n">TypeId</span><span class="p">,</span> <span class="nb">Box</span><span class="o"><</span><span class="k">dyn</span> <span class="n">ArenaObject</span><span class="o">>></span><span class="p">,</span>
<span class="c1">// ...</span>
<span class="p">}</span></code></pre></figure>
<p>My idea was that a whole <code>Heap</code> would be a semi-space, and if it was the active
semi-space, the heap would additionally have an owning handle to the idle
semi-space:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">pub</span> <span class="k">struct</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="n">idle_semi_space</span><span class="p">:</span> <span class="nb">Option</span><span class="o"><</span><span class="nb">Box</span><span class="o"><</span><span class="n">Heap</span><span class="o">>></span><span class="p">,</span>
<span class="p">}</span></code></pre></figure>
<p>Given that, we would collect the heap by essentially (papering over some
details) calling <code>copy_collect</code> on each of its internal arenas:</p>
<figure class="highlight"><pre><code class="language-rust"><span class="k">impl</span> <span class="n">Heap</span> <span class="p">{</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="nf">gc</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">to_heap</span> <span class="o">=</span> <span class="k">self</span><span class="py">.idle_semi_space</span><span class="nf">.take</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="k">for</span> <span class="p">(</span><span class="n">ty</span><span class="p">,</span> <span class="n">from_arena</span><span class="p">)</span> <span class="k">in</span> <span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="py">.arenas</span> <span class="p">{</span>
<span class="nf">copy_collect</span><span class="p">(</span><span class="n">from_arena</span><span class="p">,</span> <span class="n">to_heap</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Note that we pass the whole <code>to_heap</code> into <code>copy_collect</code>, not <code>from_arena</code>’s
corresponding <code>Arena<T></code> in the to-space, because there can be cross-type
edges. A <code>Cat</code> object can have a reference to a <code>Salami</code> object as a little
treat, and we need access to the whole to-space, not just its <code>Arena<Cat></code>, to
copy that <code>Salami</code> over when tracing <code>Cat</code>s.</p>
<p>But here’s where things break down: we also need mutable access the whole
from-space when tracing <code>Arena<Cat></code>s because we need to write the forwarding
pointer in the from-space’s <code>Arena<Salami></code> for the <code>Salami</code>’s new location in
the to-space. But we can’t have mutable access to the whole from-space because
we’ve already projected into one of its arenas. Yeah, I guess we could use
something like take the <code>Arena<Cat></code> out of the from-space, and then pass both
the <code>Arena<Cat></code> and the whole from-space into <code>copy_collect</code>. But then what do
we do for <code>Cat</code>-to-<code>Cat</code> edges? Have some kind of check to test for whether we
need to follow a given edge into the from-space <code>Heap</code> or the <code>Arena</code> we are
currently tracing?</p>
<p>Like I said, I don’t think it is <em>impossible</em> to overcome these hurdles, the
question is: is overcoming them worth it? Everything I could think up got pretty
inelegant pretty quickly and/or would have laughably poor performance.<sup id="fnref:perf"><a class="footnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fn:perf" rel="footnote">5</a></sup>
When compared with how easy it was to implement mark-and-sweep, I just don’t
think a 100% <code>unsafe</code>-free copying collector that supports arbitrary,
heterogeneous types is worth the headache.</p>
<h3 id="why-safe-gc">Why <code>safe-gc</code>?</h3>
<p><code>safe-gc</code> is certainly a point in the design space of garbage-collection
libraries in Rust. One could even argue it is an interesting — and maybe
even useful? — point in the design space!</p>
<p>Also, it was fun!</p>
<p>At the very least, you don’t have to wonder about the correctness of any
<code>unsafe</code> code in there, because there isn’t any. As long as the Rust language
and its standard library are sound, <code>safe-gc</code> is too.</p>
<h3 id="conclusion">Conclusion</h3>
<p>The <a href="https://github.com/fitzgen/safe-gc"><code>safe-gc</code></a> crate implements garbage-collection-as-library for Rust with
zero <code>unsafe</code> code. It was fun to implement!</p>
<p>Thanks to <a href="https://elliottt.github.io/">Trevor Elliott</a> and <a href="https://jamey.thesharps.us/">Jamey
Sharp</a> for brainstorming with me and thanks to
<a href="https://manishearth.github.io/">Manish Goregaokar</a> and again to Trevor Elliott
for reading early drafts of this blog post.</p>
<hr />
<div class="footnotes">
<ol>
<li id="fn:edges">
<p>In the garbage collection literature, we think about the heap of
GC-managed objects as a graph where each object is a node in that graph and
the graph’s edges are the references from one object to another. <a class="reversefootnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fnref:edges">↩</a></p>
</li>
<li id="fn:gc-arena">
<p>The one exception to this statement that I’m aware of is the
<a href="https://docs.rs/gc-arena/latest/gc_arena/"><code>gc-arena</code></a> crate, although it
is only half an exception. Similar to <code>safe-gc</code>, it also requires threading
through a heap context (that it calls a <code>Mutation</code>) to access GC objects,
although only for allocation and mutable access to GC objects. Getting
shared, immutable borrows of GC objects doesn’t require threading in a heap
context. <a class="reversefootnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fnref:gc-arena">↩</a></p>
</li>
<li id="fn:sm-rooting-analysis">
<p>I do have sympathy for users writing these bugs! I’ve
written them myself. Remembering to root GC references across operations
that can trigger collections isn’t always easy! It can be difficult to
determine which things can trigger collections or whether some reference
you’re holding has a pointer to another structure which internally holds
onto a GC reference. The SpiderMonkey GC folks had to resort to implementing
a <a href="https://firefox-source-docs.mozilla.org/js/HazardAnalysis/index.html">GCC static analysis plugin to find unrooted references held across
GC-triggering function
calls</a>. This
analysis runs in Firefox’s CI because even the seasoned systems engineers
who work on SpiderMonkey and Firefox routinely make these mistakes and the
resulting bugs are so disastrous! <a class="reversefootnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fnref:sm-rooting-analysis">↩</a></p>
</li>
<li id="fn:works">
<p>Well, this collector works in principle; I haven’t actually compiled
it. I wrote it inside this text file, so it probably has some typos and
minor compilation errors or whatever. But the point stands: you could use
this collector for your next toy lisp. <a class="reversefootnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fnref:works">↩</a></p>
</li>
<li id="fn:perf">
<p>I’m not claiming that <code>safe-gc</code> has incredible performance, I haven’t
benchmarked anything and it almost assuredly does not. But its performance
shouldn’t be laughably bad, and I’d like to think that with a bit of tuning
it would be competitive with just about any other <code>unsafe</code>-free Rust
implementation. <a class="reversefootnote" href="http://fitzgeraldnick.com/weblog/feeds/latest-atom/#fnref:perf">↩</a></p>
</li>
</ol>
</div>2024-02-06T08:00:00+00:00The Rust Programming Language Blog: crates.io: API status code changes
https://blog.rust-lang.org/2024/02/06/crates-io-status-codes.html
<p>Cargo and crates.io were developed in the rush leading up to the Rust 1.0 release to fill the needs for a tool to manage dependencies and a registry that people could use to share code. This rapid work resulted in these tools being connected with an API that initially didn't return the correct <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status">HTTP response status codes</a>. After the Rust 1.0 release, Rust's stability guarantees around backward compatibility made this non-trivial to fix, as we wanted older versions of Cargo to continue working with the current crates.io API.</p>
<p>When an old version of Cargo receives a non-"<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200">200 OK</a>" response, it displays the raw JSON body like this:</p>
<pre><code>error: failed to get a 200 OK response, got 400
headers:
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 171
body:
{"errors":[{"detail":"missing or empty metadata fields: description, license. Please see https://doc.rust-lang.org/cargo/reference/manifest.html for how to upload metadata"}]}
</code></pre>
<p>This was improved in pull request <a href="https://github.com/rust-lang/cargo/pull/6771">#6771</a>, which was released in Cargo 1.34 (mid-2019). Since then, Cargo has supported receiving <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses">4xx</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#server_error_responses">5xx</a> status codes too and extracts the error message from the JSON response, if available.</p>
<p>On <strong>2024-03-04</strong> we will switch the API from returning "200 OK" status codes for errors to the new 4xx/5xx behavior. <strong>Cargo 1.33 and below will keep working after this change</strong>, but will show the raw JSON body instead of a nicely formatted error message. We feel confident that this degraded error message display will not affect very many users. According to the <a href="https://p.datadoghq.com/sb/3a172e20-e9e1-11ed-80e3-da7ad0900002-973f4c1011257befa8598303217bfe3a">crates.io request logs</a> only very few requests are made by Cargo 1.33 and older versions.</p>
<p>This is the list of API endpoints that will be affected by this change:</p>
<ul>
<li><code>GET /api/v1/crates</code></li>
<li><code>PUT /api/v1/crates/new</code></li>
<li><code>PUT /api/v1/crates/:crate/:version/yank</code></li>
<li><code>DELETE /api/v1/crates/:crate/:version/unyank</code></li>
<li><code>GET /api/v1/crates/:crate/owners</code></li>
<li><code>PUT /api/v1/crates/:crate/owners</code></li>
<li><code>DELETE /api/v1/crates/:crate/owners</code></li>
</ul>
<p>All other endpoints have already been using regular HTTP status codes for some time.</p>
<p>If you are still using Cargo 1.33 or older, we recommend upgrading to a newer version to get the improved error messages and all the other nice things that the Cargo team has built since then.</p>2024-02-06T00:00:00+00:00Tobias BieniekMozilla Localization (L10N): L10n Report: February 2024 Edition
https://blog.mozilla.org/l10n/2024/02/02/l10n-report-february-2024-edition/
<p><i>Please note some of the information provided in this report may be subject to change as we are sometimes sharing information about projects that are still in early stages and are not final yet. </i></p>
<h3>New content and projects</h3>
<h4>What’s new or coming up in Firefox desktop</h4>
<p>While the amount of content has been relatively small over the last few months in Firefox, there have been some UI changes and updates to privacy setting related text such as form autofill, Cookie Banner Blocker, passwords (about:logins), and cookie and site data*. One change happening here (and across all Mozilla products) is the move away from using the term “login” to describe the credentials for accessing websites and instead use “password(s).”</p>
<p>In addition, while the number of strings is low, Firefox’s PDF viewer will soon have the ability to highlight content. You can test this feature now in Nightly.</p>
<p>Most of these strings and translations can be previewed by checking a Nightly build. If you’re new to localizing Firefox or if you missed our deep dive, please check out our <a href="https://blog.mozilla.org/l10n/2023/07/27/l10n-report-july-2023-edition/#firefox-schedule">blog post from July</a> to learn more about the Firefox release schedule.</p>
<p>*Recently in our <a href="https://chat.mozilla.org/#/room/#l10n-community:mozilla.org">L10N community matrix channel</a>, someone from our community asked how the new strings for clearing browsing history and data (see screenshot below) from Cookie and Site Data could be shown in Nightly.</p>
<p><a href="https://blog.mozilla.org/l10n/files/2024/02/unnamed.png"><img alt="Pontoon screenshot showing the strings for clearing browsing history and data from Cookie and Site Data." class="aligncenter wp-image-1648 size-large" height="560" src="https://blog.mozilla.org/l10n/files/2024/02/unnamed-600x560.png" width="600" /></a>In order to show the strings in Nightly, the privacy.sanitize.useOldClearHistoryDialog preference needs to be set to false. To set the preference, type about:config in your URL bar and press enter. A warning may pop up warning you to proceed with caution, click the button to continue. On the page that follows, paste privacy.sanitize.useOldClearHistoryDialog into the search field, then click the toggle button to change the value to false.</p>
<p>You can then trigger the new dialog by clicking “Clear Data…” from the Cookies and Site Data setting or “Clear History…” from the History. (You may need to quit Firefox and open it again for the change to take effect.).</p>
<p>In case of doubts about managing about:config, you can consult the <a href="https://support.mozilla.org/kb/about-config-editor-firefox">Configuration Editor guide on SUMO</a>.</p>
<h4>What’s new or coming up in mobile</h4>
<p>Much like desktop, mobile land has been pretty calm recently.</p>
<p>Having said that, we would like to call out the new Translation feature that is now available to test on the latest Firefox for Android v124 Nightly builds (this is possible only through the secret settings at the moment). It’s a built-in full page translation feature that allows you to seamlessly browse the web in your preferred language. As you navigate the site, Firefox continuously translates new content.</p>
<p>Check your Pontoon notifications for instructions on how to test it out. Note that the feature is not available on iOS at the moment.</p>
<p>In the past couple of months you may have also noticed strings mentioning a new shopping feature called “Review Checker” (that we mentioned for desktop in our November <a href="https://blog.mozilla.org/l10n/2023/11/03/l10n-report-november-2023-edition/">edition</a>). The feature is still a bit tricky to test on Android, but there are instructions you can follow – these can also be found in your Pontoon notification archive.</p>
<p>For testing on iOS, you just need to have the latest <a href="https://www.mozilla.org/en-US/firefox/ios/testflight/">Beta version</a> installed and navigate to the product pages on the US sites of<a href="http://amazon.com"> amazon.com</a>,<a href="http://bestbuy.com"> bestbuy.com</a>, and<a href="http://walmart.com"> walmart.com</a>. A logo in the URL bar will appear with a notification, to launch and test the feature.</p>
<p>Finally, another notable change that has been called out under the Firefox desktop section above: we are moving away from using the term “login” to describe the credentials for accessing websites and instead use “password(s).”</p>
<h4>What’s new or coming up in Foundation projects</h4>
<p>New languages have been added to Common Voice in 2023: Tibetan, Chichewa, Ossetian, Emakhuwa, Laz, Pular Guinée, Sindhi. Welcome!</p>
<h4>What’s new or coming up in Pontoon</h4>
<h5>Improved support for mobile devices</h5>
<p>Pontoon translation workspace is now responsive, which means you can finally use Pontoon on your mobile device to translate and review strings! We developed a single-column layout for mobile phones and 2-column layout for tablets.</p>
<div class="wp-caption aligncenter" id="attachment_1637" style="width: 262px;"><a href="https://blog.mozilla.org/l10n/files/2024/01/android.png"><img alt="Screenshot of Pontoon UI on a smartphone running Firefox for Android" class="wp-image-1637 size-medium" height="560" src="https://blog.mozilla.org/l10n/files/2024/01/android-252x560.png" width="252" /></a><p class="wp-caption-text" id="caption-attachment-1637">Screenshot of Pontoon UI on a smartphone running Firefox for Android</p></div>
<h5>2024 Pontoon survey</h5>
<p>Thanks again to everyone who has participated in the <a href="https://blog.mozilla.org/l10n/2023/12/20/2024-pontoon-survey-results/">2024 Pontoon survey</a>. The 3 top-voted features we commit to implement are:</p>
<ol>
<li><a href="https://github.com/mozilla/pontoon/issues/3031">Add ability to edit Translation Memory entries</a> (611 votes).</li>
<li><a href="https://github.com/mozilla/pontoon/issues/3032">Improve performance of Pontoon translation workspace and dashboards</a> (603 votes).</li>
<li><a href="https://github.com/mozilla/pontoon/issues/2310">Add ability to propose new Terminology entries</a> (595 votes).</li>
</ol>
<h3>Friends of the Lion <a href="https://blog.mozilla.org/l10n/files/2022/10/2-Lions-01-600x553-1.png"><img alt="" class="size-medium wp-image-1585 alignright" height="232" src="https://blog.mozilla.org/l10n/files/2022/10/2-Lions-01-600x553-1-252x232.png" width="252" /></a></h3>
<p>We started a series called “Localizer Spotlight” and have published <a href="https://blog.mozilla.org/l10n/2023/08/31/localizer-spotlight-victor-ibragimov-tajik-locale/">two</a> <a href="https://blog.mozilla.org/l10n/2023/09/29/localizer-spotlight-meet-reza-persian-locale/">already</a>. Do you know someone who should be featured there? Let us know <a href="https://docs.google.com/forms/d/e/1FAIpQLScOr7tvM7ygIQwP0lrPh8XUeMb0GtDIPWJL-mOoK7z8uHbbgA/viewform?usp=sf_link">here</a>!</p>
<p>Also, do someone in your l10n community who’s been doing a great job and should appear in this section? <a href="mailto:l10n-drivers@mozilla.org">Contact us</a> and we’ll make sure they get a shout-out!</p>
<h3>Useful Links</h3>
<ul>
<li><a href="https://chat.mozilla.org/#/room/#l10n-community:mozilla.org">#l10n-community channel on Element (chat.mozilla.org)</a></li>
<li><a href="https://discourse.mozilla.org/c/l10n/547">Localization category on Discourse</a></li>
<li><a href="https://twitter.com/mozilla_l10n">Twitter</a></li>
<li><a href="https://blog.mozilla.org/l10n/">L10n blog</a></li>
</ul>
<h3>Questions? Want to get involved?</h3>
<p>If you want to get involved, or have any question about l10n, reach out to:</p>
<ul>
<li><a href="https://pontoon.mozilla.org/contributors/mZuzEFP7EcmgBBTbvtgJP2LFFTY/">Francesco Lodolo (flod)</a> – Engineering Manager</li>
<li><a href="https://pontoon.mozilla.org/contributors/CMLZ_n1lNNSfQScLGE2yBmlS55w/">Bryan</a> – l10n Project Manager</li>
<li><a href="https://pontoon.mozilla.org/contributors/3LPn77ppB_IQ9F6ruL5lw2IVrvQ/">Delphine</a> – l10n Project Manager for mobile</li>
<li><a href="https://pontoon.mozilla.org/contributors/jIdunhnZ8Edgi9npILuSoFvf5ZY/">Peiying (CocoMo)</a> – l10n Project Manager for mozilla.org, marketing, and legal</li>
<li><a href="https://pontoon.mozilla.org/contributors/m6r3HOfoijMdyeJNKKFHchjjRbw/">Francis</a> – l10n Project Manager for Common Voice, Mozilla Foundation</li>
<li><a href="https://pontoon.mozilla.org/contributors/lY_FTvtnYcVoDP7JYZjMsm6tRno/">Théo Chevalier</a> – l10n Project Manager for Mozilla Foundation</li>
<li><a href="https://pontoon.mozilla.org/contributors/dvgiVCmoeidF2xcqSnBHtpzLTFU/">Matjaž (mathjazz)</a> – Pontoon dev</li>
<li><a href="https://pontoon.mozilla.org/contributors/pmz0uSCe_Mk9Td1cksHLI1y471k/">Eemeli</a> – Pontoon, Fluent dev</li>
</ul>
<p>Did you enjoy reading this report? <a href="mailto:l10n-drivers@mozilla.org">Let us know</a> how we can improve it.</p>2024-02-02T08:07:37+00:00Matjaž HorvatFrederik Braun: How Firefox gives special permissions to some domains
https://frederik-braun.com/special-browser-privileges-for-some-domains.html
<p>Today, I found someone tweeting about a neat <a href="https://crbug.com/1472898">security bug in Chrome, that
bypasses how Chrome disallows extensions from injecting JavaScript into
special domains like <code>chrome.google.com</code></a>.
The intention of this block is that browsers give special permissions to
some internal pages that allow troubleshooting, resetting the browser,
installing …</p>2024-02-01T23:00:00+00:00FrederikHacks.Mozilla.Org: Announcing Interop 2024
https://hacks.mozilla.org/2024/02/announcing-interop-2024/
<p>The <a href="https://github.com/web-platform-tests/interop#the-interop-project">Interop Project</a> has become one of the key ways that browser vendors come together to improve the web platform. By working to identify and improve key areas where differences between browser engines are impacting users and web developers, Interop is a critical tool in ensuring the long-term health of the open web.</p>
<p>The web platform is built on interoperability based on common standards. This offers users a degree of choice and control that sets the web apart from proprietary platforms defined by a single implementation. A commitment to ensuring that the web remains open and interoperable forms a fundamental part of Mozilla’s <a href="https://www.mozilla.org/about/manifesto/">manifesto</a> and <a href="https://www.mozilla.org/en-US/about/webvision/">web vision</a>, and is why we’re so committed to shipping Firefox with our own <a href="https://en.wikipedia.org/wiki/Gecko_(software)">Gecko</a> engine.</p>
<p>However interoperability requires care and attention to maintain. When implementations ship with differences between the standard and each other, this creates a <a href="https://2023.stateofcss.com/en-US/usage/#css_pain_points">pain point</a> for web authors; they have to choose between avoiding the problematic feature entirely and coding to specific implementation quirks. Over time if enough authors produce implementation-specific content then interoperability is lost, and along with it user agency.</p>
<p>This is the problem that the Interop Project is designed to address. By bringing browser vendors together to focus on interoperability, the project allows identifying areas where interoperability issues are causing problems, or may do in the near future. Tracking progress on those issues with a public metric provides accountability to the broader web community on addressing the problems.</p>
<p>The project works by identifying a set of high-priority focus areas: parts of the web platform where everyone agrees that making interoperability improvements will be of high value. These can be existing features where we know browsers have slightly different behaviors that are causing problems for authors, or they can be new features which web developer feedback shows is in high demand and which we want to launch across multiple implementations with high interoperability from the start. For each focus area a set of web-platform-tests is selected to cover that area, and the score is computed from the pass rate of these tests.</p>
<h3>Interop 2023</h3>
<p>The <a href="https://hacks.mozilla.org/2023/02/announcing-interop-2023/">Interop 2023</a> project covered high profile features like the new :has() selector, and web-codecs, as well as areas of historically poor interoperability such as pointer events.</p>
<p><img alt="" class="alignnone size-large wp-image-48086" height="407" src="https://hacks.mozilla.org/files/2024/01/Interop-2023-500x407.png" width="500" /></p>
<p>The <a href="https://wpt.fyi/interop-2023">results</a> of the project speak for themselves: every browser ended the year with scores in excess of 97% for the prerelease versions of their browsers. Moreover, the overall Interoperability score — that is the fraction of focus area tests that pass in all participating browser engines — increased from 59% at the start of the year to 95% now. This result represents a huge improvement in the consistency and reliability of the web platform. For users this will result in a more seamless experience, with sites behaving reliably in whichever browser they prefer.</p>
<p>For the :has() selector — which we know from author feedback has been one of the most in-demand CSS features for a long time — every implementation is <a href="https://wpt.fyi/results/css/selectors?label=experimental&label=master&product=chrome&product=firefox&product=safari&aligned&view=interop&q=label%3Ainterop-2023-has">now passing 100%</a> of the web-platform-tests selected for the focus area. Launching a major new platform feature with this level of interoperability demonstrates the power of the Interop project to progress the platform without compromising on implementation diversity, developer experience, or user choice.</p>
<p>As well as focus areas, the Interop project also has “investigations”. These are areas where we know that we need to improve interoperability, but aren’t at the stage of having specific tests which can be used to measure that improvement. In 2023 we had two investigations. The first was for accessibility, which covered writing many more tests for ARIA <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles">computed role</a> and <a href="https://developer.mozilla.org/en-US/docs/Glossary/Accessible_name">accessible name</a>, and ensuring they could be run in different browsers. The second was for mobile testing, which has resulted in both Mobile Firefox and Chrome for Android having their initial <a href="https://wpt.fyi/runs?label=master&from=2024-01-10T00%3A00&product=firefox_android&product=chrome_android">results in wpt.fyi</a>.</p>
<h3>Interop 2024</h3>
<p>Following the success of Interop 2023, we are pleased to confirm that the project will continue in 2024 with a new selection of focus areas, representing areas of the web platform where we think we can have the biggest positive impact on users and web developers.</p>
<h4>New Focus Areas</h4>
<p>New focus areas for 2024 include, among other things:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Popover_API">Popover API</a> – This provides a declarative mechanism to create content that always renders in the topmost-layer, so that it overlays other web page content. This can be useful for building features like tooltips and notifications. Support for popover was the #1 author request in the recent State of HTML survey.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting">CSS Nesting</a> – This is a feature that’s already shipping, which allows writing more compact and readable CSS files, without the need for external tooling such as preprocessors. However different browsers shipped slightly different behavior based on different revisions of the spec, and Interop will help ensure that everyone aligns on a single, reliable, syntax for this popular feature.</li>
<li>Accessibility – Ensuring that the web is accessible to all users is a critical part of <a href="https://www.mozilla.org/en-US/about/manifesto/">Mozilla’s manifesto</a>. Our ability to include Accessibility testing in Interop 2024 is a direct result of the success of the Interop 2023 Accessibility Investigation in increasing the test coverage of key accessibility features.</li>
</ul>
<p>The full list of focus areas is available in the <a href="https://github.com/web-platform-tests/interop/blob/main/2024/README.md">project README</a>.</p>
<h4>Carryover</h4>
<p>In addition to the new focus areas, we will carry over some of the 2023 focus areas where there’s still more work to be done. Of particular interest is the Layout focus area, which will combine the previous <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/grid">Grid</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Subgrid">Subgrid</a> focus area into one area covering all the most important layout primitives for the modern web. On top of that the Custom Properties, URL and Mouse and Pointer Events focus areas will be carried over. These represent cases where, even though we’ve already seen large improvements in Interoperability, we believe that users and web authors will benefit from even greater convergence between implementations.</p>
<h4>Investigations</h4>
<p>As well as focus areas, Interop 2024 will also feature a new investigation into improving the integration of WebAssembly testing into web-platform-tests. This will open up the possibility of including WASM features in future Interop projects. In addition we will extend the Accessibility and Mobile Testing investigations, as there is more work to be done to make those aspects of the platform fully testable across different implementations.</p>
<h3>Partner Announcements</h3>
<ul>
<li><strong>Apple</strong>: <a href="https://webkit.org/blog/14955/the-web-just-gets-better-with-interop/">The web just gets better with Interop, now for 2024</a></li>
<li><strong>Bocoup</strong>: <a href="https://bocoup.com/blog/interop-2024">Interop 2024</a></li>
<li><strong>Google</strong>: <a href="https://web.dev/blog/interop-2024">Interop 2024</a></li>
<li><strong>Igalia</strong>: <a href="https://www.igalia.com/2024/interop-2024-launches.html">Interop 2024 Launches</a></li>
<li><strong>Microsoft</strong>: <a href="https://blogs.windows.com/msedgedev/2024/02/01/microsoft-edge-and-interop-2024/">Microsoft Edge and Interop 2024</a></li>
</ul>
<p>The post <a href="https://hacks.mozilla.org/2024/02/announcing-interop-2024/">Announcing Interop 2024</a> appeared first on <a href="https://hacks.mozilla.org">Mozilla Hacks - the Web developer blog</a>.</p>2024-02-01T17:05:30+00:00James GrahamMike Hommey: When undefined behavior causes a nonsensical error (in Rust)
https://glandium.org/blog/?p=4354
<p>This all started when I looked at whether it would be possible to build Firefox with Pointer Authentication Code for arm64 macOS. In case you're curious, the quick answer is no, because Apple essentially hasn't upstreamed the final ABI for it yet, only Xcode clang can produce it, and obviously Rust can't.</p>
<p>Anyways, the Rust compiler did recently add the <code>arm64e-apple-darwin</code> target (which, as mentioned above, turns out to be useless for now), albeit without a prebuilt libstd (so, requiring the use of the <code>-Zbuild-std</code> flag). And by recently, I mean in 1.76.0 (in beta as of writing).</p>
<p>So, after tricking the Firefox build system into accepting to build for that target, I ended up with a Firefox build that... crashed on startup, saying:</p>
<pre><code>Hit MOZ_CRASH(unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed isize::MAX) at /builds/worker/fetches/rustc/lib/rustlib/src/rust/library/core/src/panicking.rs:155"</code></pre>
<p>(<code>MOZ_CRASH</code> is what we get on explicit crashes, like <code>MOZ_ASSERT</code> in C++ code, or <code>assert!()</code> in Rust)</p>
<p>The caller of the crashing code was <code>NS_InvokeByIndex</code>, so at this point, I was thinking <a href="https://www-archive.mozilla.org/scriptable/">XPConnect</a> might need some adjustement for arm64e.</p>
<p>But that was a build I had produced through the <a href="https://wiki.mozilla.org/ReleaseEngineering/TryServer">Mozilla try server</a>. So I did a local non-optimized debug build to see what's up, which crashed with a different message:</p>
<pre><code>Hit MOZ_CRASH(slice::get_unchecked requires that the index is within the slice) at /Users/glandium/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/index.rs:228</code></pre>
<p>This comes from this code in rust libstd:</p>
<pre><code class="language-rust"> unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
debug_assert_nounwind!(
self < slice.len(),
"slice::get_unchecked requires that the index is within the slice",
);
// SAFETY: the caller guarantees that `slice` is not dangling, so it
// cannot be longer than `isize::MAX`. They also guarantee that
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
// so the call to `add` is safe.
unsafe {
crate::hint::assert_unchecked(self < slice.len());
slice.as_ptr().add(self)
}
}</code></pre>
<p>(I'm pasting the whole thing because it will be important later)</p>
<p>We're hitting the <code>debug_assert_nounwind</code>.</p>
<p>The calling code looks like the following:</p>
<pre><code class="language-rust">let end = atoms.get_unchecked(STATIC_ATOM_COUNT) as *const _;</code></pre>
<p>And what the <code>debug_assert_nounwind</code> means is that STATIC_ATOM_COUNT is greater or equal to the slice size (spoiler alert: it is equal).</p>
<p>At that point, I started to suspect this might be a more general issue with the new Rust version, rather than something limited to arm64e. And I was kind of right? Mozilla automation did show crashes on all platforms when building with Rust beta (currently 1.76.0). But that was a different, and non-sensical crash:</p>
<pre><code>Hit MOZ_CRASH(attempt to add with overflow) at servo/components/style/gecko_string_cache/mod.rs:77</code></pre>
<p>But this time, it was in the same vicinity as the crash I was getting locally.</p>
<p>Since this was talking about an overflowing addition, I wrapped both terms in <code>dbg!()</code> to see the numbers and... the overflow disappeared but now I was getting a plain crash:</p>
<pre><code>application crashed [@ <usize as core::slice::index::SliceIndex<[T]>>::get_unchecked]</code></pre>
<p>(still from the same call to <code>get_unchecked</code>, at least)</p>
<p>The problem <a href="https://hg.mozilla.org/integration/autoland/rev/a570b0623013#l3.49">was fixed by essentially removing the entire code</a> that was using <code>get_unchecked</code>. <a href="https://en.wiktionary.org/wiki/%E3%82%81%E3%81%A7%E3%81%9F%E3%81%97%E3%82%81%E3%81%A7%E3%81%9F%E3%81%97">めでたしめでたし</a>.</p>
<p>But this was too weird to leave it at that.</p>
<p>So what's going on?</p>
<p>Well, first is that despite there being a <code>debug_assert</code>, debug builds don't complain about the out-of-bounds use of <code>get_unckecked</code>. Only when using <code>-Zbuild-std</code> does it happen. I'm not sure whether that's intended, but I <a href="https://github.com/rust-lang/rust/issues/120539">opened an issue about it to figure out</a>.</p>
<p>Second, in the code I pasted from <code>get_unchecked</code>, the <code>hint::assert_unchecked</code> is new in 1.76.0 (well, it was <code>intrinsics::assume</code> in 1.76.0 and became <code>hint::assert_unchecked</code> in 1.77.0, but it wasn't there before). This is why our broken code didn't cause actual problems until now.</p>
<p>What about the addition overflow?</p>
<p>Well, this is where undefined behavior leads the optimizer to do what the user might perceive as weird things, but they actually make sense (as usual with these things involving undefined behavior). Let's start with a standalone version of the original code, simplifying the types used originally:</p>
<pre><code class="language-rust">#![allow(non_upper_case_globals, non_snake_case, dead_code)]
#[inline]
fn static_atoms() -> &'static [[u32; 3]; STATIC_ATOM_COUNT] {
unsafe {
let addr = &gGkAtoms as *const _ as usize + kGkAtomsArrayOffset as usize;
&*(addr as *const _)
}
}
#[inline]
fn valid_static_atom_addr(addr: usize) -> bool {
unsafe {
let atoms = static_atoms();
let start = atoms.as_ptr();
let end = atoms.get_unchecked(STATIC_ATOM_COUNT) as *const _;
let in_range = addr >= start as usize && addr < end as usize;
let aligned = addr % 4 == 0;
in_range && aligned
}
}
fn main() {
println!("{:?}", valid_static_atom_addr(0));
}</code></pre>
<p>Stick this code in a newly created crate (with e.g. <code>cargo new testcase</code>), and run it:</p>
<pre><code>$ cargo +nightly run -q
false</code></pre>
<p>Nothing obviously bad happened. So what went wrong in Firefox? In my first local attempt, I had <code>-Zbuild-std</code>, so let's try that:</p>
<pre><code>$ cargo +nightly run -q -Zbuild-std --target=x86_64-unknown-linux-gnu
thread 'main' panicked at /home/glandium/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:228:9:
slice::get_unchecked requires that the index is within the slice
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.</code></pre>
<p>There we go, we hit that <code>get_unchecked</code> error. But what went bad in Firefox if the reduced testcase doesn't crash without <code>-Zbuild-std</code>? Well, Firefox is always built with optimizations on by default, even for debug builds.</p>
<pre><code>$ RUSTFLAGS=-O cargo +nightly run -q
thread 'main' panicked at src/main.rs:10:20:
attempt to add with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace</code></pre>
<p>Interestingly, though, changing the addition to</p>
<pre><code> let addr = dbg!(&gGkAtoms as *const _ as usize) + dbg!(kGkAtomsArrayOffset as usize);</code></pre>
<p>doesn't "fix" it like it did with Firefox, but it shows:</p>
<pre><code>[src/main.rs:10:20] &gGkAtoms as *const _ as usize = 94400145014784
[src/main.rs:10:59] kGkAtomsArrayOffset as usize = 61744
thread 'main' panicked at src/main.rs:10:20:
attempt to add with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace</code></pre>
<p>which is even funnier, because you can see that adding those two numbers is definitely not causing an overflow.</p>
<p>Let's take a look at what LLVM is doing with this code across optimization passes, with the following command (on the initial code without <code>dbg!()</code>, and with a <code>#[inline(never)]</code> on <code>valid_static_atom_addr</code>):</p>
<pre><code>RUSTFLAGS="-C debuginfo=0 -O -Cllvm-args=-print-changed=quiet" cargo +nightly run -q </code></pre>
<p>Here is what's most relevant to us. First, what the <code>valid_static_atom_addr</code> function looks like after inlining <code>as_ptr</code> into it:</p>
<pre><code class="language-llvm">*** IR Dump After InlinerPass on (_ZN8testcase22valid_static_atom_addr17h778b64d644106c67E) ***
; Function Attrs: noinline nonlazybind uwtable
define internal fastcc noundef zeroext i1 @_ZN8testcase22valid_static_atom_addr17h778b64d644106c67E(i64 noundef %0) unnamed_addr #3 {
%2 = call fastcc noundef align 4 dereferenceable(31212) ptr @_ZN8testcase12static_atoms17hde3e2dda1d3edc34E()
call void @llvm.experimental.noalias.scope.decl(metadata !4)
%3 = call fastcc noundef align 4 dereferenceable(12) ptr @"_ZN4core5slice29_$LT$impl$u20$$u5b$T$u5d$$GT$13get_unchecked17he5e8081ea9f9099dE"(ptr noalias noundef nonnull readonly align 4 %2, i64 noundef 2601, i64 noundef 2601)
%4 = icmp eq ptr %2, null
ret i1 %4
}</code></pre>
<p>At this point, we've already done some constant propagation, and we can see the call to get_unchecked is done with constants.</p>
<p>What comes next, after inlining both <code>static_atoms</code> and <code>get_unchecked</code>:</p>
<pre><code class="language-llvm">*** IR Dump After InlinerPass on (_ZN8testcase22valid_static_atom_addr17h778b64d644106c67E) ***
; Function Attrs: noinline nonlazybind uwtable
define internal fastcc noundef zeroext i1 @_ZN8testcase22valid_static_atom_addr17h778b64d644106c67E(i64 noundef %0) unnamed_addr #2 {
%2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 ptrtoint (ptr @_ZN8testcase8gGkAtoms17h338a289876067f43E to i64), i64 61744)
%3 = extractvalue { i64, i1 } %2, 1
br i1 %3, label %4, label %5, !prof !4
4: ; preds = %1
call void @_ZN4core9panicking5panic17hae453b53e597714dE(ptr noalias noundef nonnull readonly align 1 @str.0, i64 noundef 28, ptr noalias noundef nonnull readonly align 8 dereferenceable(24) @2) #9
unreachable
5: ; preds = %1
%6 = extractvalue { i64, i1 } %2, 0
%7 = inttoptr i64 %6 to ptr
call void @llvm.experimental.noalias.scope.decl(metadata !5)
unreachable
8: ; No predecessors!
%9 = icmp eq ptr %7, null
ret i1 %9
}</code></pre>
<p>The first basic block has two exits: 4 and 5, depending on how the add with overflow performed. Both of these basic blocks finish in... unreachable. The first one because it's the panic case for the overflow, and the second one because both values passed to <code>get_unchecked</code> are constants and equal, which the compiler has been hinted (with <code>hint::assert_unchecked</code>) that it's not possible. Thus, once <code>get_unchecked</code> is inlined, what's left is unreachable code. And because we're not rebuilding libstd, the debug_assert is not there before the <code>unreachable</code> annotation. Finally, the last basic block is now orphan.</p>
<p>Imagine you're an optimizer, and you want to optimize this code considering all its annotations. Well, you'll start by removing the orphan basic block. Then you see that the basic block 5 doesn't do anything, and doesn't have side effects, so you just remove it. Which means the branch leading to it can't happen. Basic block 4? There's a function call, so it would have to stay there, and so would the first basic block.</p>
<p>Guess what the Control-Flow Graph pass did? Just that:</p>
<pre><code class="language-llvm">*** IR Dump After SimplifyCFGPass on _ZN8testcase22valid_static_atom_addr17h778b64d644106c67E ***
; Function Attrs: noinline nonlazybind uwtable
define internal fastcc noundef zeroext i1 @_ZN8testcase22valid_static_atom_addr17h778b64d644106c67E(i64 noundef %0) unnamed_addr #2 {
%2 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 ptrtoint (ptr @_ZN8testcase8gGkAtoms17h338a289876067f43E to i64), i64 61744)
%3 = extractvalue { i64, i1 } %2, 1
call void @llvm.assume(i1 %3)
call void @_ZN4core9panicking5panic17hae453b53e597714dE(ptr noalias noundef nonnull readonly align 1 @str.0, i64 noundef 28, ptr noalias noundef nonnull readonly align 8 dereferenceable(24) @2) #9
unreachable
}</code></pre>
<p>Now, there's no point doing the addition at all, since we're not even looking at its result:</p>
<pre><code class="language-llvm">*** IR Dump After InstCombinePass on _ZN8testcase22valid_static_atom_addr17h778b64d644106c67E ***
; Function Attrs: noinline nonlazybind uwtable
define internal fastcc noundef zeroext i1 @_ZN8testcase22valid_static_atom_addr17h778b64d644106c67E(i64 noundef %0) unnamed_addr #2 {
call void @llvm.assume(i1 icmp uge (i64 ptrtoint (ptr @_ZN8testcase8gGkAtoms17h338a289876067f43E to i64), i64 -61744))
call void @_ZN4core9panicking5panic17hae453b53e597714dE(ptr noalias noundef nonnull readonly align 1 @str.0, i64 noundef 28, ptr noalias noundef nonnull readonly align 8 dereferenceable(24) @2) #9
unreachable
}</code></pre>
<p>And this is how a hint that undefined behavior can't happen transformed <code>get_unchecked(STATIC_ATOM_COUNT)</code> into an addition overflow that never happened.</p>
<p>Obviously, this all doesn't happen with <code>-Zbuild-std</code>, because in that case the <code>get_unchecked</code> branch has a panic call that is still relevant.</p>
<pre><code>$ RUSTFLAGS=-O cargo +nightly run -q -Zbuild-std --target=x86_64-unknown-linux-gnu
thread 'main' panicked at /home/glandium/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:228:9:
slice::get_unchecked requires that the index is within the slice
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.</code></pre>
<p>What about non-debug builds?</p>
<pre><code>$ cargo +nightly run --release -q
Illegal instruction</code></pre>
<p>In those builds, because there is no call to display a panic, the entire function ends up unreachable:</p>
<pre><code class="language-llvm">define internal fastcc noundef zeroext i1 @_ZN8testcase22valid_static_atom_addr17h9d1fc9abb5e1cc3aE(i64 noundef %0) unnamed_addr #4 {
unreachable
} </code></pre>
<p>So thanks to the magic of hints and compiler optimization, we have code that invokes undefined behavior that</p>
<ul>
<li>crashes when built with <code>cargo build --release</code></li>
<li>works when built with <code>cargo build</code></li>
<li>says there's an addition overflow when built with <code>RUSTFLAGS=-O cargo build</code>.</li>
</ul>
<p>And none of those give a hint as to what the real problem is.</p>2024-02-01T01:38:09+00:00glandiumSpidermonkey Development Blog: SpiderMonkey Newsletter (Firefox 122-123)
https://spidermonkey.dev/blog/2024/01/30/newsletter-firefox-122-123.html
<p>Hello everyone!</p>
<p><a href="https://www.mgaudet.ca/about">Matthew Gaudet</a> here from the SpiderMonkey team, giving Jan a break from newsletter writing.</p>
<p>Our newsletter is an opportunity to highlight some of the work that’s happened in SpiderMonkey land over the last couple of releases. Everyone is hard at work (though some of us are nicely rejuvenated from a winter break).</p>
<p>Feel free to email feedback on the shape of the newsletter to <a href="mailto:mgaudet@mozilla.com">me</a>, as I’d be interested in hearing what works for people and what doesn’t.</p>
<h3 id="-performance">🚀 Performance</h3>
<p>We’re continuing work on our performance story, with Speedometer 3 being the current main target. We like Speedometer 3 because it provides a set of workloads that we think better reflect the real web, driving <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867359">improvements to real users too</a>.</p>
<p>Here is a curated selection of just some of the performance related changes in this release:</p>
<ul>
<li>Iain Ireland improved performance on React through <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867359">eager atomization of property keys</a> (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867359#c16">13% improvement</a> on a <a href="https://firefox-source-docs.mozilla.org/devtools/tests/performance-tests-overview.html#damp">devtools benchmark subtest</a>,<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867359#c17"> 7% on Jetstream2-Offfline Assembler</a>).</li>
<li>Contributor André Bargull <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873042">improved the performance of various String methods</a> (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873042#c14">Between 2 and 5% on various Jetstream2 Subtests</a>)</li>
<li>Jon fixed an <a href="https://accidentallyquadratic.tumblr.com/">accidentally quadratic</a> traversal in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867453">Bug 1867453 - Nightly spends tons of time (2 minutes+) around GC on an online OCR tool. The time increases exponentially as the size of the image increases</a></li>
<li>I added a new optimization system called <a href="https://searchfox.org/mozilla-central/rev/c130c69b7b863d5e28ab9524b65c27c7a9507c48/js/src/vm/GuardFuse.h#21-61">Fuses</a>, which will allow us to make optimizations that depend on assumptions about the state of the virtual machine. The first optimization to make use of this <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870396">landed in 123</a>. While it wasn’t a noticeable improvement for Speedometer, it does provide about a 40% improvement on a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destructuring</a> microbenchmark. The hope is that this framework will be a foundation to build further improvement upon.</li>
</ul>
<h4 id="-contributor-spotlight-mayank-bansal">🔦 Contributor Spotlight: Mayank Bansal</h4>
<p>Mayank Bansal has been a huge help to the Firefox project for years. Taking a special interest in performance, he is often one of the first to take note of a performance improvement or regression. He also frequently files performance bugs, some of which have identified fixable problems, along with comparative profiles which smooth the investigative process.</p>
<p>In his own words:</p>
<blockquote>
<p><a href="https://www.linkedin.com/in/mayankbansal01">Mayank Bansal</a> has been using Firefox Nightly for more than a decade. He is passionate about browser performance and scours the internet for interesting javascript test-cases for the SM team to analyse. He closely monitors the performance improvement and regressions on <a href="https://arewefastyet.com">AWFY</a>. You can check out some of the bugs he has filed by visiting the metabug <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=1808325">here</a>.</p>
</blockquote>
<p>The SpiderMonkey team greatly appreciates all the help we get from Mayank. Thank you very much Mayank.</p>
<h3 id="-wasm">⚡ Wasm</h3>
<ul>
<li>Ben Visness enabled <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1861261">JIT Allocation of Structs</a>, which helps improve Wasm GC performance by 5-15% depending on workload.</li>
<li>Ryan Hunt implemented the <a href="https://github.com/WebAssembly/js-string-builtins">js-string-builtin</a> proposal championed by Mozilla for fast access to strings from wasm in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1863794">Bug 1863794</a>.</li>
<li>Ryan also implemented the <a href="https://github.com/WebAssembly/exception-handling/issues/280">exnref proposal</a> in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1853454">Bug 1853454</a></li>
</ul>
<h3 id="️--other-work">👷🏽♀️ Other Work</h3>
<ul>
<li>Contributor André Bargull has <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1423593">landed (nightly only)</a> support for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter"><code class="language-plaintext highlighter-rouge">Intl.Segmenter</code></a></li>
<li>I enabled <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1865103"><code class="language-plaintext highlighter-rouge">ArrayBuffer.prototype.transfer</code></a> by default (but André Bargull did all the real work in implementing this). This API provides ownership semantics to JS ArrayBuffers.</li>
<li>Contributor Jonatan Klemets has landed updates to our preliminary (disabled by default) support for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1835669">Import Assertions</a>.</li>
<li>I fixed a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1866385">low volume crash related to synchronous events occurring while devtools is open on a page</a>; this should eventually avoid about 10 crashes a week for people debugging in Firefox. As of 121.0.1 this should no longer occur. This was a fun investigation triggered by a seemingly impossible crash, and also an interesting case of a crash-report bug opened by a bot leading to an actionable fix.</li>
</ul>
<h3 id="-date-parsing-improvements">⏰ Date parsing improvements</h3>
<p>Contributor Vinny Diehl has continued improving our date parsing story, aiming to improve compatibility and handling of peculiar cases.</p>
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1862910">Bug 1862910 - Make Date.parse only check first 3 characters of month name</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1866811">Bug 1866811 - the javascript-engine returns 943916400000 on Date.parse(“0000-00-00”) instead of NaN</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870434">Bug 1870434 - Date.parse rejects single numbers < 1000</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1872333">Bug 1872333 - Day of month overflow should be parsed as an ISO style date</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870570">Bug 1870570 - Date.parse accepts incomplete time zone abbreviations and AM/PM</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873186">Bug 1873186 - Deprecate day of week late in the format for Date.parse</a></li>
</ul>
<h3 id="-fuzzing">🐇 Fuzzing</h3>
<p>In order to find bugs, <a href="https://en.wikipedia.org/wiki/Fuzzing">fuzzing</a> by generating and running random testcases to see if they crash turns out to be an unreasonably effective technique. The SpiderMonkey team works with a variety of fuzzers, both inside of Mozilla (👋 Hi <code class="language-plaintext highlighter-rouge">fuzzing@</code>!) and outside (Thank you all!).</p>
<p>Fuzzing can find test cases which are both very benign but worth fixing, as well as extremely serious security bugs. Security sensitive fuzz bugs are eligible for the <a href="https://www.mozilla.org/en-US/security/bug-bounty/">Mozilla Bug Bounty Program</a>.</p>
<p>To show off the kind of fun we have with fuzzing, I thought I’d curate some fun, interesting (and not hidden for security reasons) fuzz bugs.</p>
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870756">A fun catch on weird ARM32 Hardware</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1858678">Finding overly strict assertions</a>in testing code.</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870747">Discovering our <code class="language-plaintext highlighter-rouge">callWithABI</code> signatures couldn’t handle <code class="language-plaintext highlighter-rouge">int64_t</code> returns on 32-bit, which went subtly awry in the arm32 simulator build.</a></li>
</ul>2024-01-30T17:00:00+00:00Mozilla Thunderbird: Thunderbird Monthly Development Digest: January 2024
https://blog.thunderbird.net/2024/01/thunderbird-monthly-development-digest-january-2024/
<p><img alt="Stylized Thunderbird icon with a code prompt in its center, against a purple background." class="attachment-640x360 size-640x360 wp-post-image" height="320" src="https://blog.thunderbird.net/files/2024/01/Developer-banner.png" width="640" /></p>
<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=de&u=https://blog.thunderbird.net/2024/01/thunderbird-monthly-development-digest-january-2024/" rel="noreferrer noopener" target="_blank">Auf Deutsch übersetzen</a></div>
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=fr&u=https://blog.thunderbird.net/2024/01/thunderbird-monthly-development-digest-january-2024/" rel="noreferrer noopener" target="_blank">Traduire en français</a></div>
<div class="wp-block-button has-custom-font-size has-small-font-size"><a class="wp-block-button__link has-black-color has-white-background-color has-text-color has-background wp-element-button" href="https://translate.google.com/translate?js=n&sl=auto&tl=ja&u=https://blog.thunderbird.net/2024/01/thunderbird-monthly-development-digest-january-2024/">日本語に翻訳</a></div>
</div>
<p id="defanged2-docs-internal-guid-143fabb5-7fff-ee66-6ae0-7abd9defdc45">Hello Thunderbird Community! I’m very happy to kick off a new monthly Thunderbird development recap in order to bring a deeper look and understanding of what we’re working on, and the status of these efforts. (We also publish monthly progress reports on <a href="https://blog.thunderbird.net/category/thunderbird-mobile/">Thunderbird for Android</a>.)</p>
<p>These monthly digests will be in a very short format, focusing primarily on the work that is currently being planned or initiated that is not yet fully captured in BugZilla. Nonetheless, we’re putting it out there to cherish and fully embrace the open nature of Thunderbird. </p>
<p>Without further ado, let’s get into it!</p>
<h3 class="wp-block-heading"><strong>2024 Thunderbird Development Roadmaps</strong> <strong>Published</strong></h3>
<p>Over at DTN, we’ve published initial 2024 roadmaps for the work we have planned on <a href="https://developer.thunderbird.net/planning/roadmap">Thunderbird for desktop</a>, and <a href="https://developer.thunderbird.net/planning/android-roadmap">Thunderbird for Android</a>. These will be updated periodically as we continue to scope out each project. </p>
<h3 class="wp-block-heading"><strong>Global Message Database</strong></h3>
<p>Our database is currently based on <a href="https://en.wikipedia.org/wiki/Mork_(file_format)" rel="noreferrer noopener" target="_blank">Mork</a>, which is a very old paradigm that creates a lot of limitations, blocking us from doing anything remotely modern or expected (a real threaded conversation view is a classic example). Removing and reworking this implementation, which is at the very core of every message and folder interaction, is not an easy lift and requires a lot of careful planning and exploration, but the work is underway.</p>
<p>You can follow the general effort in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1572000" rel="noreferrer noopener" target="_blank">Bug 1572000</a>.</p>
<p>The first clean up effort is targeted at removing the old and bad paradigm of the <em>“non-unique unique ID”</em> (kudos to our very own Ben Campbell for coining this term), which causes all sorts of problems. You can follow the work in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1806770" rel="noreferrer noopener" target="_blank">Bug 1806770</a>.</p>
<h3 class="wp-block-heading"><strong>Cards view final sprint</strong></h3>
<p>If you’re using Daily or Beta you might have already seen a lot of drastic differences from 115 for Cards View.</p>
<p>Currently, we’re shaping up the final sprint to polish what we’ve implemented and add extra needed features. We’re in the process of opening all the needed bugs and assigning resources for this final sprint. You can follow the progress by tracking <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1861062" rel="noreferrer noopener" target="_blank">this meta bug</a> and all its child bugs.</p>
<p>As usual, we will continue sharing plans and mock-ups in the <a href="https://thunderbird.topicbox.com/groups/ux" rel="noreferrer noopener" target="_blank">UX mailing list</a>, so make sure to follow that if you’re interested in seeing early visual prototypes before any code is touched.</p>
<h3 class="wp-block-heading"><strong>Rust Implementation and Exchange</strong> <strong>Support</strong></h3>
<p>This is a very large topic and exploration that requires dedicated posts (which are coming) and extensive recaps. The short story is that we were able to enable the usage of <strong>Rust </strong>in Thunderbird, therefore opening the doors for us to start implementing native support for the <strong>Exchange </strong>protocol by building and vendoring a Rust crate.</p>
<p>Once we have a stable and safe implementation, we will share that crate publicly on a <a href="https://github.com/thunderbird" rel="noreferrer noopener" target="_blank">GitHub repo</a> so everyone will be able to vendor it and improve it.</p>
<p>Make sure to follow <a href="https://thunderbird.topicbox.com/groups/planning" rel="noreferrer noopener" target="_blank">tb-planning</a> and <a href="https://thunderbird.topicbox.com/groups/developers" rel="noreferrer noopener" target="_blank">tb-developers</a> mailing lists to soon get more detailed and very in depth info on Rust and Exchange in Thunderbird.</p>
<p>As usual, if you want to see things as they land you can always check the <a href="https://hg.mozilla.org/comm-central/pushloghtml" rel="noreferrer noopener" target="_blank">pushlog </a>and try running dail<a href="https://ftp.mozilla.org/pub/thunderbird/nightly/2024" rel="noreferrer noopener" target="_blank">y</a>, which would be immensely helpful for catching bugs early.</p>
<p><strong>Alessandro Castellani</strong> <em>(he, him)</em><br />Director of Product Engineering</p>
<figure class="wp-block-pullquote" style="border-width: 2px; font-style: normal; font-weight: 400;"><blockquote><p>If you’re interested in joining the discussion around Thunderbird development, consider joining one or several of our <a href="https://thunderbird.topicbox.com">mailing list groups here</a>. </p></blockquote></figure>
<p>The post <a href="https://blog.thunderbird.net/2024/01/thunderbird-monthly-development-digest-january-2024/">Thunderbird Monthly Development Digest: January 2024</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p>2024-01-30T04:33:52+00:00Alessandro CastellaniHacks.Mozilla.Org: Option Soup: the subtle pitfalls of combining compiler flags
https://hacks.mozilla.org/2024/01/option-soup-the-subtle-pitfalls-of-combining-compiler-flags/
<p><i>Firefox development uncovers many cross-platform differences and unique features of its combination of dependencies. Engineers working on Firefox regularly overcome these challenges and while we can’t detail all of them, we think you’ll enjoy hearing about some so here’s a sample of a recent technical investigation.</i></p>
<p>During the Firefox 120 beta cycle, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1861365">a new crash signature appeared on our radars with significant volume</a>.</p>
<p>At that time, the distribution across operating systems revealed that more than 50% of the crash volume originates from Ubuntu 18.04 LTS users.</p>
<p>The main process crashes in a <code>CanvasRenderer</code> thread, with the following call stack:</p>
<pre>0 firefox std::locale::operator=
1 firefox std::ios_base::imbue
2 firefox std::basic_ios<char, std::char_traits<char> >::imbue
3 libxul.so sh::InitializeStream<std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> > > /build/firefox-ZwAdKm/firefox-120.0~b2+build1/gfx/angle/checkout/src/compiler/translator/Common.h:238
3 libxul.so sh::TCompiler::setResourceString /build/firefox-ZwAdKm/firefox-120.0~b2+build1/gfx/angle/checkout/src/compiler/translator/Compiler.cpp:1294
4 libxul.so sh::TCompiler::Init /build/firefox-ZwAdKm/firefox-120.0~b2+build1/gfx/angle/checkout/src/compiler/translator/Compiler.cpp:407
5 libxul.so sh::ConstructCompiler /build/firefox-ZwAdKm/firefox-120.0~b2+build1/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp:368
6 libxul.so mozilla::webgl::ShaderValidator::Create /build/firefox-ZwAdKm/firefox-120.0~b2+build1/dom/canvas/WebGLShaderValidator.cpp:215
6 libxul.so mozilla::WebGLContext::CreateShaderValidator const /build/firefox-ZwAdKm/firefox-120.0~b2+build1/dom/canvas/WebGLShaderValidator.cpp:196
7 libxul.so mozilla::WebGLShader::CompileShader /build/firefox-ZwAdKm/firefox-120.0~b2+build1/dom/canvas/WebGLShader.cpp:98</pre>
<p>At first glance, we want to blame WebGL. The C++ standard library functions cannot be at fault, right?</p>
<p>But when looking at the WebGL code, the crash occurs in the perfectly valid lines of C++ summarized below:</p>
<pre>std::ostringstream stream;
stream.imbue(std::locale::classic());</pre>
<p>This code should never crash, and yet it does. In fact, taking a closer look at the stack gives a first lead for investigation:<br />
Although we crash into functions that belong to the C++ standard library, these functions appear to live in the firefox binary.</p>
<p>This is an unusual situation that never occurs with official builds of Firefox.<br />
It is however very common for distribution to change the configuration settings and apply downstream patches to an upstream source, no worries about that.<br />
Moreover, there is only a single build of Firefox Beta that is causing this crash.</p>
<p>We know this thanks to a unique identifier associated with any ELF binary.<br />
Here, if we choose any specific version of Firefox 120 Beta (such as 120b9), the crashes all embed the same unique identifier for firefox.</p>
<p>Now, how can we guess what build produces this weird binary?</p>
<p>A useful user comment mentions that they regularly experience this crash since updating to <var>120.0~b2+build1-0ubuntu0.18.04.1</var>.<br />
And by looking for this build identifier, we quickly reach <a href="https://launchpad.net/~mozillateam/+archive/ubuntu/firefox-next">the Firefox Beta PPA</a>.<br />
Then indeed, we are able to reproduce the crash by installing it in a Ubuntu 18.04 LTS virtual machine: it occurs when loading any WebGL page!<br />
With the binary now at hand, running <code>nm -D ./firefox</code> confirms the presence of several symbols related to libstdc++ that live in the text section (<code>T</code> marker).</p>
<p>Templated and inline symbols from libstdc++ usually appear as weak (<code>W</code> marker), so there is only one explanation for this situation: firefox has been statically linked with libstdc++, probably through <code>-static-libstdc++</code>.</p>
<p>Fortunately, the build logs are available for all Ubuntu packages.<br />
After some digging, we find <a href="https://launchpadlibrarian.net/697121043/buildlog_ubuntu-bionic-amd64.firefox_120.0~b9+build1-0ubuntu0.18.04.1_BUILDING.txt.gz">the logs for the 120b9 build</a>, which indeed contain references to <code>-static-libstdc++</code>.</p>
<p>But why?</p>
<p>Again, everything is well documented, and thanks to well trained digging skills we reach <a href="https://bugs.launchpad.net/ubuntu/+source/firefox/+bug/1856861">a bug report</a> that provides interesting insights.<br />
Firefox requires a modern C++ compiler, and hence a modern libstdc++, which is unavailable on old systems like Ubuntu 18.04 LTS.<br />
The build uses <code>-static-libstdc++</code> to close this gap.<br />
This just explains the weird setup though.</p>
<p>What about the crash?</p>
<p>Since we can now reproduce it, we can launch Firefox in a debugger and continue our investigation.<br />
When inspecting the crash site, we seem to crash because <code>std::locale::classic()</code> is not properly initialized.<br />
Let’s take a peek at the implementation.</p>
<pre>const locale& locale::classic()
{
_S_initialize();
return *(const locale*)c_locale;
}</pre>
<p><code>_S_initialize()</code> is in charge of making sure that <code>c_locale</code> will be properly initialized before we return a reference to it.<br />
To achieve this, <code>_S_initialize()</code> calls another function, <code>_S_initialize_once()</code>.</p>
<pre>void locale::_S_initialize()
{
#ifdef __GTHREADS
if (!__gnu_cxx::__is_single_threaded())
__gthread_once(&_S_once, _S_initialize_once);
#endif
if (__builtin_expect(!_S_classic, 0))
_S_initialize_once();
}</pre>
<p>In <code>_S_initialize()</code>, we first go through a wrapper for <code>pthread_once()</code>: the first thread that reaches this code consumes <code>_S_once</code> and calls <code>_S_initialize_once()</code>, whereas other threads (if any) are stuck waiting for <code>_S_initialize_once()</code> to complete.</p>
<p>This looks rather fail-proof, right?</p>
<p>There is even an extra direct call to <code>_S_initialize_once()</code> if <code>_S_classic</code> is still uninitialized after that.<br />
Now, <code>_S_initialize_once()</code> itself is rather straightforward: it allocates <code>_S_classic</code> and puts it within <code>c_locale</code>.</p>
<pre>void
locale::_S_initialize_once() throw()
{
// Need to check this because we could get called once from _S_initialize()
// when the program is single-threaded, and then again (via __gthread_once)
// when it's multi-threaded.
if (_S_classic)
return;
// 2 references.
// One reference for _S_classic, one for _S_global
_S_classic = new (&c_locale_impl) _Impl(2);
_S_global = _S_classic;
new (&c_locale) locale(_S_classic);
}</pre>
<p>The crash looks as if we never went through <code>_S_initialize_once()</code>, so let’s put a breakpoint there and see what happens.<br />
And just by doing this, we already notice something suspicious.<br />
We do reach <code>_S_initialize_once()</code>, but not within the firefox binary: instead, we only ever reach the version exported by liblgpllibs.so.<br />
In fact, liblgpllibs.so is also statically linked with libstdc++, such that firefox and liblgpllibs.so both embed and export their own <code>_S_initialize_once()</code> function.</p>
<p>By default, <i>symbol interposition</i> applies, and <code>_S_initialize_once()</code> should always be called through the procedure linkage table (PLT), so that every module ends up calling the same version of the function.<br />
If symbol interposition were happening here, we would expect that liblgpllibs.so would reach the version of _S_initialize_once() exported by firefox rather than its own, because firefox was loaded first.</p>
<p>So maybe there is no symbol interposition.</p>
<p>This can occur when using <code>-fno-semantic-interposition</code>.</p>
<p>Each version of the standard library would live on its own, independent from the other versions.<br />
But neither the Firefox build system nor the Ubuntu maintainer seem to pass this flag to the compiler.<br />
However, by looking at the disassembly for <code>_S_initialize()</code> and <code>_S_initialize_once()</code>, we can see that the exported global variables (<code>_S_once</code>, <code>_S_classic</code>, <code>_S_global</code>) <b>are</b> subject to symbol interposition:</p>
<p>These accesses all go through the global offset table (GOT), so that every module ends up accessing the same version of the variable.<br />
This seems strange given what we said earlier about <code>_S_initialize_once()</code>.<br />
Non-exported global variables (<code>c_locale</code>, <code>c_locale_impl</code>), however, are accessed directly without symbol interposition, as expected.</p>
<p>We now have enough information to explain the crash.</p>
<p>When we reach <code>_S_initialize()</code> in liblgpllibs.so, we actually consume the <code>_S_once</code> that lives in firefox, and initialize the <code>_S_classic</code> and <code>_S_global</code> that live in firefox.<br />
But we initialize them with pointers to well initialized variables <code>c_locale_impl</code> and <code>c_locale</code> that live in liblgpllibs.so!<br />
The variables <code>c_locale_impl</code> and <code>c_locale</code> that live in firefox, however, remain uninitialized.</p>
<p>So if we later reach <code>_S_initialize()</code> in firefox, everything looks as if initialization has happened.<br />
But then we return a reference to the version of <code>c_locale</code> that lives in firefox, and this version has never been initialized.</p>
<p>Boom!</p>
<p>Now the main question is: why do we see interposition occur for <code>_S_once</code> but not for <code>_S_initialize_once()</code>?<br />
If we step back for a minute, there is a fundamental distinction between these symbols: one is a function symbol, the other is a variable symbol.<br />
And indeed, the Firefox build system uses the <code>-Bsymbolic-function</code> flag!</p>
<p>The ld man page describes it as follows:</p>
<blockquote>
<pre>-Bsymbolic-functions
When creating a shared library, bind references to global function symbols to the definition within the shared library, if any. This option is only meaningful on ELF platforms which support shared libraries.</pre>
</blockquote>
<p>As opposed to:</p>
<blockquote>
<pre>-Bsymbolic
When creating a shared library, bind references to global symbols to the definition within the shared library, if any. Normally, it is possible for a program linked against a shared library to override the definition within the shared library. This option is only meaningful on ELF platforms which support shared libraries.</pre>
</blockquote>
<p>Nailed it!</p>
<p>The crash occurs because this flag makes us use a weird variant of symbol interposition, where symbol interposition happens for variable symbols like <code>_S_once</code> and <code>_S_classic</code> but not for function symbols like <code>_S_initialize_once()</code>.</p>
<p>This results in a mismatch regarding how we access global variables: exported global variables are unique thanks to interposition, whereas every non-interposed function will access its own version of any non-exported global variable.</p>
<p>With all the knowledge that we have now gathered, it is easy to write a reproducer that does not involve any Firefox code:</p>
<pre>/* main.cc */
#include <iostream>
extern void pain();
int main() {
pain();
std::cout << "[main] " << std::locale::classic().name() <<"\n";
return 0;
}
/* pain.cc */
#include <iostream>
void pain() {
std::cout << "[pain] " << std::locale::classic().name() <<"\n";
}
# Makefile
all:
$(CXX) pain.cc -fPIC -shared -o libpain.so -static-libstdc++ -Wl,-Bsymbolic-functions
$(CXX) main.cc -fPIC -c -o main.o
$(CC) main.o -fPIC -o main /usr/lib/gcc/x86_64-redhat-linux/13/libstdc++.a -L. -Wl,-rpath=. -lpain -Wl,-Bsymbolic-functions
./main
clean:
$(RM) libpain.so main
</pre>
<p>Understanding the bug is one step, and solving it is yet another story.<br />
Should it be considered a libstdc++ bug that the code for locales is not compatible with <code>-static-stdlibc++ -Bsymbolic-functions</code>?</p>
<p>It feels like combining these flags is a very nice way to dig our own grave, and <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112551">that seems to be the opinion of the libstdc++ maintainers indeed</a>.</p>
<p>Overall, perhaps the strangest part of this story is that this combination did not cause any trouble up until now.<br />
Therefore, we suggested to the maintainer of the package to stop using <code>-static-libstdc++</code>.</p>
<p>There are other ways to use a different libstdc++ than available on the system, such as using dynamic linking and setting an <code>RPATH</code> to link with a bundled version.</p>
<p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1861365#c11">Doing that</a> allowed them to successfully deploy a fixed version of the package.<br />
A few days after that, with the official release of Firefox 120, we noticed a very significant bump in volume for the same crash signature. Not again!</p>
<p>This time the volume was coming exclusively from users of NixOS 23.05, and it was huge!</p>
<p>After we shared the conclusions from our beta investigation with them, the maintainers of NixOS were able to <a href="https://github.com/NixOS/nixpkgs/issues/269571#issuecomment-1825836670">quickly associate</a> the crash with <a href="https://github.com/NixOS/nixpkgs/pull/192459">an issue that had not yet been backported </a>for 23.05 and was causing the compiler to behave like <code>-static-libstdc++</code>.</p>
<p>To avoid such mess in the future, <a href="https://phabricator.services.mozilla.com/rMOZILLACENTRAL0930954b46bbc315ffcb92658bde0efc2945b04b">we added detection for this particular setup in Firefox’s configure</a>.</p>
<p>We are grateful to the people who have helped fix this issue, in particular:</p>
<ul>
<li>Rico Tzschichholz (ricotz) who quickly fixed the Ubuntu 18.04 LTS package, and Amin Bandali (bandali) who provided help on the way;</li>
<li>Martin Weinelt (hexa) and Artturin for their prompt fixes for the NixOS 23.05 package;</li>
<li>Nicolas B. Pierron (nbp) for helping us get started with NixOS, which allowed us to quickly share useful information with the NixOS package maintainers.</li>
</ul>
<p> </p>
<p>The post <a href="https://hacks.mozilla.org/2024/01/option-soup-the-subtle-pitfalls-of-combining-compiler-flags/">Option Soup: the subtle pitfalls of combining compiler flags</a> appeared first on <a href="https://hacks.mozilla.org">Mozilla Hacks - the Web developer blog</a>.</p>2024-01-29T18:18:33+00:00Serge GueltonThe Talospace Project: Firefox 122 on POWER
https://www.talospace.com/2024/01/firefox-122-on-power.html
Right now during our relocation I'm not always in the same ZIP code as my T2, but we've still got to keep it up to date. To that end Firefox 122 is out with <a href="https://www.mozilla.org/en-US/firefox/122.0/releasenotes/">some UI improvements</a> and <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/122">new Web platform support</a>.
<p>
A number of changes have occurred between Fx121 and Fx122 which improve our situation in OpenPOWER world, most notably being we no longer need to drag our WebRTC build changes around (and/or you can remove <tt>--disable-webrtc</tt> in your <tt>.mozconfig</tt>). However, on Fedora I needed to add <tt>ac_add_options --with-libclang-path=/usr/lib64</tt> to my <tt>.mozconfig</tt>s (or <tt>./mach build</tt> would fail during configuration because Rust <tt>bindgen</tt> could not find <tt>libclang.so</tt>), and I also needed to effectively <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1865993">fix bug 1865993</a> to get PGO builds to work again on Python 3.12, which Fedora 39 ships with. You may not need to do either of these things depending on your distro. There are separate weird glitches due to certain other components being deprecated in Python 3.12 that do not otherwise affect the build.
</p><p>
To that end, here is <a href="https://gist.github.com/classilla/1202f8d467749c029325278a87a068c8">the updated PGO-LTO patch</a> I'm using, as well as the current <tt>.mozconfig</tt>s:
</p><h3><b>Optimized</b></h3>
<pre>export CC=/usr/bin/gcc
export CXX=/usr/bin/g++
mk_add_options MOZ_MAKE_FLAGS="-j24" # or as you like
ac_add_options --enable-application=browser
ac_add_options --enable-optimize="-O3 -mcpu=power9 -fpermissive"
ac_add_options --enable-release
ac_add_options --enable-linker=bfd
ac_add_options --enable-lto=full
ac_add_options --without-wasm-sandboxed-libraries
ac_add_options --with-libclang-path=/usr/lib64
ac_add_options MOZ_PGO=1
export GN=/home/censored/bin/gn # if you haz
export RUSTC_OPT_LEVEL=2
</pre>
<h3><b>Debug</b></h3>
<pre>export CC=/usr/bin/gcc
export CXX=/usr/bin/g++
mk_add_options MOZ_MAKE_FLAGS="-j24" # or as you like
ac_add_options --enable-application=browser
ac_add_options --enable-optimize="-Og -mcpu=power9 -fpermissive -DXXH_NO_INLINE_HINTS=1"
ac_add_options --enable-debug
ac_add_options --enable-linker=bfd
ac_add_options --without-wasm-sandboxed-libraries
ac_add_options --with-libclang-path=/usr/lib64
export GN=/home/censored/bin/gn # if you haz
</pre>2024-01-28T02:42:54+00:00ClassicHasClassFirefox Developer Experience: Firefox DevTools Newsletter — 122
https://fxdx.dev/firefox-devtools-newsletter-122/
<p id="block-660521a7-b7f1-4009-9ba0-e51d24c1c3bb"><em>Developer Tools help developers write and debug websites on Firefox. This newsletter gives an overview of the work we’ve done as part of the Firefox 122 Nightly release cycle.</em></p>
<p id="block-0cf4b3d9-690f-481f-8115-a35a2ee4f80d">Firefox being an open source project, we are grateful to get contributions from people outside of Mozilla, like <a href="https://bugzilla.mozilla.org/user_profile?user_id=738995"><strong>AAR.dev</strong></a>, who fixed a typo in the Profiler settings page (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1865895">#1865895</a>).</p>
<p class="has-background-secondary-background-color has-background" id="block-f6fddf3c-3ebb-46d8-81e6-94a2caf64a22">Want to help? DevTools are written in HTML, CSS and JS so any web developer can contribute! Read <a href="https://firefox-source-docs.mozilla.org/devtools/getting-started/README.html">how to setup the work environment</a> and check <a href="https://codetribute.mozilla.org/projects/devtools">the list of mentored issues</a></p>
<hr class="wp-block-separator has-alpha-channel-opacity" />
<h3>Accessibility</h3>
<p>As said in previous newsletters, we worked on accessibility issues across the toolbox, and fixed a few of them in this release. First, there was a big focus in the Inspector view to make sure that various elements are all accessible and can activated using only the keyboard:</p>
<ul>
<li>the checkbox to disable/enable a property (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1844055">#1844055</a>)</li>
<li>the selector highlighter icon (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1844053">#1844053</a>) </li>
<li>the button to show rules containing a given property (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1844058">#1844058</a>)</li>
<li>the expandable containers like Pseudo elements, keyframes, … (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1866986">#1866986</a>)</li>
<li>the new CSS property edit control (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1844057">#1844057</a>)</li>
<li>the toggle buttons in top toolbar (:hov, .cls, print and dark/light mode simulation) (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1844061">#1844061</a>)</li>
<li>the grid highlighter color picker (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1844072">#1844072</a>)</li>
</ul>
<p>While working on keyboard navigation in the Rules view, we felt like we could revisit the behavior of the Enter key when editing selector,property name or value. Since we know this is an important change, we write a specific blog post to explain our motivation behind it: <a href="https://fxdx.dev/rules-view-enter-key/">https://fxdx.dev/rules-view-enter-key/</a> <br /><br />Finally, we fixed remaining focus indicator (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1865846">#1865846</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1866087">#186608</a>) and color contrast issue (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1843332">#1843332</a>), as well as properly labelled the button to toggle object properties in the console and debugger (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1844088">#1844088</a>)</p>
<p>This project is coming to an end, but we’ll likely have another project later this year to take care of remaining, especially in tools we didn’t investigate yet, like the Network panel.</p>
<h3>Miscellaneous</h3>
<p>Did you know that the console exposes two helper functions, <code>$</code> and <code>$$</code> ? They are similar to <code>document.querySelector</code> and <code>document.querySelectorAll</code>, the only difference being that <code>$$</code> returns an array, while <code>document.querySelectorAll</code> <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll#return_value">returns a <code>NodeList</code></a>. Now those two helpers are eagerly evaluated, making it easier to query a specific element as you get feedback about matching elements as you’re typing (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1616524">#1616524</a>)</p>
<figure class="wp-block-image aligncenter size-large"><img alt="The console input, filled with the following expression: `$$(":has(h1)")` The eager evaluation result, just below the console input is displaying `Array [ html, body ]`" class="wp-image-238" height="257" src="https://fxdx.dev/files/2024/01/CleanShot-2024-01-26-at-16.05.47-600x257.png" width="600" /></figure>
<p>You can now set <code>beforeunload</code> and <code>unload</code> <a href="https://firefox-source-docs.mozilla.org/devtools-user/debugger/set_event_listener_breakpoints/index.html">event listener breakpoints</a> in the Debugger which should be pretty useful when investigating navigation/reload issues (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1569775">#1569775</a>).<br /><br />The total transferred size in the Network Monitor does not include service worker requests any more (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1347146">#1347146</a>).<br /><br />We fixed fews issues in the Inspector. First, we weren’t able to load stylesheet text, which could occur in projects using <a href="https://vitejs.dev/">Vite</a> (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867816">#1867816</a>). We also introduced a bug in the Inspector markup view in 121, which was causing single click to activate URLS in element attributes (e.g. the <code>src</code> attribute on <code><img></code> elements) (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870214">#1870214</a>). Finally, using the the clip path editor could cause the value in the Rules view to be invalid (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1868263">#1868263</a>).</p>
<p class="has-text-align-center has-background-secondary-background-color has-background"><strong>Thank you for reading this and using our tools, see you next month for a new round of updates <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" style="height: 1em;" /></strong></p>
<p></p>2024-01-26T15:58:07+00:00Nicolas ChevobbeThe Servo Blog: Two months in Servo: better inline layout, stable Rust, and more!
https://servo.org/blog/2024/01/26/two-months-in-servo/
<figure class="_figr"><a href="https://servo.org/img/blog/layout-2020-justify.png"><img alt="Servo nightly showing support for ‘text-align-last’, ‘text-align: justify’, ‘vertical-align: baseline’, and ‘position: sticky’" src="https://servo.org/img/blog/layout-2020-justify.png" /></a></figure>
<p>Servo has had some exciting changes land in our nightly builds over the last month:</p>
<ul>
<li>as of 2023-12-27, the ‘text-align-last’ property is now supported (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30905">#30905</a>)</li>
<li>as of 2023-12-27, ‘text-align: justify’ is now supported (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30807">#30807</a>, <a href="https://github.com/servo/servo/pull/30866">#30866</a>)</li>
<li>as of 2024-01-09, ‘line-height’ and ‘vertical-align’ are now moderately supported (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30902">#30902</a>)</li>
<li>as of 2024-01-24, ‘Event#composedPath()’ is now supported (<a href="https://github.com/gterzian">@gterzian</a>, <a href="https://github.com/servo/servo/pull/31123">#31123</a>)</li>
</ul>
<figure class="_figl"><a href="https://servo.org/img/blog/layout-2020-tables.png"><img alt="Servo nightly showing rudimentary support for table layouts when the pref is enabled" src="https://servo.org/img/blog/layout-2020-tables.png" /></a></figure>
<p>We’ve started working on support for <strong>sticky positioning</strong> and <strong>tables</strong> in the new layout engine, with some very early sticky positioning code landing in 2023-11-30 (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30686">#30686</a>), the CSS tables tests now enabled (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31131">#31131</a>), and rudimentary table layout landing in 2024-01-20 under the <code>layout.tables.enabled</code> pref (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/Loirooriol">@Loirooriol</a>, <a href="https://github.com/Manishearth">@Manishearth</a>, <a href="https://github.com/servo/servo/pull/30799">#30799</a>, <a href="https://github.com/servo/servo/pull/30868">#30868</a>, <a href="https://github.com/servo/servo/pull/31121">#31121</a>).</p>
<p>Geometry in our new layout engine is now being migrated from floating-point coordinates (<code>f32</code>) to <strong>fixed-point coordinates</strong> (<code>i32</code> × 1/60) (<a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/servo/pull/30825">#30825</a>, <a href="https://github.com/servo/servo/pull/30894">#30894</a>, <a href="https://github.com/servo/servo/pull/31135">#31135</a>), similar to other engines like WebKit and Blink.
While floating-point geometry was thought to be better for transformation-heavy content like SVG, the fact that larger values are less precise than smaller values causes a variety of rendering problems and test failures (<a href="https://github.com/servo/servo/issues/29819">#29819</a>).</p>
<p>As a result of these changes, we’ve made big strides in our WPT pass rates:</p>
<ul>
<li><strong>CSS2 floats</strong> (+3.3pp to 84.9%) and <strong>floats-clear</strong> (+5.6pp to 78.9%) continue to surge</li>
<li>we now surpass legacy layout in the <strong>CSS2 linebox</strong> tests (<strong>61.1% → 87.9%</strong>, legacy 86.4%)</li>
<li>we now surpass legacy layout in the <strong>css-flexbox</strong> tests (49.5% → 52.7%, legacy 52.2%)</li>
<li>we’ve closed 76% of the gap in <strong>key CSS2 tests</strong> (79.2% → 82.2%, legacy 83.1%)</li>
</ul>
<h3>Updates, servoshell, and stability <a class="header-anchor" href="https://servo.org/blog/2024/01/26/two-months-in-servo/#updates%2C-servoshell%2C-and-stability">
<span class="icon hashlink"><i class="fas fa-link"></i></span>
</a></h3>
<p><strong>GStreamer</strong> has been updated from 0.15 to 0.21 (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30750">#30750</a>), fixing long-standing breakage of video playback.
<strong>WebGPU</strong> has been updated from 0.17 to 0.18 (<a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/servo/servo/pull/30926">#30926</a>, <a href="https://github.com/servo/servo/pull/30954">#30954</a>), and <strong>ANGLE</strong> has been updated from <a href="https://chromium.googlesource.com/angle/angle/+/refs/heads/chromium/3729">April 2019</a> to <a href="https://chromium.googlesource.com/angle/angle/+/refs/heads/chromium/5359">August 2023</a> (<a href="https://github.com/sagudev">@sagudev</a>, <a href="https://github.com/servo/servo/pull/30546">#30546</a>).</p>
<figure class="_figr"><a href="https://servo.org/img/blog/back-forward.png"><img alt="Servo nightly showing Back and Forward buttons in the minibrowser" src="https://servo.org/img/blog/back-forward.png" /></a></figure>
<p>Servo’s example browser now has <strong>Back and Forward buttons</strong> (<a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/servo/pull/30805">#30805</a>), and no longer shows the incorrect location when navigation takes a long time (<a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/servo/pull/30518">#30518</a>).</p>
<p>Many stability improvements have landed, including fixes for a crash in inline layout (<a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/servo/pull/30897">#30897</a>), three WebGPU-related crashes (<a href="https://github.com/lucasMontenegro">@lucasMontenegro</a>, <a href="https://github.com/gterzian">@gterzian</a>, <a href="https://github.com/Taym95">@Taym95</a>, <a href="https://github.com/servo/servo/pull/30888">#30888</a>, <a href="https://github.com/servo/servo/pull/30989">#30989</a>, <a href="https://github.com/servo/servo/pull/31002">#31002</a>), a crash in the PerformanceResourceTiming API (<a href="https://github.com/delan">@delan</a>, <a href="https://github.com/servo/servo/pull/31063">#31063</a>), and several crashes due to script runtimes being dropped in the wrong order (<a href="https://github.com/gterzian">@gterzian</a>, <a href="https://github.com/servo/servo/pull/30896">#30896</a>).</p>
<h3>CI, code health, and dev changes <a class="header-anchor" href="https://servo.org/blog/2024/01/26/two-months-in-servo/#ci%2C-code-health%2C-and-dev-changes">
<span class="icon hashlink"><i class="fas fa-link"></i></span>
</a></h3>
<p>The intermittent macOS build failures on CI should now be fixed (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30975">#30975</a>).</p>
<p>Servo now has some preliminary Android build support (<a href="https://github.com/mukilan">@mukilan</a>, <a href="https://github.com/servo/servo/pull/31086">#31086</a>), though more work needs to be done before Servo will run on Android.</p>
<p>The long-term effort to simplify how Servo is built continues (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31075">#31075</a>), and we’ve replaced the <code>time</code> crate with <code>chrono</code> and <code>std::time</code> in much of Servo (<a href="https://github.com/Taym95">@Taym95</a>, <a href="https://github.com/augustebaum">@augustebaum</a>, <a href="https://github.com/servo/servo/pull/30927">#30927</a>, <a href="https://github.com/servo/servo/pull/31020">#31020</a>, <a href="https://github.com/servo/servo/pull/30639">#30639</a>, <a href="https://github.com/servo/servo/pull/31079">#31079</a>).
We have also started migrating our DOM bindings to use typed arrays where possible (<a href="https://github.com/gterzian">@gterzian</a>, <a href="https://github.com/servo/servo/pull/30990">#30990</a>, <a href="https://github.com/servo/servo/pull/31077">#31077</a>, <a href="https://github.com/servo/servo/pull/31087">#31087</a>, <a href="https://github.com/servo/servo/pull/31076">#31076</a>, <a href="https://github.com/servo/servo/pull/31106">#31106</a>), as part of an effort to <strong>reduce our unsafe code surface</strong> (<a href="https://github.com/servo/servo/issues/30889">#30889</a>, <a href="https://github.com/servo/servo/issues/30862">#30862</a>).</p>
<p>Several crates have been moved into <a href="https://github.com/servo/servo">our main repo</a>:</p>
<ul>
<li><code>hyper_serde</code> (<a href="https://github.com/servo/hyper_serde">servo/hyper_serde</a>) was moved to <code>components/hyper_serde</code> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30803">#30803</a>)</li>
<li><code>device</code> (<a href="https://github.com/servo/devices">servo/devices</a>) was merged into <code>components/bluetooth</code> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30974">#30974</a>)</li>
<li><code>blurmac</code> (<a href="https://github.com/servo/devices">servo/devices</a>) was moved to <code>third_party/blurmac</code> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30974">#30974</a>)</li>
</ul>
<p>We’ve also made some dev changes:</p>
<ul>
<li>the default branch in <a href="https://github.com/servo/servo">our main repo</a> is now <code>main</code> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/atouchet">@atouchet</a>, <a href="https://github.com/servo/servo/commit/23add0c1e5c9cbdf0301b891d265e363d049532b">23add0c1e5c9c</a>, <a href="https://github.com/servo/servo/pull/30877">#30877</a>)</li>
<li>we now target <strong>Rust 1.74</strong> stable, marking the first time ever we have built without unstable features (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/30831">#30831</a>)</li>
<li>we now require <strong>Python 3.10</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31088">#31088</a>), and you no longer need to install virtualenv (<a href="https://github.com/frewsxcv">@frewsxcv</a>, <a href="https://github.com/servo/servo/pull/30377">#30377</a>)</li>
<li>we’ve fixed problems building Servo on <strong>Ubuntu 20.04</strong> (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31019">#31019</a>) and <strong>NixOS</strong> (<a href="https://github.com/delan">@delan</a>, <a href="https://github.com/servo/servo/pull/31052">#31052</a>, <a href="https://github.com/servo/servo/pull/31055">#31055</a>, <a href="https://github.com/servo/servo/pull/30987">#30987</a>)</li>
<li>we now support <strong>Visual Studio 2022</strong> on Windows (<a href="https://github.com/mrobinson">@mrobinson</a>, <a href="https://github.com/servo/servo/pull/31148">#31148</a>), the same version that rustup installs by default</li>
</ul>
<h4>Linux build issues <a class="header-anchor" href="https://servo.org/blog/2024/01/26/two-months-in-servo/#linux-build-issues">
<span class="icon hashlink"><i class="fas fa-link"></i></span>
</a></h4>
<p>Several people have reported problems building Servo on newer Linux distro versions, particularly <a href="https://github.com/servo/servo/issues/31059">with clang 15</a> or <a href="https://github.com/servo/servo/issues/30587">with clang 16</a>.
While we’re still working on fixing the underlying issues, there are some workarounds.
If your distro lets you install older versions of clang with a package like <code>clang-14</code>, you can tell Servo to use it with:</p>
<pre><code>export CC=/usr/bin/clang-14
export CXX=/usr/bin/clang++-14
</code></pre>
<p>Alternatively you can try our new Nix-based dev environment, which should now work on any Linux distro (<a href="https://github.com/delan">@delan</a>, <a href="https://github.com/servo/servo/pull/31001">#31001</a>).
<a href="https://nixos.org/manual/nix/stable/">Nix</a> is a package manager with some unusual benefits.
Servo can use Nix to find the correct versions of all of its compilers and build dependencies without needing you to install them or run <code>mach bootstrap</code>.
All you need to do is install Nix, and <code>export MACH_USE_NIX=</code> to your environment.
<a href="https://github.com/servo/servo/wiki/Building#nix-on-other-distros">See the wiki</a> for more details!</p>2024-01-26T00:00:00+00:00Firefox Developer Experience: Firefox WebDriver Newsletter — 122
https://fxdx.dev/firefox-webdriver-newsletter-122/
<p id="block-d9f14d93-e0ec-44b4-b661-97bf385e01de"><em>WebDriver is a remote control interface that enables introspection and control of user agents. As such it can help developers to verify that their websites are working and performing well with all major browsers. The protocol is standardized by the <a href="https://www.w3.org/">W3C</a> and consists of two separate specifications: <a href="https://w3c.github.io/webdriver/">WebDriver classic</a> (HTTP) and the new <a href="https://w3c.github.io/webdriver-bidi/">WebDriver BiDi </a>(Bi-Directional).</em></p>
<p id="block-657c8643-6b93-4546-8626-3d7c3976c217"><em>This newsletter gives an overview of the work we’ve done as part of the Firefox 122 release cycle</em>.</p>
<h3>Contributions</h3>
<p id="block-9278fa20-63dc-4975-a72b-e3ba73b202a4">With Firefox being an open source project, we are grateful to get contributions from people outside of Mozilla.</p>
<p id="block-f6e2b9b0-63b6-4a4b-aeea-cffbde1019dd">WebDriver code is written in JavaScript, Python, and Rust so any web developer can contribute! Read <a href="https://firefox-source-docs.mozilla.org/devtools/getting-started/README.html">how to setup the work environment</a> and check <a href="https://codetribute.mozilla.org/projects/automation">the list of mentored issues</a> for Marionette.</p>
<h3>General</h3>
<p>The modifications outlined in this section are applicable to both WebDriver BiDi and Marionette, as both implementations utilize a shared set of common code:</p>
<ul>
<li>Fixed a bug that <a href="https://bugzil.la/1864614">prevented Perform Actions to correctly synthesize double and other multi-click events</a> for the <code>mouse</code> input source. Additionally, <a href="https://bugzil.la/1681076">these events will only be emitted when the actual mouse position has not changed</a> since the last click action.</li>
<li>The <a href="https://bugzil.la/1863687">definitions for the <code>Pause</code> and <code>Equal</code> (Numpad block) keys have been updated</a> to align with the WebDriver specification.</li>
</ul>
<h3>WebDriver BiDi</h3>
<h4>New: Support for the “browsingContext.traverseHistory” command</h4>
<p>The <a href="https://bugzil.la/1841018"><code>browsingContext.traverseHistory</code> command</a> enables clients to navigate pages within a specified browsing context backward and forward in history, similar to a user clicking the back and forward buttons in the browser’s toolbar. The command expects a <code>delta</code> number argument to specify how many history steps to traverse. For instance to jump forward to the next page, <code>delta</code> should be set to <code>1</code>. To navigate back 3 steps – and therefore skip 2 entries – <code>delta</code> should be <code>-3</code>, as in the example below:</p>
<pre class="wp-block-code"><code>{
"id": 68,
"method": "browsingContext.traverseHistory",
"params": {
"context":"4143d9c5-09bd-4491-816c-8c8a50f89ab2",
"delta": -3
}
}</code></pre>
<h4>Updates for the browsingContext.setViewport command</h4>
<p>In preparation for the addition of emulating the device pixel ratio (DPR) in <a href="https://bugzil.la/1865618">the <code>browsingContext.setViewport</code> command, a variant was needed to retain the current viewport size</a> of the specified top-level browsing context. Using <code>null</code> as a value for the <code>viewport</code> argument, which is already supported, resets the view port to its original size. Omitting the argument instead ensures that the viewport size remains unchanged.</p>
<h4>Bug Fixes</h4>
<ul>
<li>The <a href="https://bugzil.la/1867667">serialization of <code>WindowProxy</code> remote objects now also works correctly for out-of-process iframes</a>.</li>
<li><a href="https://bugzil.la/1869735">Fixed a bug in all supported network events where the <code>context</code> id consistently reported the top-level browsing context</a>, even when the navigation occurred within an iframe.</li>
</ul>
<h3>Marionette (WebDriver classic)</h3>
<h4>Bug Fixes</h4>
<ul>
<li><a href="https://bugzil.la/1824664">Fixed a regression with Get Element Text</a>, where the command was incorrectly returning an empty text when the element was located within a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement">ShadowRoot’s slot</a>.</li>
</ul>2024-01-23T17:15:18+00:00Henrik SkupinFirefox Nightly: Happy New Year – These Weeks in Firefox: Issue 152
https://blog.nightly.mozilla.org/2024/01/22/happy-new-year-these-weeks-in-firefox-issue-152/
<h3>Highlights</h3>
<ul>
<li>Sam is currently working to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1789727">enabling the new Screenshots component on Nightly</a>
<ul>
<li>This is a replacement for the extension implementation. The component should have full feature parity, and have improved performance and accessibility.</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1801954">New keyboard accessibility</a> has been added to the screenshots component. The selected region can now be moved/adjusted with the keyboard.</li>
<li>Until this is on by default, you can enable it manually by setting screenshots.browser.component.enabled to true in about:config.</li>
<li>Please file any bugs <a href="https://bugzilla.mozilla.org/enter_bug.cgi?assigned_to=nobody%40mozilla.org&blocked=1696573&bug_ignored=0&bug_severity=--&bug_status=NEW&bug_type=defect&cf_a11y_review_project_flag=---&cf_accessibility_severity=---&cf_fx_iteration=---&cf_fx_points=---&cf_has_str=---&cf_install_update_workflow=---&cf_performance_impact=---&cf_status_firefox121=---&cf_status_firefox122=---&cf_status_firefox123=---&cf_status_firefox_esr115=---&cf_tracking_firefox121=---&cf_tracking_firefox122=---&cf_tracking_firefox123=---&cf_tracking_firefox_esr115=---&cf_tracking_firefox_relnote=---&cf_webcompat_priority=---&component=Screenshots&contenttypemethod=list&contenttypeselection=text%2Fplain&defined_groups=1&filed_via=standard_form&flag_type-203=X&flag_type-37=X&flag_type-41=X&flag_type-607=X&flag_type-708=X&flag_type-721=X&flag_type-737=X&flag_type-748=X&flag_type-787=X&flag_type-799=X&flag_type-803=X&flag_type-846=X&flag_type-855=X&flag_type-864=X&flag_type-930=X&flag_type-936=X&flag_type-937=X&flag_type-963=X&needinfo_role=other&needinfo_type=needinfo_from&op_sys=Unspecified&priority=--&product=Firefox&rep_platform=Unspecified&target_milestone=---&version=unspecified">here</a></li>
</ul>
</li>
<li>Lee Salzman (:lsalzman) landed off-main-thread canvas for macOS, Linux and Android back in December for Firefox 123 – and that’s given us a 4-7% boost on Speedometer3! More details <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1829026#c30">here</a>.</li>
<li>Telemetry informs us that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1818237">the Ubuntu Snap import wizard improvements we landed late last year</a> have more than <b>doubled</b> the number of users that have successfully imported from another browser when Firefox is installed as a Snap package!</li>
<li>In the Network Monitor with Firefox DevTools, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1353798">Hubert has made it so that right-clicking a network request allows you to “Save Response As”</a> for any request, instead of just images
<ul>
<li><img src="https://blog.nightly.mozilla.org/files/2024/01/headlines152_0.png" /></li>
</ul>
</li>
</ul>
<h3>Friends of the Firefox team</h3>
<h4>Introductions/Shout-Outs</h4>
<ul>
<li>[jepstein] <a href="mailto:ini@mozilla.com"><span>Irene Ni</span></a> joins the Front-end team through April. Welcome! She is starting on the Reader View work with Cieara, Sam, and Fred.</li>
</ul>
<h4><a href="https://bugzilla.mozilla.org/buglist.cgi?title=Resolved%20bugs%20%28excluding%20employees%29&quicksearch=1867610%2C1872012%2C1872116%2C1461755%2C1870498%2C1852961%2C1861372%2C1872824%2C1843720%2C1764694%2C1221964&list_id=16852419">Resolved bugs (excluding employees)</a></h4>
<h4>Volunteers that fixed more than one bug</h4>
<ul>
<li>Gregory Pappas [:gregp]</li>
<li>Javi Rueda :javirid</li>
</ul>
<h4>New contributors (🌟 = first patch)</h4>
<ul>
<li>🌟 Aaron <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1221964">replaced netmonitor ‘Save Image As’ with ‘Save Response As’</a> in context menu</li>
<li>Eliot Jacobs <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1843720">fixed typo in comment: extension.webextensions.remote</a> to extensions.webextensions.remote in RemoteWorkerManager.cpp</li>
<li>🌟 Kate Galich <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1867610">updated browser/themes/shared/autocomplete.css</a> to use CSS nesting</li>
</ul>
<h3>Project Updates</h3>
<h4>Add-ons / Web Extensions</h4>
<h5>Addon Manager & about:addons</h5>
<ul>
<li>Landed a fix to prevent AddonRepository.sys.mjs from mistakenly clearing add-ons metadata (stored in ProfD/addons.json) when an addon metadata refresh request is triggered while Gecko is disconnected from the network – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870905">Bug 1870905</a></li>
</ul>
<ul>
<li>Thanks to Hartmut Welpmann for fixing addon updates error handling of empty results and improving logging – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1861372">Bug 1861372</a></li>
</ul>
<h5>WebExtensions Framework</h5>
<ul>
<li>Thanks to Gregory Pappas for contributing a fix to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870498">Bug 1870498</a> and fix a regression that was preventing extensions content scripts from accessing getCoalescedEvents() after it has been marked as only available to Secure Contexts</li>
</ul>
<h5>WebExtension APIs</h5>
<ul>
<li>Thanks to Cimbali for contributing changes to ContextualIdentityService.sys.mjs internals and the WebExtensions contextualIdentities API to introduce a new method that allows extensions to reorder the defined containers – <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1333395">Bug 1333395</a></li>
</ul>
<h4>Developer Tools</h4>
<ul>
<li>Aaron expanded the “Save as File” context menu to all types of Network responses in Netmonitor (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1221964">bug</a>). It was only enabled for images before.</li>
<li>Emilio fixed a styling issues on tooltips (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1872983">bug</a>)</li>
<li>Alex added the ability to show a link to the original source when selecting a location in a bundle in the Debugger(<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1834729">bug</a>)</li>
<li>Nicolas fixed a few issues on the Preview popup in the Debugger (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1872715">bug</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873147">bug</a>)</li>
</ul>
<h4>Fluent</h4>
<ul>
<li><a href="https://www.arewefluentyet.com/">Almost 66% of all strings in Firefox are now using Fluent!</a> .properties usage is seeing a slow, steady decline.</li>
</ul>
<h4>ESMification status</h4>
<ul>
<li>ESMified status:
<ul>
<li>browser: 89%</li>
<li>toolkit: 99%</li>
<li>Total: 96.48% (no change)</li>
</ul>
</li>
<li>#esmification on Matrix</li>
</ul>
<h4>Lint, Docs and Workflow</h4>
<ul>
<li>The whitespace and file permission linters <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1872857">now run on json files</a>.</li>
<li>We have updated various <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1873158">ESLint plugins (node modules) to their latest versions as</a> part of working towards <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1872685">upgrading ESLint to v9</a>.
<ul>
<li>v9 is changing to the <a href="https://eslint.org/blog/2023/12/eslint-v9.0.0-alpha.0-released/#flat-config-is-now-the-default-and-has-some-changes">new “flat” configuration</a>. This changes the formats of plugins as well as the main configuration, which will help to fix some long standing issues.</li>
<li>Due to this change, we will be making some significant changes to how ESLint is configured across the tree over the coming months.</li>
</ul>
</li>
</ul>
<h4>Migration Improvements</h4>
<ul>
<li>Device migration
<ul>
<li>We sent out a spotlight message a few weeks ago encouraging users without a Mozilla account and lots of local data (like bookmarks, history, passwords, etc) that they can use a Mozilla account to have an end-to-end encrypted copy of that data in the cloud. This targeted clients in the English, Italian, French and German locales. We’re going to be doing the rest of the locales later this month, and include folks on the 115 ESR branch as well.</li>
<li>mconley <a href="https://phabricator.services.mozilla.com/D195934">has a prototype component</a> that can create periodic snapshots of SQLite databases, which could end up being the basis of a local profile backup at runtime system.</li>
</ul>
</li>
</ul>
<h4>New Tab Page</h4>
<ul>
<li>The ASRouterAdmin code has been moved out from about:newtab. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1866802">It now lives at about:asrouter</a>. The DiscoveryStream tools still remain in about:newtab.</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1868194">Patches are up to convert TelemetryFeed.jsm to an ESM</a> (which involved rewriting TelemetryFeed.test.js as an xpcshell test)</li>
</ul>
<h4>Performance</h4>
<ul>
<li>The off-main-thread Windows Jump List backend is currently enabled by default on Nightly, and the code to support it has ridden the trains to Beta 122. When that code reaches the Release channel after January 23rd, we plan to run an experiment to see if there’s a measurable improvement to input event response time with it enabled.</li>
</ul>
<h4>Screenshots</h4>
<ul>
<li>Niklas made the following fixes/enhancements
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1854953">improved performance when taking large screenshots</a>
<ul>
<li>We now take multiple smaller screenshots instead of one giant screenshot which was causing the browser to hang</li>
</ul>
</li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1855313">selected region now shows size on screenshots overlay</a>
<ul>
<li>Can now see the size of the selected region
<ul>
<li><img src="https://blog.nightly.mozilla.org/files/2024/01/headlines152_1.png" /></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Search and Navigation</h4>
<ul>
<li>Mike Kaply <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1870138">added support for overriding search engine URLs from remote settings</a></li>
<li>Search engine result page telemetry
<ul>
<li>Stephanie <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1854196">modified categorization logic based on input from Data Science</a></li>
<li>James made us <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1871083">record additional properties of the categorization impression to a placeholder API</a></li>
</ul>
</li>
<li>Lots of test fixes, see the <a href="https://bugzilla.mozilla.org/buglist.cgi?chfield=resolution&chfieldfrom=-14D&chfieldto=Now&classification=Client%20Software&classification=Developer%20Infrastructure&classification=Components&classification=Server%20Software&classification=Other&columnlist=short_desc%2Cpriority%2Cassigned_to%2Ccf_fx_points%2Cresolution%2Ccomponent%2Creporter%2Ccf_fx_iteration&component=Address%20Bar&component=Search&known_name=Fixed%20last%2014D&product=Firefox&product=Toolkit&resolution=FIXED&order=bug_id&list_id=16852447">full bug list</a> if you’re curious</li>
</ul>
<h3>Below the fold</h3>
<ul>
<li>[standard8] PromiseUtils.defer() <a href="https://groups.google.com/a/mozilla.org/g/firefox-dev/c/gwH_bpGsGdM/m/pR3A4d1GAAAJ">has been replaced</a> by <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers">Promise.withResolvers()</a></li>
<li>General triage
<ul>
<li>This month’s <a href="https://docs.google.com/document/d/1_r8lKtJg1FXeY9R3mufsQKI3ylXiIrrLgsb3DqC0EoA/edit">Firefox / Toolkit :: General triagers</a> are:
<ul>
<li>Gijs, Dão, Niklas, Kelly</li>
</ul>
</li>
</ul>
</li>
</ul>2024-01-22T17:30:25+00:00Niklas BaumgardnerMozilla Thunderbird: January 2024 Community Office Hours: Context Menu Updates
https://blog.thunderbird.net/2024/01/january-2024-thunderbird-community-office-hours-how-to-join-us/
<p><img alt="The blue Thunderbird is circled around a heart created by clasped hands, in the featured image for the Thunderbird Community Office Hours blog post." class="attachment-640x360 size-640x360 wp-post-image" height="320" src="https://blog.thunderbird.net/files/2024/01/Community-Default.png" width="640" /></p>
<p><strong>UPDATE: Our January Office Hours was fantastic! Here’s the full video replay.</strong></p>
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<h3>A New Year of New Office Hours</h3>
<p>We’re back from our end of year break, breaking in our new calendars, and ready to start 2024 with our renewed, refreshed, and refocused community office hours. Thank you to everyone who joined us for our November session! If you missed out on our chat about the new Cards View and the Thunderbird design process, you can find the video (which also describes the new format) in this <a href="https://blog.thunderbird.net/2023/11/upcoming-thunderbird-community-office-hours/">blog post</a>. </p>
<p>We’re excited for another year of bringing you expert insights from the Thunderbird Team and our broader community. To kick off 2024, and to build on November’s excellent discussion, we’ll be continuing our dive into another important aspect of the Thunderbird design process.</p>
<h3>January Office Hours Topic: Message Context Menu</h3>
<figure class="wp-block-image size-full"><a href="https://blog.thunderbird.net/files/2024/01/tb-context-menu-design-plan.png"><img alt="The image shows a mock-up of a nested Thunderbird context menu, with the Organize menu option opening to a menu that lists, from top to bottom, Tag, Archive, Move To, Copy To, Convert To. Tag has been chosen in this mock up, and from top to bottom, this menu lists New Tag, Manage Tags, Remove All Tags, Important, Work, Personal, To Do, Later. The tags all have a color-coded tag icon to their left." class="wp-image-1498" height="957" src="https://blog.thunderbird.net/files/2024/01/tb-context-menu-design-plan.png" width="1183" /></a><figcaption class="wp-element-caption">Mock-up: designs shown are not final and subject to change. </figcaption></figure>
<p>We’ve been working on some significant (and what we think are pretty fantastic) UI changes to Thunderbird. Besides the new Cards View, we have some exciting overhauls to the Message Context Menu (aka the right-click menu) planned. UX Engineer Elizabeth Mitchell will discuss these changes, and most importantly, <em>why </em>we’re making them. Additionally, Elizabeth is one of the leaders on making Thunderbird accessible for all! We’re excited to hear how the new Message Context Menu will make your email experience easier and more effective.</p>
<p>If you’d like a sneak peak of the Context Menu plans, you can find them <a href="https://thunderbird.topicbox.com/groups/ux/T3d84faa372bf41a8">here</a>.</p>
<p>And as always, if you have any questions you’d like to ask during the January office hours, you can e-mail them to <a href="mailto:officehours@thunderbird.net">officehours@thunderbird.net</a>.</p>
<h3>Join Us On Zoom</h3>
<p>(Yes, we’re still on Zoom for now, but a Jitsi server for future office hours is in the works!)</p>
<p><strong>When</strong>: <strong><a href="https://time.is/1800_25_Jan_2024_in_UTC?January_25_Thunderbird_Community_Office_Hours">January 25 at 18:00 UTC</a></strong></p>
<p><strong>Direct URL To Join:</strong> <a href="https://mozilla.zoom.us/j/92739888755">https://mozilla.zoom.us/j/92739888755</a><br />Meeting ID: 92739888755<br />Password: 365021</p>
<p><strong>Dial by your location:</strong></p>
<ul>
<li>+1 646 518 9805 US (New York)</li>
<li>+1 669 219 2599 US (San Jose)</li>
<li>+1 647 558 0588 Canada</li>
<li>+33 1 7095 0103 France</li>
<li>+49 69 7104 9922 Germany</li>
<li>+44 330 088 5830 United Kingdom</li>
<li>Find your local number:<a href="https://mozilla.zoom.us/u/adkUNXc0FO"> https://mozilla.zoom.us/u/adkUNXc0FO</a></li>
</ul>
<p>The call will be recorded and this post updated with a link to the recording afterwards.</p>
<h3>Stay Informed About Future Thunderbird Releases and Events</h3>
<p>Want to be notified about upcoming releases AND Community Office Hours? Subscribe to the <a href="https://calendar.google.com/calendar/embed?src=c_f7b7f2cea6f65593ef05afaf2abfcfb48f87e25794468cd4a19d16495d17b6d1%40group.calendar.google.com&ctz=America%2FNew_York">Thunderbird Release and Events Calendar</a>!</p>
<figure class="wp-block-image size-large"><a href="https://blog.thunderbird.net/files/2024/01/EOY-FB-Mastodon-Lanscape.jpg"><img alt="" class="wp-image-1489" height="315" src="https://blog.thunderbird.net/files/2024/01/EOY-FB-Mastodon-Lanscape-600x315.jpg" width="600" /></a></figure>
<p>The post <a href="https://blog.thunderbird.net/2024/01/january-2024-thunderbird-community-office-hours-how-to-join-us/">January 2024 Community Office Hours: Context Menu Updates</a> appeared first on <a href="https://blog.thunderbird.net">The Thunderbird Blog</a>.</p>2024-01-19T19:09:07+00:00Monica Ayhens-MadonMozilla Open Policy & Advocacy Blog: Platform Tilt: Documenting the Uneven Playing Field for an Independent Browser Like Firefox
https://blog.mozilla.org/netpolicy/2024/01/19/platform-tilt/
<p>Browsers are the principal gateway connecting people to the open Internet, acting as their <a href="https://www.mozilla.org/en-US/about/webvision/full/#agency">agent</a> and shaping their experience. The central role of browsers has long motivated us to build and improve Firefox in order to offer people an independent choice. However, this centrality also creates a strong incentive for dominant players to control the browser that people use. The right way to win users is to build a better product, but shortcuts can be irresistible — and there’s a long history of companies leveraging their control of devices and operating systems to tilt the playing field in favor of their own browser.</p>
<p>This tilt manifests in a variety of ways. For example: making it harder for a user to download and use a different browser, ignoring or resetting a user’s default browser preference, restricting capabilities to the first-party browser, or requiring the use of the first-party browser engine for third-party browsers.</p>
<p>For years, Mozilla has engaged in dialog with platform vendors in an effort to address these issues. With renewed public attention and an evolving regulatory environment, we think it’s time to publish these concerns using the same transparent process and tools we use to <a href="https://github.com/mozilla/standards-positions">develop positions</a> on emerging technical standards. So today we’re publishing a new <a href="https://mozilla.github.io/platform-tilt/">issue tracker</a> where we intend to document the ways in which platforms put Firefox at a disadvantage and engage with the vendors of those platforms to resolve them.</p>
<p>This tracker captures the issues we experience developing Firefox, but we believe in an even playing field for everyone, not just us. We encourage other browser vendors to publish their concerns in a similar fashion, and welcome the engagement and contributions of other non-browser groups interested in these issues. We’re particularly appreciative of the efforts of <a href="https://open-web-advocacy.org/">Open Web Advocacy</a> in articulating the case for a level playing field and for documenting self-preferencing.</p>
<p>People deserve choice, and choice requires the existence of viable alternatives. Alternatives and competition are good for everyone, but they can only flourish if the playing field is fair. It’s not today, but it’s also not hard to fix if the platform vendors wish to do so.</p>
<p>We call on Apple, Google, and Microsoft to engage with us in this new forum to speedily resolve these concerns.</p>
<p>The post <a href="https://blog.mozilla.org/netpolicy/2024/01/19/platform-tilt/">Platform Tilt: Documenting the Uneven Playing Field for an Independent Browser Like Firefox</a> appeared first on <a href="https://blog.mozilla.org/netpolicy">Open Policy & Advocacy</a>.</p>2024-01-19T14:05:36+00:00MozillaThe Servo Blog: Tauri update: embedding prototype, offscreen rendering, multiple webviews, and more!
https://servo.org/blog/2024/01/19/embedding-update/
<p><a href="https://servo.org/blog/2023/11/30/embedding-floats-color-mix/">Back in November</a>, we highlighted our ongoing efforts to make Servo more embeddable, and today we are a few steps closer!</p>
<p><a href="https://tauri.app/">Tauri</a> is a framework for building desktop apps that combine a web frontend with a Rust backend, and work is already ongoing to expand it to mobile apps and other backend languages.
But unlike say, Electron or React Native, Tauri is both engine-agnostic and frontend-agnostic, allowing you to use any frontend tooling you like and whichever web engine makes the most sense for your users.</p>
<p>To integrate Servo with Tauri, we need to add <strong>support for Servo in <a href="https://github.com/tauri-apps/wry">WRY</a></strong>, the underlying webview library, and the developers of Tauri have created a proof of concept doing exactly that!
While this is definitely not production-ready yet, you can play around with it by checking out the <a href="https://github.com/tauri-apps/wry/tree/servo-wry-demo">servo-wry-demo</a> branch (<a href="https://github.com/tauri-apps/wry/tree/305220efbe4e8b5813543a7b8f5d8e0a8abb7fbc">permalink</a>) and following the README.</p>
<figure class="_fig" id="_wry_demo_fig">
</figure>
<p>While servoshell, <a href="https://servo.org/blog/2023/09/15/upcoming-events-and-new-browser-ui/">our example browser</a>, continues to be the “reference” for embedding Servo, this has its limitations in that servoshell’s needs are often simpler than those of a general-purpose embeddable webview.
For example, the “minibrowser” UI needs the ability to reserve space at the top of the window, and hook the presenting of new frames to do extra drawing, but it doesn’t currently need multiple webviews.</p>
<p>This is where working with the Tauri team has been especially invaluable for Servo — they’ve used their experience integrating with other embeddable webviews to guide changes on the Servo side.
Early changes include making it possible to <strong>position Servo webviews</strong> anywhere within a native window (<a href="https://github.com/wusyong">@wusyong</a>, <a href="https://github.com/servo/servo/pull/30088">#30088</a>), and give them <strong>translucent or transparent backgrounds</strong> (<a href="https://github.com/wusyong">@wusyong</a>, <a href="https://github.com/servo/servo/pull/30488">#30488</a>).</p>
<p>Support for <strong>multiple webviews</strong> in one window is needed for parity with the other WRY backends.
Servo currently has a fairly pervasive assumption that only one webview is active at a time.
We’ve found almost all of the places where this assumption was made (<a href="https://github.com/delan">@delan</a>, <a href="https://github.com/servo/servo/pull/30648">#30648</a>), and now we’re breaking those findings into changes that can actually be reviewed and landed (<a href="https://github.com/delan">@delan</a>, <a href="https://github.com/servo/servo/pull/30840">#30840</a>, <a href="https://github.com/servo/servo/pull/30841">#30841</a>, <a href="https://github.com/servo/servo/pull/30842">#30842</a>).</p>
<p>Support for <strong>multiple windows</strong> sounds similar, but it’s a lot harder.
Servo handles user input and drawing with a component known for historical reasons as the “compositor”.
Since the constellation — the heart of Servo — is currently associated with exactly one compositor, and the compositor is currently tightly coupled with the event loop of exactly one window, supporting multiple windows will require some big architectural changes.
<a href="https://github.com/paulrouget">@paulrouget</a>’s extensive research and prior work on making Servo embeddable will prove especially helpful.</p>
<p><strong>Offscreen rendering</strong> is critical for integrating Servo with apps containing non-Servo components.
For example, you might have a native app that uses Servo for online help or an OAuth flow, or a game that uses Servo for purchases or social features.
We can now draw Servo to an offscreen framebuffer and let the app decide how to present it (<a href="https://github.com/delan">@delan</a>, <a href="https://github.com/servo/servo/pull/30767">#30767</a>), rather than assuming control of the whole window, and servoshell now uses this ability except when the minibrowser is disabled (<code>--no-minibrowser</code>).</p>
<p><strong>Precompiling <a href="https://github.com/servo/mozangle">mozangle</a></strong> and <a href="https://github.com/servo/mozjs"><strong>mozjs</strong></a> would improve developer experience by reducing initial build times.
We can now build the C++ parts of mozangle as a dynamic library (.so/.dylib/.dll) on Linux and macOS (<a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/mozangle/pull/71">mozangle#71</a>), though more work is needed to distribute and make use of them.</p>
<p>We’re exploring two approaches to precompiling mozjs.
The easier approach is to build the C++ parts as a static library (.a/.lib) and cache the generated Rust bindings (<a href="https://github.com/wusyong">@wusyong</a>, <a href="https://github.com/servo/mozjs/issues/439">mozjs#439</a>).
Building a dynamic library (<a href="https://github.com/atbrakhi">@atbrakhi</a>, <a href="https://github.com/servo/mozjs/pull/432">mozjs#432</a>) will be more difficult, but it should reduce build times even further.</p>
<p>Many thanks to <a href="https://nlnet.nl/"><strong>NLnet</strong></a> for <a href="https://nlnet.nl/project/Tauri-Servo/">sponsoring this work</a>.</p>2024-01-19T00:00:00+00:00Adrian Gaudebert: L'état de l'Adrian 2023
http://adrian.gaudebert.fr/blog/post/L-%C3%A9tat-de-l-Adrian-2023
<p>L'année 2023 est terminée, donc comme depuis trois ans, c'est l'heure de dresser un bilan de ce que j'ai fait ces douze derniers mois. Je démarre cette retrospective avec la sensation de n'avoir « rien » fait, mais c'est parce que je me suis concentré essentiellement sur un seul et unique projet, notre jeu Dawnmaker. Vous allez le voir, l'année a en fait été bien chargée pour moi. En route pour le bilan !</p>
<h3>Projets principaux</h3>
<h4>Arpentor Studio</h4>
<p><a href="https://arpentor.studio"><img alt="" src="http://adrian.gaudebert.fr/blog/public/.Arpentor_s.png" style="float: right; margin: 0 0 1em 1em;" /></a></p>
<p>Notre société, cofondée avec Alexis, a stagné cette année. Nous sommes toujours deux, même si nous avons été trois à deux moments dans l'année, avec Aurélie au sound design en début d'année puis Agathe au UX / UI design pendant deux mois. Nous n'avons quasiment aucune entrée d'argent, nous ne nous payons pas, et avons également réduit au minimum les dépenses de fonctionnement pour tenir le plus longtemps possible.</p>
<p>Mécaniquement, la gestion du studio m'a demandé moins de temps cette année. J'ai dû faire un dossier de demande de solde pour une subvention de la Région, plusieurs itérations sur le budget de Dawnmaker pour des négociations (qui n'ont malheureusement mené à rien) avec un éditeur, et l'entretien administratif mensuel — envoyer les factures à notre expert-comptable, essentiellement.</p>
<p>La principale erreur sur laquelle j'ai appris, et redressé la barre, en 2023 porte sur la stratégie d'édition de notre jeu. Depuis début 2022, nous avons établi une feuille de route qui implique l'arrivée d'un éditeur, partenaire qui prend en charge le financement et la publication de Dawnmaker. C'est, je crois aujourd'hui, une erreur, <em>a fortiori</em> dans le contexte actuel de l'industrie du jeu vidéo : les éditeurs traversent une période de disette financière, liée à de nombreux facteurs — bulle financière de 2021 suite au COVID et à la forte augmentation des habitudes de jeu, de nombreuses très grosses sorties en 2023, décalées là aussi à cause du COVID, qui ont phagocyté les ventes de jeux indépendants, et bien sûr les taux d'intérêts bancaires qui ont explosé. Résultat, en 2023, les éditeurs sont frileux et il est devenu très difficile de leur vendre son jeu.</p>
<p>Baser la stratégie financière de son entreprise sur l'apport d'un partenaire externe, sur lequel nous n'avons aucun contrôle, me paraît donc un risque énorme. C'est pourtant la stratégie de l'immense majorité des studios de jeu vidéo aujourd'hui, pour une raison très simple : <a href="http://adrian.gaudebert.fr/blog/post/how-much-does-it-cost-to-make-a-game-like-dawnmaker3">ça coûte très cher de produire un jeu vidéo</a> ! De notre côté, nous avons la chance aujourd'hui de pouvoir travailler sans salaire, grâce notamment au RSA. C'est cependant une situation qui n'est ni enviable, ni viable sur le moyen terme.</p>
<p>Face à tous ces éléments, j'ai décidé de modifier notre stratégie pour Dawnmaker. Nous ne planifions plus le fait de trouver un éditeur. Notre plan principal, désormais, est de sortir le jeu nous-même (en « auto-édition »), dans un délai qui nous permet à la fois de le mener vers une qualité satisfaisante pour un produit commercial, et de ne pas nous couler financièrement. Nous avons donc deux échéances : début mars, nous devons avoir terminé la <em>vertical slice</em> du jeu, une version qui contient tous les systèmes du jeu mais avec une partie seulement de son contenu. C'est un produit de très bonne qualité, proche de l’état final attendu, et qui est donc représentatif de ce qu'on veut faire. On se donnera ensuite environ trois mois pour chercher à nouveau un éditeur, tout en menant une campagne marketing et en ajoutant quelques améliorations au jeu en fonction des retours de nos testeuses et testeurs. Si courant mai nous n'avons pas sécurisé de financement, nous sortirons alors le jeu nous-mêmes — très probablement fin juin. Ce sera une version « amputée » du jeu, loin du contenu que nous souhaiterions avoir, mais une version malgré tout fonctionnelle et de qualité professionnelle. Et bien sûr, si un éditeur s'engage sur notre jeu et le finance, nous reprendrons le plan secondaire, qui consiste à faire une vraie phase de production, recruter quelques personnes en plus, et sortir, probablement début 2025, une version complète du jeu.</p>
<p>En conclusion, Arpentor Studio avance, mais c'est difficile. 2024 sera une année décisive pour le studio, avec soit l'arrivée d'un éditeur pour notre premier jeu, soit sa sortie. Dans tous les cas, ça devrait faire entrer de l'argent dans l'entreprise, ce dont j'ai hâte !</p>
<h4>Dawnmaker</h4>
<p>Le projet Cities of Heksiga a changé de nom et s'appelle désormais <a href="https://arpentor.studio/fr/jeux/dawnmaker/">Dawnmaker</a> ! J'ai passé l'essentiel de mon année 2023 à travailler dessus, sur trois aspects principalement : la programmation, le Game Design — la conception des règles du jeu et de son contenu — et le marketing.</p>
<p style="text-align: center;"><a href="https://arpentor.studio/fr/jeux/dawnmaker"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/Truecapsule616x353.png" /></a></p>
<p>Dawnmaker a beaucoup changé pendant cette année. Le jeu est passé d'un rendu 2D très (très) basique à un rendu en 3D en début d'année, puis est revenu vers la 2D pendant l'été. Le passage du jeu vers la 3D était prévu de longue date, mais s'est avéré être une erreur. Quasiment tous les éditeurs à qui nous avons montré le jeu nous l'ont fait remarquer. La question qui nous a fait revenir en arrière a été : « quelle est la valeur ajoutée de la 3D pour le jeu ? » On a eu bien du mal à y répondre…</p>
<p>Nous avons donc fait machine arrière — pas vraiment, puisque j'en ai profité pour coder tout le rendu avec une nouvelle techno optimisée pour la 2D. Grand bien nous en a fait : le jeu est vraiment beaucoup plus beau maintenant ! Il tourne également mieux sur ma machine vieillissante, ce qui est un bon signe pour le sortir sur téléphones portables. J'ai aussi amélioré notre éditeur de contenu pour qu'Alexis soit le plus autonome possible sur l'intégration des assets des bâtiments.</p>
<p>Voici une petite fresque de la progression du jeu en 2023 :</p>
<p>
<a href="http://adrian.gaudebert.fr/blog/public/icones-billets/2023-01-12_Screenshot_of_Cities_of_Heksiga.png" target="_blank"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.2023-01-12_Screenshot_of_Cities_of_Heksiga_m.png" style="margin: 0 auto; display: table;" /></a>
</p>
<p style="text-align: center; font-style: italic;">En janvier</p>
<p>
<a href="http://adrian.gaudebert.fr/blog/public/icones-billets/2023-05-10_at_12.09.31.png" target="_blank"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.2023-05-10_at_12.09.31_m.png" style="margin: 0 auto; display: table;" /></a>
</p>
<p style="text-align: center; font-style: italic;">En mai</p>
<p>
<a href="http://adrian.gaudebert.fr/blog/public/icones-billets/2023-11-10_at_12.06.43.png" target="_blank"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.2023-11-10_at_12.06.43_m.png" style="margin: 0 auto; display: table;" /></a>
</p>
<p style="text-align: center; font-style: italic;">En novembre</p>
<p>Au delà de l'aspect graphique, nous avons ajouté beaucoup de contenu (une quarantaine de nouveaux bâtiments, une vingtaine de nouvelles cartes), des mécaniques importantes (notamment une boucle de progression à la roguelike), et beaucoup de choses pour améliorer la jouabilité du jeu (de nouvelles interfaces, notamment grâce aux contributions de <a href="https://www.amametz.fr/">Menica Folden</a>, du drag&drop pour jouer les cartes, des petites animations un peu partout… ).</p>
<p>Comme annoncé dans ma retrospective 2022, Dawnmaker a énormément progressé cette année, et il est passé d'un prototype à un vrai jeu vidéo. Il reste cependant encore beaucoup de choses à régler : la boucle de progression n'est toujours pas fonctionnelle, il n'y a aucun accompagnement à la prise en main pour les nouveaux joueurs, il faut retravailler encore une grosse partie de l'interface du jeu… Et tout ça, idéalement pour mars 2024 ! Autant vous dire que : c'est chaud. Mais la sortie du jeu approche, et ça, ça fait plaisir ! Peut-être que vous pourrez acheter Dawnmaker en 2024 ?</p>
<h3>Projets secondaires</h3>
<h4>Souls</h4>
<p>Comme l'année dernière, je n'ai quasiment pas eu l'occasion de toucher à Souls, mon vieux projet de jeu de cartes compétitif. Mais : « quasiment », car oui, je l'ai tout de même ressorti de sa boîte, et j'en ai fait une partie. Ça été l'occasion de me remémorer là où j'en étais, et surtout tous les défauts de la version en cours. Je ne travaille toujours pas activement dessus, mais j'ai bon espoir de m'y remettre un peu en 2024.</p>
<h4>Blog</h4>
<p>En début d'année, je me suis mis l'objectif de publier 6 articles sur ce blog, un tous les deux mois. L'objectif est presque atteint : j'en ai publié 5.</p>
<ul>
<li><a href="http://adrian.gaudebert.fr/blog/post/l-etat-de-l-adrian-2022">L'état de l'Adrian 2022</a></li>
<li><a href="http://adrian.gaudebert.fr/blog/post/how-much-does-it-cost-to-make-a-game-like-dawnmaker3">How much does it cost to make a game like Dawnmaker?</a></li>
<li><a href="http://adrian.gaudebert.fr/blog/post/Dawnmaker-s-endless-conundrum-of-infinite-replayability">Dawnmaker's endless conundrum of infinite replayability</a></li>
<li><a href="http://adrian.gaudebert.fr/blog/post/Removing-Dawnmaker-s-3rd-dimension">Removing Dawnmaker's 3rd dimension</a></li>
<li><a href="http://adrian.gaudebert.fr/blog/post/The-ruins-of-Dawnmaker-s-lost-continent">The ruins of Dawnmaker's lost continent</a></li>
</ul>
<p>La majorité de ces articles est en anglais, car ils ont également servi de contenu pour la <a href="https://arpentor.substack.com/">newsletter d'Arpentor Studio</a>, lancée cette année.</p>
<p>J'ai eu un peu de mal à me lancer dans l'écriture régulière, mais je me suis créé un système en cours d’année — en gros, un rappel tous les deux mois — et depuis, je m'y tiens correctement ! J’ai bon espoir de continuer sur ce rythme en 2024, pour continuer à partager avec vous mes expériences.</p>
<h4>Autres jeux</h4>
<p>En 2023 j'ai enfin rejoint une association locale de créateurs de jeux, la Compagnie des zAuteurs Lyonnais (CAL). C'est un groupement informel d'auteurs et autrices de jeux de société, qui se réunit dans les bars à jeux lyonnais régulièrement. Ce fût l'occasion pour moi d'enfin entrer dans ce milieu, de tester des prototypes très chouettes, et surtout de montrer les miens, de prototypes. Parce que oui, j'ai malgré tout continué à travailler, épisodiquement, sur des protos de jeux.</p>
<p>Le premier a pour nom de code « Little Brass Imhotep », car il est conçu pour être à la croisée des expériences de jeu de <a href="https://boardgamegeek.com/boardgame/241266/little-town">Little Town</a>, <a href="https://boardgamegeek.com/boardgame/224517/brass-birmingham">Brass: Birmingham</a> et <a href="https://boardgamegeek.com/boardgame/255674/imhotep-duel">Imhotep: The Duel</a>. Le concept central est le suivant : il y a un plateau de 5 par 5 cases, sur lequel les joueurs vont construire des bâtiments. Ces bâtiments peuvent être activés pour donner des ressources ou des points de victoire. Les joueurs disposent d'ouvriers, qu'ils vont placer à l’extrémité d'une ligne ou d'une colonne, et ce faisant vont activer tous les bâtiments de la ligne ou colonne. Construire un bâtiment permet de marquer des points de victoire et de créer ou d'améliorer un moteur, mais donne aussi des opportunités à l'adversaire de l'exploiter.</p>
<p>
<a href="http://adrian.gaudebert.fr/blog/public/icones-billets/2023-03-30_-_Proto_test_1_avec_Laura.jpg" target="_blank"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.2023-03-30_-_Proto_test_1_avec_Laura_m.jpg" style="margin: 0 auto; display: table;" /></a>
</p>
<p>Les premiers playtests ont fait apparaître de nombreuses lacunes dans le système de jeu, notamment une trop grande symétrie sur les ressources et les effets qui rend la mécanique principale, construire des bâtiments, peu attirante. Le prototype en est pour l'instant resté là.</p>
<p>Mon second prototype de l'année est né de la volonté de croiser l'expérience d'un draft de Magic — probablement mon expérience de jeu préférée — avec le cycle de <em>feedback</em> très court d'un autochess. La première version du jeu, nom de code « Cube Light » (oui je sais je suis nul en noms), donne ceci : sur une table de 8 joueurs, chacun⋅e reçoit un deck de 4 cartes (les mêmes pour chaque personne), puis va commencer à drafter des paquets de 4 cartes. Ensuite, chaque joueur se constitue un deck de 7 cartes, en jetant une de ses cartes. Puis on joue un match en 1 contre 1 : chaque joueur pioche trois cartes, puis simultanément va répartir ses 3 cartes, face cachée, sur trois lieux disposés au milieu de la table. Une fois les cartes placées, on les dévoile chacun son tour. Bien sûr, chaque carte a des effets variés, de même que les lieux, il faut donc placer ses cartes au bon endroit, et anticiper les prochaines cartes que l'on piochera, pour créer des combinaisons puissantes. À la fin du deuxième tour, la manche est terminée, et on compte la puissance cumulée des personnages joués sur chaque lieu. Un joueur qui a strictement plus de puissance que son adversaire sur un lieu contrôle celui-ci, et le joueur qui contrôle le plus de lieux gagne la manche. On recommence ensuite une nouvelle phase de draft, en ayant changé les places des joueurs. On construit un deck de 10 cartes, on fait une manche en trois tours. On répète ça sur 4 manches, et à la fin de la dernière manche le joueur qui a le plus de points de victoire remporte la partie !</p>
<p>
<a href="http://adrian.gaudebert.fr/blog/public/icones-billets/2023-08-20_-_Cube_Light_prototype.jpg" target="_blank"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.2023-08-20_-_Cube_Light_prototype_m.jpg" style="margin: 0 auto; display: table;" /></a>
</p>
<p>Je me suis rendu compte, pendant que je produisais ce prototype, que ça se rapproche énormément de <a href="https://boardgamegeek.com/boardgame/359970/challengers">Challengers</a>, un excellent jeu sorti en 2022, et dont le pitch est assez proche du mien — reproduire l'expérience d'un autochess en jeu de plateau. Mon objectif cependant est d'avoir une expérience plus proche de celle de Magic, c'est-à-dire d'avoir plus de décisions stratégiques, à la fois pendant le choix des cartes (la phase de draft) et pendant les manches.</p>
<p>Le premier playtest a laissé apparaître de nombreux axes d'améliorations, mais le cœur du jeu fonctionne bien et constitue une base solide. J'espère prendre du temps cette année pour reprendre ce prototype et en faire un jeu fun, au moins pour mon groupe de joueurs de Magic.</p>
<h3>Mes recommandations de l'année</h3>
<p>Et voilà pour le bilan de mon travail sur 2023 ! C'est l'heure de terminer ce bilan par une partie plus fun. Cette année à nouveau, j'aimerais vous partager les quelques découvertes culturelles que j'ai le plus appréciées ces douze derniers mois.</p>
<h4>Mon jeu vidéo de l'année</h4>
<p><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.bg3_m.jpg" style="float: right; margin: 0 0 1em 1em;" /></p>
<p>2023 a été une année pauvre en jeux vidéo pour moi. Peut-être est-ce le fait de passer mes journées à travailler sur un jeu qui m'empêche d'apprécier pleinement les autres ? Peut-être est-ce parce que j'ai utilisé beaucoup de mon temps de jeu à étudier des jeux en lien avec Dawnmaker ? Ou bien est-ce un simple concours de circonstances qui fait qu'aucun jeu ne m'a vraiment happé, ou marqué, cette année ?</p>
<p>Quoi qu'il en soit, le meilleur jeu auquel j'ai joué cette année est <a href="https://baldursgate3.game/">Baldur's Gate 3</a>. Je suis un immense fan des deux premiers titres, sur lesquels j'ai passé énormément de temps étant ado. J'abordais le troisième opus avec beaucoup d'appréhension, mais il ne m'a pas déçu. Le jeu donne vraiment la sensation de jouer à un Baldur's Gate pur jus, mais moderne. Certains personnages sont très attachants, l'histoire est prenante, et le contenu est gigantesque. C'est presque le seul vrai point noir pour moi d'ailleurs : je n'aime pas passer à côté de quelque chose dans un jeu, du coup j'ai passé trop de temps à tout fouiller. Et je sais que j'ai malgré ça raté des tas de choses, parce que le jeu est ainsi conçu.</p>
<p>Bref : Baldur's Gate 3 mérite son titre de Game of the Year.</p>
<h4>Mes jeux de plateau de l'année</h4>
<p>Trop difficile de choisir un seul jeu cette année, alors en voilà deux : Spirit Island et Brass: Birmingham ! Deux gros jeux, dans lesquels il faut beaucoup réfléchir, l'un coopératif et l'autre compétitif.</p>
<p><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.spiritisland1-2048x2048_s.jpg" style="float: left; margin: 0 1em 1em 0;" /></p>
<p><a href="https://boardgamegeek.com/boardgame/162886/spirit-island">Spirit Island</a>, jeu coopératif donc, vous met dans la peau des esprits protecteurs d'une île qui se fait envahir par des colons. Chaque esprit a un gameplay différent, des capacités spéciales, et un lot de cartes de départ uniques. En solo ou avec vos alliés, vous devez développer vos ressources (gagner plus d'énergie pour jouer vos cartes, obtenir de nouvelles cartes plus puissantes… ) et utiliser vos cartes pour détruire les envahisseurs, les empêcher de construire des villages ou des cités, et de répandre la désolation sur votre île luxuriante. C'est vraiment un jeu excellent, dans lequel chaque tour est un gros puzzle à plusieurs, où il y a des interactions entre les capacités des joueurs. Et bonus : sa complexité limite assez fortement l'effet « joueur alpha », quand un joueur dirige tous les autres.</p>
<p><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.birmingham1_s.jpg" style="float: right; margin: 0 0 1em 1em;" /></p>
<p><a href="https://boardgamegeek.com/boardgame/224517/brass-birmingham">Brass: Birmingham</a>, à l'inverse, est un jeu compétitif dans l'Angleterre de la révolution industrielle. Pur jeu de gestion, il faut y construire des bâtiments — mines de charbon, fonderies, usines, manufactures… — pour développer ses ressources et marquer des points de victoire. On y construit également des canaux ou chemins de fer, on y vend des ressources, et on s'adapte aux cartes de sa main pour se positionner sur la carte. Il y a un gros aspect planification qui est contrebalancé par l'importance d'être opportuniste par moment. Ce n'est pas le jeu <a href="https://boardgamegeek.com/browse/boardgame">numéro 1 sur boardgamegeek</a> pour rien !</p>
<h4>Ma BD de l'année</h4>
<p><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.nice-house-on-the-lake-8211-edition-integrale_s.jpg" style="float: left; margin: 0 1em 1em 0;" /></p>
<p><a href="https://www.urban-comics.com/nice-house-on-the-lake-edition-integrale/">The Nice House on the Lake</a>, tomes 1 et 2, gagnent la palme d'or de la BD 2023 ! C'est un comic — une bande dessinée américaine — de science fiction, un huit clos qui démarre très simplement et tourne, très rapidement, vers quelque chose d'angoissant. Il y a des interludes qui montrent un futur dramatique, un personnage très énigmatique qui est au centre de l'intrigue, des enjeux qui se développent progressivement pour atteindre une ouverture, à la fin du tome 2, qui donne vraiment envie de lire la suite ! Difficile d'en dire plus tant tout le plaisir de la lecture se trouve dans la découverte de cette intrigue, mais grosse recommandation de ma part.</p>
<h4>Mon livre de l'année</h4>
<p><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.smart_notes_s.jpg" style="float: right; margin: 0 0 1em 1em;" /></p>
<p>Chose incroyable, en 2023, mon livre préféré n'est pas une fiction, mais un livre de productivité : <a href="https://www.soenkeahrens.de/en/takesmartnotes">How to take smart notes</a>. L'auteur y présente une méthode de prise de notes créée par le sociologue <a href="https://fr.m.wikipedia.org/wiki/Niklas_Luhmann">Niklas Luhmann</a>. La méthode est simple, mais demande une certaine assiduité pour qu'elle développe tout son potentiel. En résumé : prendre des notes temporaires, constamment, puis régulièrement les transformer en notes « permanentes », des notes autosuffisantes, rédigées, et surtout systématiquement mises en lien avec d'autres notes. L'idée est de se constituer une base de notes, qu'on relit régulièrement, en suivant des liens et surtout en en créant de nouveaux à chaque fois que c'est pertinent. C'est à la fois une manière de mieux apprendre, en se forçant à écrire ce qu'on apprend et les idées qu'on développe, et à la fois une manière de structurer sa pensée et d'articuler ses idées, pour les transformer et en faire des outils novateurs et impactant.</p>
<h3>Conclusions sur l'année 2023</h3>
<p>Bon, ben, quelle année bizarre — comme prévu. Bosser aussi longtemps sur un unique projet, ou presque, c'est éreintant. Heureusement, on a pu montrer du concret au cours de l'année, grace notamment à notre serveur discord et à la newsletter que j'ai lancée. Mais à l'heure du bilan, l'impression que rien n'a avancé est vraiment forte, bien que totalement fausse. Fin 2022, je déclarais que j'avais encore beaucoup d'énergie, là, je dois avouer que c'est moins le cas. Je compte sur cette année 2024 pour chambouler un peu tout ça et me rebooster !</p>
<p>Sur ce, je vous remercie chaleureusement de m'avoir lu, je vous souhaite une très bonne année 2024, et je vous dis à bientôt sur ce blog pour une grande annonce sur Dawnmaker !</p>2024-01-18T16:07:23+00:00AdrianAdrian Gaudebert: L'état de l'Adrian 2022
http://adrian.gaudebert.fr/blog/post/l-etat-de-l-adrian-2022
<p>Il est l'heure, tardive, de faire le point sur mon année 2022 ! Vous allez le lire, l'année a été chargée, ce qui explique que j'ai un peu de retard dans la rédaction de ce billet… Mais pour me faire pardonner, je vous ai mis quelques recommandations culturelles à la fin !</p>
<p>Voici donc un résumé de ce que j'ai fait en 2022…</p>
<h3>Projets principaux</h3>
<h4>Arpentor Studio</h4>
<p><a href="https://arpentor.studio"><img alt="" src="http://adrian.gaudebert.fr/blog/public/.Arpentor_s.png" style="float: right; margin: 0 0 1em 1em;" /></a></p>
<p>Mon projet principal en 2022 a évidemment été le studio de jeu vidéo que nous avons créé avec Alexis. J'ai raconté l'essentiel de l'histoire dans mon billet <a href="http://adrian.gaudebert.fr/blog/post/starting-a-game-studio">Starting a Games Studio [en]</a>, mais je voudrais revenir ici sur d'autres aspects de cette aventure, notamment sur certaines erreurs que nous avons faites.</p>
<p>En début d'année, nous avons rejoint l'incubateur <a href="https://gameonly.org/lets-go-lincubateur-jeu-video-2">Let's GO</a>, porté par l'association régionale Game Only. Ce fût une excellente décision que de postuler, ce programme nous a apporté énormément de connaissances, de contacts, d'opportunités, et puis des bons moments de fun aussi ! Mais ça nous a mené à faire une erreur fondamentale : nous nous sommes laissés porter par les connaissances qu'on nous livrait, sans nous demander si c'était vraiment pertinent de s'en servir à ce moment-là.</p>
<p>Concrètement, nous avons modifié notre plan initial. Nous voulions nous concentrer sur la création d'un jeu relativement rapidement, entre un an et un an et demi. Entraîné par les formations, notamment sur les financements, nous avons révisé ce plan pour le faire grossir, impliquer plus de gens, dépenser plus d'argent pour pouvoir en demander plus, etc. Ce changement de stratégie a eu plusieurs conséquences :</p>
<ol>
<li>Nous avons passé énormément de temps à faire des dossiers de financement, des pitch decks et autre documents de recherche d'argent, et pas assez à travailler concrètement sur notre jeu. Nous avons du coup pris beaucoup de retard sur la production de celui-ci. Hors sans jeu un minimum abouti, sans une vraie démo qui montre notre savoir-faire, impossible d'espérer signer un contrat avec un éditeur — ce sans quoi nous ne pourrons de toute manière pas terminer notre jeu.</li>
<li>Nous avons anticipé sur l'arrivée de financements qui, il s'avère, n'étaient pas aussi faciles à obtenir que prévu. Nous avons commencé à nous rémunérer Alexis et moi, nous avons recruté une employée, nous avons engagé des frais de déplacement sur des salons… Le fait de n'avoir pas obtenu le principal financement public sur lequel nous comptions nous a mis face à une situation qui aurait pu devenir critique : la faillite. Heureusement pour nous, nous avons su nous rattraper suffisamment tôt. Malheureusement, ça impliquait de nous séparer de notre employée, d'arrêter de nous salarier, et de réduire nos frais dans le futur.</li>
<li>Nous avons fait grossir notre jeu, ajoutant de nombreuses fonctionnalités, jusqu'à atteindre un point où j'estimais qu'il nous aurait fallut une équipe de plus de 10 personnes pendant un an et demi pour réussir à finir le jeu. Là aussi, nous avons su largement réduire la taille du jeu et revenir à quelque chose de plus raisonnable pour nous, sans (trop) compromettre la vision que nous avions.</li>
</ol>
<p>Cette année a du coup été éprouvante pour moi, à faire un peu les montagnes russes : on a passé une partie de l'année à rêver d'une grosse production, de financements faramineux, de faire un jeu très ambitieux. Et puis <a href="https://twitter.com/bouletcorp/status/410390478526242816">le parpaing de la réalité s'est écrasé sur la tartelette aux fraises de nos illusions</a>, et il a fallut revenir à des choses plus raisonnables, prendre des décisions difficiles, faire du mal à des gens.</p>
<p>Malgré tout ça, ou grâce à tout ça, j'ai énormément appris en 2022 : sur la production d'un jeu, la stratégie d'entreprise, le recrutement, les relations avec les éditeurs… Le timing n'était pas toujours le bon pour apprendre ces choses-là, mais je sais qu'on s'en souviendra le moment venu, et que ça n'aura pas servi à rien. L'essentiel, comme me disait récemment un grand homme, ce n'est pas de ne plus faire d'erreur : c'est de toujours faire de nouvelles erreurs.</p>
<p>Si je devais recommencer demain, je ferais en sorte de garder ce plan de commencer petit, et de grossir tout doucement. Commencer par faire quasiment des jeux de Jams, en quelques jours seulement, puis faire un jeu en un mois, puis en deux, puis en quatre, etc. L'idée étant de monter en compétence doucement mais sûrement, sur toute la chaîne de production d'un jeu vidéo, et de se faire connaître en sortant régulièrement du contenu. C'est un modèle qui a bien fonctionné pour d'autres studios, et qui me semble vraiment sain pour quelqu'un comme moi qui n'a pas 10 ans d'expérience dans l'industrie. C'est aussi, je crois, une bonne manière de créer une entreprise financièrement stable dans ce milieu difficile.</p>
<p>Pour conclure, Arpentor Studio va bien. En fin d'année, nous avons fait en sorte de bien redresser la barre, et nous nous dirigeons actuellement vers un cap qui nous semble plus cohérent, plus sûr. On ne sortira probablement pas de jeu en 2023, mais progressera énormément dessus, on fera grossir l'équipe, et on mettra en place tout ce qu'il faut pour sortir le meilleur jeu possible en 2024.</p>
<p>État : <strong>en cours</strong>.</p>
<h4>Cities of Heksiga</h4>
<p>Qui dit studio de jeu vidéo dit forcément jeu vidéo. Ça n'est pas vraiment un secret (même si j'en ai peu parlé), nous travaillons depuis un peu plus d'un an sur un jeu que nous appelons actuellement <em>Cities of Heksiga</em>. C'est un jeu de stratégie solo, pour PC et mobile, qui se déroule dans un univers de Fantasy Steampunk. C'est en quelque sorte un jeu de plateau numérique, à la Terraforming Mars par exemple, qui mélange deck building (améliorer un deck de carte au fil de la partie en acquérant des cartes de plus en plus fortes ou synergiques) et pose de tuiles sur un plateau. Je ne vous en dit pas plus pour le moment parce qu'on a encore beaucoup de choses à stabiliser, mais ça viendra bien assez tôt. Sachez qu'on vise actuellement une sortie pendant la première moitié de 2024.</p>
<p>Sur ce jeu, je suis responsable de la programmation (le jeu est codé avec des technologies du Web, en TypeScript, avec une interface qui utilise Svelte) mais aussi du game design, c'est-à-dire de la conception des mécaniques du jeu. Alexis quant à lui est responsable de la direction artistique, de la création de tous les assets graphiques, et de la narration du jeu. Nous sommes également accompagnés par <a href="https://www.aureliemoiroud.com/">Aurélie</a>, qui créé la musique et tous les effets sonores qui viennent embellir l'expérience.</p>
<p>En 2022 j'ai travaillé sur plusieurs prototypes du jeu (j'en compte au moins une douzaine d'après notre documentation), itérant chaque fois sur les mécaniques centrales du jeu pour trouver une formule qui fonctionne. J'ai fait quelques prototypes papier, mais je suis rapidement passé sur des versions numériques, parce que nos mécaniques impliquaient tout un ensemble de calculs et d'actions automatiques difficiles à effectuer manuellement.</p>
<p><img alt="Capture d'écran du prototype de Cities of Heksiga au 12 janvier 2023" src="http://adrian.gaudebert.fr/blog/public/.2023-01-12_Screenshot_of_Cities_of_Heksiga_m.png" style="margin: 0 auto; display: table;" /></p>
<p style="text-align: center; font-style: italic;">Le prototype de Cities of Heksiga au 12 janvier 2023</p>
<p>J'ai également travaillé sur des outils, notamment un outil de gestion du contenu du jeu : j'ai une interface très simple qui me permet de créer rapidement un nouveau bâtiment, ou de mettre à jour un bâtiment existant, puis d'exporter ça en un seul clic. Le fait que nous utilisions des techno Web me permet d'être très efficace là-dessus, et j'ai bon espoir de mettre en place un workflow de game design aux petits oignons d'ici quelques mois.</p>
<p>Fin 2022, nous terminons, enfin mais difficilement, notre phase de prototypage. C'est-à-dire que nous avons consolidé les mécaniques centrales du jeu, que nous les avons validées (bon, pas vraiment, mais c'est en cours et j'ai confiance) et que nous pouvons maintenant passer à la suite : créer une vraie démo qui déchire, et étoffer doucement le jeu en ajoutant de nouvelles mécaniques et du contenu.</p>
<p>Comme je l'ai dit dans la partie précédente, nous avons passé trop peu de temps à travailler sur ce jeu cette année. Mais ça a présenté un avantage : nous avons eu le temps de le faire tester, de prendre des retours posés et construits sur les forces et les faiblesses de nos différents prototypes. Au final, nous avons pu identifier des problèmes fondamentaux et les corriger, ce qui aurait été plus difficile si nous avions eu plus la tête dans le guidon. Un mal pour un bien !</p>
<p>En 2023, Cities of Heksiga devrait vraiment prendre forme, et passer d'un prototype à une véritable démo, puis à une vertical slice, une version représentative de ce que nous voulons que le jeu final soit. Nous prévoyons actuellement de sortir le jeu dans la première moitié de 2024.</p>
<p>État : <strong>en cours</strong>.</p>
<h3>Projets secondaires</h3>
<h4>Souls</h4>
<p>Souls, mon jeu de cartes compétitif en ligne, a fait une grosse pause en 2022. Au milieu de tout le reste, je n'ai tout simplement pas eu le temps de me remettre dessus. Mais tout mon travail à côté a pour objectif de monter en compétence et de créer un contexte dans lequel il sera possible de faire de Souls un succès. Donc quelque part, ça avance quand même !</p>
<p>État : <strong>en pause</strong>.</p>
<h4>Board Game Jam 2</h4>
<p>Voici mon gros projet secondaire de ces derniers mois : l'organisation d'une Jam de création de jeux de plateau. C'est une idée que mon ami Aurélien et moi avions depuis trèèèès longtemps, qui s'est enfin concrétisée début 2020 via l'association Game Dev Party… mais qui s'est fait couper en plein milieu par l'annonce du premier confinement. Je suis donc très heureux d'avoir enfin pu mener une vraie Board Game Jam jusqu'au bout !</p>
<p>Mais qu'est-ce que c'est que ce truc, me demandez-vous ? Une Jam, c'est un événement de création, initialement de jeu vidéo, en équipe, en général sur un week-end. On réunit une cinquantaine de personnes dans un même lieu physique, ils se répartissent en groupes et passent leur week-end à créer de toutes pièces, depuis zéro, un jeu vidéo. À Lyon, l'association Game Dev Party a fait de l'organisation de ces événement sa spécialité depuis 2011 — et j'en suis membre organisateur depuis 2012. Une Board Game Jam, c'est le même principe, mais pour les jeux de société.</p>
<p><img alt="" src="http://adrian.gaudebert.fr/blog/public/.2023-01-15_-_Board_Game_Jam_2_m.jpg" style="margin: 0 auto; display: table;" /></p>
<p style="text-align: center; font-style: italic;">La table de matériel mis à disposition des participant⋅e⋅s</p>
<p>L'événement a eu lieu mi-janvier, et s'est soldée par une franche réussite : environ 40 participant⋅e⋅s pour <a href="https://gamedevparty.fr/retour-sur-la-board-game-jam-2/">9 jeux créés pendant le week-end</a>. Le week-end s'est déroulé sans accroc majeur (oublions les quelques couacs techniques du dimanche soir), les gens avaient l'air heureux, et les jeux produits étaient incroyablement engageants et variés.</p>
<p>Je suis particulièrement ravi de cette formule. Travailler sur un jeu vidéo présente un réel challenge technique : il faut programmer, il faut illustrer, il faut sonoriser… Le temps d'itération est relativement long, entre le moment où on a une idée et le moment où on peut réellement la tester, clavier, souris ou manette en main. Avec le jeu de société, ce temps d'itération est très largement réduit. Une nouvelle idée de carte ? Un bout de papier, un crayon, et hop, la carte est créée et prête à être testée.</p>
<p>C'était épuisant de porter cet événement, mais je suis fier de ce qu'on a réalisé, et je compte fortement sur d'autres personnes pour organiser de nouveaux événements de ce type. Parce que c'est quand même super frustrant de voir tous ces gens créer des jeux et de ne pas participer !!!</p>
<p>État : <strong>terminé</strong>.</p>
<h4>Blog</h4>
<blockquote>
<p>Je me note donc, pour mon moi du futur, de faire attention à rester ouvert : c'est éprouvant d'avancer sans que rien de concret ne « sorte », sans avoir la satisfaction d'avoir terminé quelque chose. Alors, Adrian de 2022 : n'oublie pas de parler de ce que tu fais, de montrer tes avancées, même si c'est moche, même si ça marche mal, parce que ça te donnera la sensation de progresser, et que ça t'aidera beaucoup !</p>
</blockquote>
<p>Raté ! Je n'ai publié que deux articles en 2022 : <a href="http://adrian.gaudebert.fr/blog/post/how-i-did-my-market-research-on-steam">How I did my market research on Steam [en]</a> en mars puis <a href="http://adrian.gaudebert.fr/blog/post/starting-a-game-studio">Starting a Games Studio [en]</a> en août. Ce dernier a été un énorme travail, que j'ai fait sur plusieurs mois, mais ça reste très insuffisant pour moi. Heureusement, j'ai quand même partagé mon travail, mais ailleurs : sur un serveur discord qu'on utilise pour les playtests de notre jeu, et au sein de l'incubateur Let's GO. Je n'ai pas ressenti le besoin de plus écrire, même si ça reste un objectif que j'aimerais tenir un jour. J'ai beaucoup appris de gens qui ont partagé leurs expériences avant moi, et je souhaite rendre ce service moi aussi. C'est dans cette démarche que j'ai écrit ces deux billets, mais je pense que je peux en faire plus.</p>
<p>Allez, objectif pour 2023 : 6 billets dans l'année, soit un tous les deux mois !</p>
<h3>Mes recommandations de l'année</h3>
<p>Pour conclure ce billet, j'ai envie de faire un truc nouveau : vous recommander quelques œuvres culturelles qui m'ont marquées cette année.</p>
<h4>Mon jeu vidéo de l'année</h4>
<p><a href="https://store.steampowered.com/app/1284190/The_Planet_Crafter/"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.planet-crafter_s.jpg" style="float: left; margin: 0 1em 1em 0;" /></a></p>
<p>Sans conteste, c'est <a href="https://store.steampowered.com/app/1284190/The_Planet_Crafter/">Planet Crafter</a> qui a été mon jeu de 2022. On y mélange survie, exploration et construction de base sur une planète inhabitable, et notre objectif est de la terraformer. Le jeu est en early access, mais son contenu est déjà énorme, et les mises à jour ont toutes été très bénéfiques. J'ai pris quelques grosses claques en découvrant certains lieux, j'ai passé des heures à me construire une belle base, la progression est excellemment maîtrisée, il y a toujours quelque chose à faire, bref : je vous recommande de jouer à Planet Crafter !</p>
<p><em>PS : j'ai découvert via le <a href="https://www.canardpc.com/jeu-video/dossier-jeu-video/interview-miju-games-les-createurs-de-the-planet-crafter/">CanardPC de janvier</a> que les créateurs de Planet Crafter sont un couple de Toulousains. Ils ont fait ce jeu à deux. C'est très impressionnant. :-)</em></p>
<p><a href="https://www.trictrac.net/jeu-de-societe/terraforming-mars-expedition-ares"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.terraforming-mars-expedition-ares_s.jpg" style="float: right; margin: 0 0 1em 1em;" /></a></p>
<h4>Mon jeu de plateau de l'année</h4>
<p>J'ai été conquis par <a href="https://www.trictrac.net/jeu-de-societe/terraforming-mars-expedition-ares">Terraforming Mars: Expédition Arès</a>. Ce mélange des cartes du merveilleux <a href="https://www.trictrac.net/jeu-de-societe/terraforming-mars-2">Terraforming Mars</a> original avec la mécanique d'actions partagées de <a href="https://www.trictrac.net/jeu-de-societe/race-for-the-galaxy">Race for the Galaxy</a> a complètement fait mouche chez moi. C'est tout ce que j'aime : de l'engine building pur, avec de la planification, un poil de bluff, et juste ce qu'il faut de ressources. C'est accessible, et ça se joue (relativement) vite, entre 1h et 1h30.</p>
<div class="clear"></div>
<h4>Ma BD de l'année</h4>
<p><a href="https://www.bedetheque.com/serie-62493-BD-Bolchoi-arena.html"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.bolchoi-arena_s.jpg" style="float: left; margin: 0 1em 1em 0;" /></a></p>
<p>Je décerne le prix de la BD de l'année à <a href="https://www.bedetheque.com/serie-62493-BD-Bolchoi-arena.html">Bolchoï Arena</a>, de Boulet et Aseyn. Le tome 1 date de 2018, mais je n'ai découvert la série qu'en 2022 à l'occasion de la sortie du tome 3 — pour une série prévue en 5 livres. Dans cette histoire de Science Fiction, on suit les pérégrinations d'une jeune femme dans le Bolchoï, monde virtuel en ligne particulièrement gigantesque qui reproduit à l'identique l'univers connu. Jusqu'à, bien sûr, qu'il se passe des trucs de ouf qui posent des tonnes de questions. On y retrouve de l'aventure, de l'exploration, de la géopolitique, des questions existentielles sur le rapport aux mondes virtuels, et bien plus mais je peux pas dire quoi pour pas spoiler. J'ai très très hâte de lire la suite, les trois premiers tomes sont excellents !</p>
<div class="clear"></div>
<p><a href="https://www.goodreads.com/hr/book/show/54493401-project-hail-mary"><img alt="" src="http://adrian.gaudebert.fr/blog/public/icones-billets/.project-hail-mary_s.jpg" style="float: right; margin: 0 0 1em 1em;" /></a></p>
<h4>Mon livre de l'année</h4>
<p>Andy Weir, auteur du livre de SF The Martian, qui a été adapté au cinéma dans un film éponyme avec Matt Damon (très bonne adaptation soit dit en passant), a sorti deux autres livres : Artemis et Project Hail Mary. Si Artemis est une lecture très agréable, <a href="https://www.goodreads.com/hr/book/show/54493401-project-hail-mary">Project Hail Mary</a> a été une claque monumentale. Le personnage principal cynique à souhaite, la narration par flashbacks qui fait monter la compréhension et les enjeux, et un incroyable twist au milieu du livre qui change complètement la donne : j'ai adoré ce livre, et je ne peux que le recommander à tout le monde, c'est une merveille.</p>
<h3>Conclusions sur l'année 2022</h3>
<p>2022 fût une année encore plus éprouvante que ce que j'avais prévu. Mais j'ai énormément appris, sur beaucoup de choses. J'ai été tour à tour programmeur, game designer, producer, entrepreneur, recruteur, organisateur… Ça fait beaucoup pour un seul homme, c'est épuisant, mais je ne regrette pas ! Dans tout ça, j'ai tout de même vraiment réussi à me préserver, à ne pas me surcharger de travail, à prendre de (longues) vacances, et c'est une très bonne chose. Je ne suis pas cramé, j'ai encore plein d'énergie pour 2023, et je suis confiant sur l'avenir.</p>
<p>Bonne année 2023 à vous toutes et tous, chères lectrices, chers lecteurs, et merci de tout cœur de me suivre dans ces aventures !</p>2024-01-18T10:27:45+00:00AdrianMozilla Localization (L10N): Advancing Mozilla’s mission through our work on localization standards
https://blog.mozilla.org/l10n/2024/01/18/advancing-mozillas-mission-through-our-work-on-localization-standards/
<p>After the previous post highlighting <a href="https://blog.mozilla.org/l10n/2024/01/15/mozilla-localization-in-2023/">what the Mozilla community and Localization Team achieved in 2023</a>, it’s time to dive deeper on the work the team does in the area of localization technologies and standards.</p>
<p>A significant part of our work on localization at Mozilla happens within the space of Internet standards. We take seriously our commitments that stem from the <a href="https://www.mozilla.org/about/manifesto/">Mozilla Manifesto</a>:</p>
<blockquote><p>We are committed to an internet that includes all the peoples of the earth — where a person’s demographic characteristics do not determine their online access, opportunities, or quality of experience.</p></blockquote>
<p>To us, this means that it’s not enough to strive to improve the localization of our products, but that we need to improve the <i>localizability</i> of the Internet as a whole. We need to take the lessons we are learning from our work on Firefox, Thunderbird, websites, and all our other projects, and make them available to everyone, everywhere.</p>
<p>That’s a pretty lofty goal we’ve set ourselves, but to be fair it’s not just about altruism. With our work on <a href="https://projectfluent.org/">Fluent</a> and <a href="https://projectfluent.org/dom-l10n-documentation/">DOM Localization</a>, we’re in a position where it would be far too easy to rest on our laurels, and to consider what we have “good enough”. To keep going forward and to keep improving the experiences of our developers and localizers, we need input from the outside that questions our premises and challenges us. One way for us to do that is to work on Internet standards, presenting our case to other experts in the field.</p>
<p>In 2023, a large part of our work on localization standards has been focused on <a href="https://github.com/unicode-org/message-format-wg">Unicode MessageFormat 2</a> (aka “MF2”), an upcoming message formatting specification, as well as other specifications building on top of it. Work on this has been ongoing since late 2019, and Mozilla has been one of the core participants from the start. The base MF2 spec is now slated for an initial “technology preview” release as a part of the 2024 Spring’s <a href="https://cldr.unicode.org/">Unicode CLDR</a> release.</p>
<p>Compared to Fluent, MF2 corresponds to the syntax and formatting of a single message pattern. Separately, we’ve also been working on the syntax and representation of a <a href="https://github.com/eemeli/message-resource-wg">resource format</a> for messages (corresponding to Fluent’s FTL files), as well as championing JavaScript language proposals for <a href="https://github.com/tc39/proposal-intl-messageformat">formatting messages</a> and <a href="https://github.com/tc39/proposal-intl-message-resource">parsing resources</a>. Work on standardizing DOM localization (as in, being able to use just HTML to localize a website) is also getting started in <a href="https://www.w3.org/blog/2019/w3c-and-whatwg-to-work-together-to-advance-the-open-web-platform/">W3C/WHATWG</a>, but its development is contingent on all the preceding specifications reaching a more stable stage.</p>
<p>So, besides the long term goal of improving localization everywhere, what are the practical results of these efforts? The nature of this work is exploratory, so predicting results has not and will not be completely possible. One tangible benefit that we’ve been able to already identify and deploy is a reconsideration of how Fluent messages with internal selectors — like <a href="https://projectfluent.org/fluent/guide/selectors.html">plurals</a> — are presented to localizers: Rather than showing a message in pieces, we’ve adopted the MF2 approach of presenting a message with its selectors (possibly <a href="https://pontoon.mozilla.org/fr/firefox-profiler/app.ftl/?string=224370">more than one</a>) applying to the whole message. This duplicates some parts of the message, but it also makes it easier to read and to translate via machine translation, as well as ensuring that it is internally consistent across all languages.</p>
<p>Another byproduct of this work is MF2’s <a href="https://github.com/unicode-org/message-format-wg/tree/main/spec/data-model">message data model</a>: Unlike anything before it, it is capable of representing all messages in all languages in all formats. We are currently refactoring our tools and internal systems around this data model, allowing us to deduplicate file format-specific tooling, making it easier to add new features and support new syntaxes. In Pontoon, this approach already made it easier to introduce syntax highlighting and improve the editing experience for right-to-left scripts. To hear more, you can join us at FOSDEM next month, where we’ll be <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-1759-a-universal-data-model-for-localizable-messages/">presenting on this</a> in more detail!</p>
<p>At Mozilla, we do not presume to have all the answers, or to always be right. Instead, we try to share what we have, and to learn from others. With many points of view, we gain greater insights – and we help make the world a better place for all peoples of all demographic characteristics.</p>2024-01-18T07:33:03+00:00Francesco Lodolo [:flod]