惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
P
Privacy International News Feed
Vercel News
Vercel News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 叶小钗
F
Fortinet All Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
L
LINUX DO - 最新话题
AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta
Attack and Defense Labs
Attack and Defense Labs
Recent Announcements
Recent Announcements
Recent Commits to openclaw:main
Recent Commits to openclaw:main
PCI Perspectives
PCI Perspectives
Cloudbric
Cloudbric
AI
AI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
IT之家
IT之家
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
J
Java Code Geeks
M
MIT News - Artificial intelligence
Cisco Talos Blog
Cisco Talos Blog
V2EX - 技术
V2EX - 技术
Webroot Blog
Webroot Blog
Microsoft Security Blog
Microsoft Security Blog
Cyberwarzone
Cyberwarzone
博客园 - 聂微东
G
Google Developers Blog
W
WeLiveSecurity
罗磊的独立博客
P
Privacy & Cybersecurity Law Blog
阮一峰的网络日志
阮一峰的网络日志
A
About on SuperTechFans
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
T
Tailwind CSS Blog
V
Visual Studio Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
Secure Thoughts
Apple Machine Learning Research
Apple Machine Learning Research
Hugging Face - Blog
Hugging Face - Blog
Google DeepMind News
Google DeepMind News
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Full Disclosure
Blog — PlanetScale
Blog — PlanetScale
The Last Watchdog
The Last Watchdog
P
Proofpoint News Feed

Rust Blog

Security Advisory for Cargo (CVE-2026-5223) | Rust Blog Security Advisory for Cargo (CVE-2026-5222) | Rust Blog Project goals update — April 2026 (end of 2025H2) | Rust Blog Rust is participating in Outreachy | Rust Blog Raising the baseline for the `nvptx64-nvidia-cuda` target | Rust Blog Announcing Google Summer of Code 2026 selected projects | Rust Blog Announcing Rust 1.95.0 | Rust Blog docs.rs: building fewer targets by default | Rust Blog Changes to WebAssembly targets and handling undefined symbols | Rust Blog Announcing Rust 1.94.1 | Rust Blog Security advisory for Cargo | Rust Blog What we heard about Rust's challenges | Rust Blog Call for Testing: Build Dir Layout v2 | Rust Blog Announcing rustup 1.29.0 | Rust Blog Announcing Rust 1.94.0 | Rust Blog 2025 State of Rust Survey Results | Rust Blog Rust debugging survey 2026 | Rust Blog Update on the October 15, 2018 incident on crates.io Announcing Rust 1.29.2 Announcing Rust 1.29 Launching the 2018 State of Rust Survey Announcing Rust 1.28 What is Rust 2018? Announcing Rust 1.27.2 Announcing Rust 1.27.1 Security Advisory for rustdoc Announcing Rust 1.27 Announcing Rust 1.26.2 Announcing Rust 1.26.1 Rust turns three The Rust Team All Hands in Berlin: a Recap Increasing Rust’s Reach 2018 Announcing Rust 1.25 Rust's 2018 roadmap Announcing Rust 1.24.1 Announcing Rust 1.24 The 2018 Rust Event Lineup Announcing Rust 1.23 New Year's Rust: A Call for Community Blogposts Rust in 2017: what we achieved Announcing Rust 1.22 (and 1.22.1) Fearless Concurrency in Firefox Quantum Announcing Rust 1.21 impl Future for Rust Rust 2017 Survey Results Announcing Rust 1.20 Announcing Rust 1.19 The 2017 Rust Conference Lineup Rust's 2017 roadmap, six months in Increasing Rust’s Reach Announcing Rust 1.18 Two years of Rust The Rust Libz Blitz Launching the 2017 State of Rust Survey Announcing Rust 1.17 Announcing Rust 1.16 Rust's language ergonomics initiative Announcing Rust 1.15.1 Rust's 2017 roadmap Announcing Rust 1.15 Announcing Rust 1.14 Announcing the First Underhanded Rust Contest Announcing Rust 1.13 Announcing Rust 1.12.1 Announcing Rust 1.12 Incremental Compilation Announcing Rust 1.11 Shape of errors to come The 2016 Rust Conference Lineup Announcing Rust 1.10 State of Rust Survey 2016 Announcing Rust 1.9 One year of Rust Taking Rust everywhere with rustup Launching the 2016 State of Rust Survey Cargo: predictable dependency management Introducing MIR Announcing Rust 1.8 Announcing Rust 1.7 Announcing Rust 1.6 Announcing Rust 1.5 Announcing Rust 1.4 Announcing Rust 1.3 Rust in 2016 Announcing Rust 1.2 Rust 1.1 stable, the Community Subteam, and RustCamp Announcing Rust 1.0 Abstraction without overhead: traits in Rust Rust Once, Run Everywhere Mixing matching, mutation, and moves in Rust Fearless Concurrency with Rust Announcing Rust 1.0 Beta Announcing Rust 1.0.0.alpha.2 Rust 1.0: status report and final timeline Announcing Rust 1.0 Alpha Rust 1.0: Scheduling the trains Yehuda Katz and Steve Klabnik are joining the Rust Core Team Cargo: Rust's community crate host Stability as a Deliverable Road to Rust 1.0
Announcing Rust 1.26
The Rust Cor · 2018-05-10 · via Rust Blog

The Rust team is happy to announce a new version of Rust, 1.26.0. Rust is a systems programming language focused on safety, speed, and concurrency.

If you have a previous version of Rust installed via rustup, getting Rust 1.26.0 is as easy as:

$ rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.26.0 on GitHub.

What's in 1.26.0 stable

The past few releases have had a steady stream of relatively minor additions. We've been working on a lot of stuff, however, and it's all starting to land in stable. 1.26 is possibly the most feature-packed release since Rust 1.0. Let's dig in!

"The Rust Programming Language" Second Edition

For almost 18 months, Carol, Steve, and others have been working on a complete re-write of "The Rust Programming Language." We've learned a lot about how people learn Rust since the first book was written, and this version is an improvement in every way.

We've shipped the draft of the second edition on the website for a while now, but with a disclaimer that it was a work in progress. At this point, the book is undergoing some final, minor copy-edits, and being prepared for print. As such, with this release, we are recommending the second edition over the first. You can read it on doc.rust-lang.org or locally via rustup doc --book.

Speaking of print, you can pre-order a dead tree version of the book from NoStarch Press. The contents are identical, but you get a nice physical book to put on a shelf, or a beautifully typeset PDF. Proceeds are going to charity.

impl Trait

At long last, impl Trait is here! This feature has been highly desired for quite a while, and provides a feature known as "existential types." It's simpler than that sounds, however. The core of it is this idea:

fn foo() -> impl Trait {
    // ...
}

This type signature says "foo is a function that takes no arguments but returns a type that implements the Trait trait." That is, we're not going to tell you what the return type of foo actually is, only that it implements a particular trait. You may wonder how this differs from a trait object:

fn foo() -> Box<Trait> {
    // ...
}

While it's true that you could have written this code today, it's not ideal in all situations. Let's say we have a trait Trait that is implemented for both i32 and f32:

trait Trait {
    fn method(&self);
}

impl Trait for i32 {
    // implementation goes here
}

impl Trait for f32 {
    // implementation goes here
}

Consider this function:

fn foo() -> ? {
    5
}

We want to fill in the return type with something. Previously, only the trait object version was possible:

fn foo() -> Box<Trait> {
    Box::new(5) as Box<Trait>
}

But this introduces a Box, which means allocation. We're not actually returning some kind of dynamic data here either, so the dynamic dispatch of the trait object hurts too. So instead, as of Rust 1.26, you can write this:

fn foo() -> impl Trait {
    5
}

This doesn't create a trait object, it's like we had written -> i32, but instead, we're only mentioning the part about Trait. We get static dispatch, but we can hide the real type like this.

Why is this useful? One good use is closures. Remember that closures in Rust all have a unique, un-writable type, yet implement the Fn trait. This means that if your function returns a closure, you can do this:

// before
fn foo() -> Box<Fn(i32) -> i32> {
    Box::new(|x| x + 1)
}

// after
fn foo() -> impl Fn(i32) -> i32 {
    |x| x + 1
}

No boxing, no dynamic dispatch. A related scenario happens when returning iterators. Not only do iterators often include closures, but since they nest, you get quite deeply nested types. For example:

fn foo() {
    vec![1, 2, 3]
        .into_iter()
        .map(|x| x + 1)
        .filter(|x| x % 2 == 0)
}

when compiled, gives this error:

error[E0308]: mismatched types
 --> src/main.rs:5:5
  |
5 | /     vec![1, 2, 3]
6 | |         .into_iter()
7 | |         .map(|x| x + 1)
8 | |         .filter(|x| x % 2 == 0)
  | |_______________________________^ expected (), found struct `std::iter::Filter`
  |
  = note: expected type `()`
             found type `std::iter::Filter<std::iter::Map<std::vec::IntoIter<{integer}>, [closure@src/main.rs:7:14: 7:23]>, [closure@src/main.rs:8:17: 8:31]>`

That's a huge 'found type'. Each adapter in the chain adds a new type. Additionally, we have that closure in there. Previously, we'd have had to use a trait object here, but now we can simply do

fn foo() -> impl Iterator<Item = i32> {
    vec![1, 2, 3]
        .into_iter()
        .map(|x| x + 1)
        .filter(|x| x % 2 == 0)
}

and be done with it. Working with futures is very similar.

It's important to note that sometimes trait objects are still what you need. You can only use impl Trait if your function returns a single type; if you want to return multiple, you need dynamic dispatch. For example:

fn foo(x: i32) -> Box<Iterator<Item = i32>> {
    let iter = vec![1, 2, 3]
        .into_iter()
        .map(|x| x + 1);

    if x % 2 == 0 {
        Box::new(iter.filter(|x| x % 2 == 0))
    } else {
        Box::new(iter)
    }
}

Here, we may return a filtered iterator, or maybe not. There's two different types that can be returned, and so we must use a trait object.

Oh, and one last thing: to make the syntax a bit more symmetrical, you can use impl Trait in argument position too. That is:

// before
fn foo<T: Trait>(x: T) {

// after
fn foo(x: impl Trait) {

which can look a bit nicer for short signatures.

Side note for you type theorists out there: this isn't an existential, still a universal. In other words, impl Trait is universal in an input position, but existential in an output position.

Nicer match bindings

Have you ever had a reference to an Option, and tried to use match? For example, code like this:

fn hello(arg: &Option<String>) {
    match arg {
        Some(name) => println!("Hello {}!", name),
        None => println!("I don't know who you are."),
    }
}

If you tried to compile this in Rust 1.25, you'd get this error:

error[E0658]: non-reference pattern used to match a reference (see issue #42640)
 --> src/main.rs:6:9
  |
6 |         Some(name) => println!("Hello {}!", name),
  |         ^^^^^^^^^^ help: consider using a reference: `&Some(name)`

error[E0658]: non-reference pattern used to match a reference (see issue #42640)
 --> src/main.rs:7:9
  |
7 |         None => println!("I don't know who you are."),
  |         ^^^^ help: consider using a reference: `&None`

Okay, sure. Let's modify the code:

fn hello(arg: &Option<String>) {
    match arg {
        &Some(name) => println!("Hello {}!", name),
        &None => println!("I don't know who you are."),
    }
}

We added the &s the compiler complained about. Let's try to compile again:

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:6:9
  |
6 |         &Some(name) => println!("Hello {}!", name),
  |         ^^^^^^----^
  |         |     |
  |         |     hint: to prevent move, use `ref name` or `ref mut name`
  |         cannot move out of borrowed content

Okay, sure. Let's make the compiler happy again by taking its advice:

fn hello(arg: &Option<String>) {
    match arg {
        &Some(ref name) => println!("Hello {}!", name),
        &None => println!("I don't know who you are."),
    }
}

This will finally compile. We had to add two &s, and a ref. But more importantly, none of this was really helpful to us as programmers. Sure, we forgot a & at first, but does that matter? We had to add ref to get a reference to the inside of the option, but we couldn't do anything but get a reference, as we can't move out of a &T.

So, as of Rust 1.26, the initial code, without the &s and ref, will just compile and do exactly what you'd expect. In short, the compiler will automatically reference or de-reference in match statements. So when we say

    match arg {
        Some(name) => println!("Hello {}!", name),

the compiler automatically references the Some, and since we're borrowing, name is bound as ref name automatically as well. If we were mutating:

fn hello(arg: &mut Option<String>) {
    match arg {
        Some(name) => name.push_str(", world"),
        None => (),
    }
}

the compiler will automatically borrow by mutable reference, and name will be bound as ref mut too.

We think this will remove a significant papercut for new and old Rustaceans alike. The compiler will just do the right thing more often without the need for boilerplate.

main can return a Result

Speaking of papercuts, since Rust uses the Result type for returning errors, and ? to make handling them easy, a common pain-point of new Rustaceans is to try and use ? in main:

use std::fs::File;

fn main() {
    let f = File::open("bar.txt")?;
}

This will give an error like "error[E0277]: the ? operator can only be used in a function that returns Result". This leads to a pattern where many people write code that looks like this:

fn run(config: Config) -> Result<(), Box<Error>> {
    // --snip--
}

fn main() {
    // --snip--

    if let Err(e) = run(config) {
        println!("Application error: {}", e);

        process::exit(1);
    }
}

Our run function has all of the real logic, and main calls run, only checking to see if there was an error and exiting. We need to make this second function because main can't return a Result, but we'd like to use ? in that logic.

In Rust 1.26, you can now declare main that returns Result:

use std::fs::File;

fn main() -> Result<(), std::io::Error> {
    let f = File::open("bar.txt")?;

    Ok(())
}

This now works just fine! If main returns an error, this will exit with an error code, and print out a debug representation of the error.

Inclusive ranges with ..=

Since well before Rust 1.0, you've been able to create exclusive ranges with .. like this:

for i in 1..3 {
    println!("i: {}", i);
}

This will print i: 1 and then i: 2. In Rust 1.26, you can now create an inclusive range, like this:

for i in 1..=3 {
    println!("i: {}", i);
}

This will print i: 1 and then i: 2 like before, but also i: 3; the three is included in the range. Inclusive ranges are especially useful if you want to iterate over every possible value in a range. For example, this is a surprising Rust program:

fn takes_u8(x: u8) {
    // ...
}

fn main() {
    for i in 0..256 {
        println!("i: {}", i);
        takes_u8(i);
    }
}

What does this program do? The answer: nothing. The warning we get when compiling has a hint:

warning: literal out of range for u8
 --> src/main.rs:6:17
  |
6 |     for i in 0..256 {
  |                 ^^^
  |
  = note: #[warn(overflowing_literals)] on by default

That's right, since i is a u8, this overflows, and is the same as writing for i in 0..0, so the loop executes zero times.

We can do this with inclusive ranges, however:

fn takes_u8(x: u8) {
    // ...
}

fn main() {
    for i in 0..=255 {
        println!("i: {}", i);
        takes_u8(i);
    }
}

This will produce those 256 lines of output you might have been expecting.

Basic slice patterns

Another long-awaited feature is "slice patterns." These let you match on slices similar to how you match on other data types. For example:

let arr = [1, 2, 3];

match arr {
    [1, _, _] => "starts with one",
    [a, b, c] => "starts with something else",
}

In this case, we know arr has a length of three, and so we need three entries inside the []s. We can also match when we don't know the length:

fn foo(s: &[u8]) {
    match s {
        [a, b] => (),
        [a, b, c] => (),
        _ => (),
    }
}

Here, we don't know how long s is, so we can write the first two arms, each with different lengths. This also means we need a _ term, since we aren't covering every possible length, nor could we!

Speed improvements

We continue to work on the speed of the compiler. We discovered that deeply nesting types was non-linear in some cases, and a fix was implemented. We're seeing up to a 12% reduction in compile times from this change, but many other smaller fixes landed as well. More to come in the future!

128 bit integers

Finally, a very simple feature: Rust now has 128 bit integers!

let x: i128 = 0;
let y: u128 = 0;

These are twice the size of u64, and so can hold more values. More specifically,

  • u128: 0 - 340,282,366,920,938,463,463,374,607,431,768,211,455
  • i128: −170,141,183,460,469,231,731,687,303,715,884,105,728 - 170,141,183,460,469,231,731,687,303,715,884,105,727

Whew!

See the detailed release notes for more.

Library stabilizations

We stabilized fs::read_to_string, a convenience over File::open and io::Read::read_to_string for easily reading an entire file into memory at once:

use std::fs;
use std::net::SocketAddr;

let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?;

You can now format numbers as hexadecimal with Debug formatting:

assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]")

Trailing commas are now supported by all macros in the standard library.

See the detailed release notes for more.

Cargo features

Cargo didn't receive many big new features this release but rather saw a steady stream of stability and performance improvements. Cargo should now resolve lock files even faster, backtrack more intelligently, and require manual cargo update invocations less. Cargo's binary now also shares the same version as rustc.

See the detailed release notes for more.

Contributors to 1.26.0

Many people came together to create Rust 1.26. We couldn't have done it without all of you.

Thanks!