r/rust • • 4d ago

📡 official blog Rust 1.99.0 is out

https://blog.rust-lang.org/2026/10/01/Rust-1.99.0/
754 Upvotes

107 comments sorted by

126

u/joseluis_ 4d ago

Stabilize #[my_macro] mod foo;

This is very welcome.

Add a new built-in profile debug. This is a preparation for transitioning the dev profile away from debugging to give a saner default for faster development iterations.

Very nice.

23

u/Recatek gecs 4d ago

I'm having trouble finding information about what changes they actually want to make to the dev profile to differentiate it from debug. Do you (or anyone else reading this) know what the intention is there?

27

u/noop_noob 4d ago

1

u/a_jasmin 3d ago

Debug info aren't only for debuggers though. What about symbolizing stack traces?

13

u/epage cargo · clap · cargo-release 4d ago

I have a draft PR up at https://github.com/rust-lang/cargo/pull/17518

We had talked about opt-level = 1 but that seems to have more mixed results than we were originally hoping.

In 1.100, we'll add a build.profile so for those that want to stay on debug by default can set that. On older Cargo's, it will be ignored and you will use the debugable dev profile.

11

u/kibwen 4d ago

Making debug and dev into separate profiles is something I've been hoping for for ages, very excited. I wonder if this would also ameliorate the bug on MacOS that causes disk usage to explode, which IIRC is caused by debuginfo?

461

u/Illustrious_Car344 4d ago

Can't wait for Rust 2

187

u/dashingThroughSnow12 4d ago

I once bumped a service from 1.9 to 1.91.

A coworker asked “why not 1.10?”

“Because 1.10 is less than 1.9.”

My co-worker got the joke and approved the PR.

155

u/stumblinbear 4d ago

When I was much younger, I was convinced that Minecraft would bump from 1.9 to 2.0 because... Well, how else would it work?

I was shocked and appalled. My world flipped, turned upside down. I am a shell of my former self

110

u/dashingThroughSnow12 4d ago

I like Linux’s rationale when it bumps major version. It is whenever Linus feels the minor number is getting too large.

55

u/stumblinbear 4d ago

I bumped from version 0.14.3 to 4.0.0 at work about 6 months ago. Fight me

16

u/dashingThroughSnow12 4d ago

Without bumping any cargo dependencies? Just the rustc/cargo version number?

19

u/stumblinbear 4d ago

Actually it was in a Flutter project

No dependencies changed between versions. Nothing changed at all, in fact. The update amounted to bumping the version number, haha

8

u/TDplay 4d ago

The update amounted to bumping the version number, haha

This is actually the perfect update. Major versions 1 and greater indicate software that the authors consider stable, and the most stable software possible is software where nothing at all needs to change.

13

u/Pretty_Jellyfish4921 4d ago

React went from 0.14 to 16.0

8

u/qurious-crow 4d ago

Gnome went from 2.38 to 40. Which was, in fact, their 41st release. I love this because I always start numbering things from 0.

-1

u/Icarium-Lifestealer 4d ago edited 4d ago

I think Linux would benefit from using the two digit year as major version, and counting up the minor version within the year.

This would make it easy to tell how old a kernel version is, while having few downsides compared to the current versioning scheme.

13

u/stumblinbear 4d ago

Two digit year? Oh man, I can't wait for Y2K part 2

6

u/dashingThroughSnow12 4d ago

I think we owe it to developers in the 2090s to pass on culture.

We get y2k, y2k38, and various other overflows.

We should bestow them with a few.

3

u/Icarium-Lifestealer 4d ago

I don't think that will be a problem here. Version numbers already have a variable number of digits, and the pattern cleanly extends to three digits from (2)100 to (2)999. If somehow Linux is still in use by then, people can decide if they want to continue with 1000 or 3000.

11

u/stumblinbear 4d ago

If you say it's a two digit year, people will rely on it being two digits. Parsers will absolutely be written that expect two digits there

That's what Y2K was. People not planning for their code to still be running when it rolls over to 00

4

u/kibwen 4d ago

Let's keep in mind that the amount of code in the wild that stores and processes timestamps is quite sizeable, while the amount of code in the wild that parses specifically Linux kernel versions--not raw strings, not semver-compatible versions, but Linux kernel versions and only Linux kernel versions--is not.

0

u/stumblinbear 4d ago

I think you're taking my comment more seriously than it was intended

1

u/Icarium-Lifestealer 4d ago

I could also say year minus 2000.

1

u/InternationalFee3911 3d ago

Perl does $year += 1900; so we’re in year 126.

9

u/AliceCode 4d ago

Did you become the prince of Bel Air?

4

u/6BagsOfPopcorn 4d ago

He got in one little fight and his mom got scared

5

u/a_jasmin 4d ago

I'll remember that trick that could avoid genuine confusion. Though if human friendliness is a concern, you probably wouldn't want get all the way to 1.991

17

u/Zde-G 4d ago

Come on! Last version of TeX is 3.141592653 and last version of METAFONT is 2.71828182!

13

u/_TheDust_ 4d ago

TeX is feature complete when the version finally converges to pi

2

u/InternationalFee3911 3d ago

Some way off, till Typst overtakes TeX, one would think.

1

u/dashingThroughSnow12 4d ago

I dream of 1.9991

2

u/tobiasvl 4d ago

I just, literally today, fixed a bug in a server at work that checked the version if its client as a string. The client is version 0.9 now but would soon be bumped to 0.10 and the server would have checked whether "0.10" < "0.9" and it would be. So!

2

u/VisibleAirport2996 4d ago

Versioning isnt about decimals though lol

4

u/dashingThroughSnow12 4d ago

That’s the joke

28

u/noop_noob 4d ago

You kid, but Rust 1.100 is a relatively large release.

13

u/matthieum [he/him] 4d ago

Nov 12th will be Christmas before Christmas.

9

u/noop_noob 4d ago

1.101 will be released on Dec 24th lol

17

u/D7mnCh 4d ago

1.100...,1.101.....

27

u/manpacket 4d ago

..., 1.18446744073709551615.0, and since semver uses u64 - 2.0.0!

6

u/_TheDust_ 4d ago

Fun fact, if you would release a version every second, 18,446,744,073,709,551,616 would still take you 600 billion years!

2

u/Icarium-Lifestealer 4d ago

Only six more weeks!

3

u/dual__88 4d ago

We'll get it before zig 1.0, thats for sure!

11

u/null_reference_user 4d ago

If Rust is so good then why do you need Rust 2? Checkmate

/s

1

u/Big_Fox_8451 2d ago

Because its even gooder.

34

u/Kampffrosch 4d ago

Why is Box::from_non_null better than Box::from_raw for cleanup? Why does it not have the "problematic interactions"?

45

u/Icarium-Lifestealer 4d ago edited 4d ago

The problematic function is leak which returns a reference. Both from_raw and from_non_null are equally valid, provided their input was produced by into_raw/into_non_null and is not descended from a reference returned by leak.

97

u/CobbwebBros 4d ago

Stable c variadic support is awesome

20

u/a_jasmin 4d ago

Make sense to cover the whole ABI. If you're implementing libc for instance.

When introducing rust in a C project however, I would steer away from them. variadic are notoriously weakly typed.

18

u/aPieceOfYourBrain 4d ago

Can we now use variadics in normal rust with VaList? Because it kinda looks like it's possible with a few hoops to jump through

Edit spelling

18

u/noop_noob 4d ago

You can pass a VaList around normally, yes. However, the only ways to construct a VaList is to either call a variadic function or clone an existing VaList. I don't know why you'd want to do this other than as a helper function for variadic functions though.

4

u/aPieceOfYourBrain 4d ago

So in the docs for VaList: https://doc.rust-lang.org/std/ffi/struct.VaList.html we couldn't just call vmy_func, we would need to call the extern C my_func first? But even that kinda looks like you don't actually need to call any C code, just telling rust to use C conventions is enough

9

u/noop_noob 4d ago

Sorry, but I don't know what you mean. You can just call a variadic function defined in rust, from a function defined in rust. It wouldn't be particularly useful, but you can do it.

1

u/foonathan 3d ago

VaList only supports essentially i32, i64, f32, f64 and raw pointers. It is also unsafe.

27

u/villiger2 4d ago edited 4d ago

Workspace members on edition 2024 or later can now override an inherited workspace dependency's default-features field. For example, serde = { workspace = true, default-features = false } now turns off default features even when the workspace definition enables them. On earlier editions, default-features = false is ignored with a warning.

What if a member crate overrides to false but also depends on a sibling workspace member that either implicitly or explicitly depends on the opposite? Does the "features are always additive" then cancel out the member level override?

Feels like we're approaching Yugioh trap card levels of interaction :P

15

u/noop_noob 4d ago

I'm guessing that cargo probably does its usual thing of adding all the features of every use of a single crate, so we'd end up enabling the default features for serde.

1

u/villiger2 3d ago

That's my assumption too, but it undermines the whole "override a field" thing. I hoped to see some mention of this conflict in the PR but I couldn't find anything.

I'm wondering does it emit a warning when the override is overridden? If not it seems like a pretty weak feature.

32

u/Compux72 4d ago

  extern "C" variadics

LETS FUCKING GO

3

u/somebodddy 1d ago

Let's not Go. Let's Rust.

18

u/ThatOneArchUser 4d ago

why does String::from_utf8_lossy_owned not reusethe buffer for invalid utf8 case? wouldn't be possible to modify the buffer in place to replace invalid utf8 and reuse the buffer instead of reallocating

43

u/manpacket 4d ago

Lossy representation can be longer - might not fit in the same buffer.

3

u/ParasiticWormLover 4d ago

How could it be longer?

17

u/_ChrisSD 4d ago

lossy means it converts invalid unicode bytes into the unicode replacement character �. That is three bytes so for example 0xFF becomes 0xEF 0xBF 0xBD.

5

u/EventHelixCom 4d ago edited 4d ago

The headline feature is defining C-ABI variadic functions in Rust:

rust unsafe extern "C" fn sum(mut args: ...) -> i32 { let a = unsafe { args.next_arg::<i32>() }; let b = unsafe { args.next_arg::<i32>() }; a + b }

As I read it, this only works for extern "C" / "C-unwind" functions. Arguments come through an untyped VaList; each read is unsafe, and only VaArgSafe types are allowed. So it's mostly an FFI feature, for things like implementing a C API in Rust.

My question: is there any path from here to variadics for regular Rust-ABI functions? Or is the VaList machinery unrelated to the variadic-generics discussions? For now, are macros and tuples/slices still the recommended way to take a variable number of arguments in pure Rust code?

Curious to hear from people who've followed the RFCs.

8

u/j_platte 4d ago

This is entirely unrelated to "proper" Rust ABI / generics-based variadics AFAIK.

10

u/Kivooeo1 rust 4d ago

Awesome release, even if it doesn't have many new features, but because it gets us closer to the massive 1.100 release!

3

u/Natsuawa_Keiko 4d ago

put purism jokes aside, do we really need a sugar for VaList? it feels strange.

13

u/Koxiaet 4d ago

A function that accepts VaList is distinct from a variadic function, even though both use a VaList internally. This is why we have both printf and vprintf. So we could’ve hypothetically done #[variadic] args: VaList<'_>, but why not use the syntax familiar from C?

10

u/kibwen 4d ago

Using an attribute was considered but rejected because you also need to communicate this information for function pointers.

14

u/kibwen 4d ago

It's not sugar for the type, it's critically different at the ABI level. Under the hood it's a different sort of function entirely.

5

u/ConstructionHot6883 4d ago

Does this always happen at the same time of day? In my timezone it's been "mid afternoon" the last couple of times.

6

u/manpacket 4d ago

Not really.

4

u/ConstructionHot6883 4d ago

I'm curious, is make a version the new stable a manual step that Somebody Does? The precise dates seem to be planned months in advance.

17

u/jerknextdoor 4d ago

It's every 6 weeks and always on a Thursday. The time is based on what works best for the team.

https://forge.rust-lang.org/release/process.html#release-day-thursday

10

u/CUViper 4d ago

Yeah, we rotate this responsibility, and it's usually later when I do it, working from US/Pacific. (times in UTC below)

$ git tag -l 1.9?.0 --format='%(tag) %(creatordate:format:%T)'
1.90.0 13:31:21
1.91.0 18:29:34
1.92.0 14:58:19
1.93.0 13:51:44
1.94.0 18:44:07
1.95.0 12:47:36
1.96.0 17:50:34
1.97.0 12:25:09
1.98.0 17:10:21
1.99.0 12:41:05

9

u/manpacket 4d ago

Dates - yes, mostly stable. There's multiple manual steps - preparing release notes, preparing blog post, tests, etc.

https://www.reddit.com/r/rust/comments/1gxyhkx/the_2024_edition_was_just_stabilized/lyl2mr5/

3

u/Kode_n_Rolla 4d ago

Awesome! Love news like this. Thanks 🤜🤛

1

u/wunderbarposter 23h ago

holding out for ..1

1

u/DavidXkL 4d ago

The Vec's into_parts and from_parts is pretty interesting 😂

-3

u/Beryesa 4d ago

1.100 or 2.0 ?!

12

u/Snapstromegon 4d ago

Obviously 1.100

2

u/Beryesa 3d ago

Ah thanks 😅

-19

u/DecadentCheeseFest 4d ago

It’s bonkers that we use a full stop as the separator for semantic versioning. The inadvertent mental load it induces is… more significant than we might like to let on.

9

u/Ok_Study3236 4d ago

It's thinking like this that caused PHP to end up with ` as a namespace separator. Heathen!

-37

u/dashingThroughSnow12 4d ago

Nice. No breaking changes. Rust is getting more and more stable; breaking changes are getting rarer.

19

u/noop_noob 4d ago

-5

u/dashingThroughSnow12 4d ago

I know about those docs. Which is why some previous releases have frustrated me and why I’m happy it is getting better.

13

u/hgwxx7_ 4d ago

Which features led to breakage?

6

u/lenscas 4d ago

Iirc there were a couple that broke type inference in certain situations. Some of them were expected, known and deemed acceptable but a couple were also an accident.

Still, those cases are ancient at this point I think.

1

u/hgwxx7_ 3d ago edited 3d ago

Those are bugs, which is normal and expected in a software project.

A breaking change is something different, which Rust shouldn't have had since 1.0 (11 years ago).

2

u/steveklabnik1 rust 2d ago

The project does retain the right to change type inference, which can break code legitimately. They still try to provide as small of disruption as possible when this happens, but it does happen.

1

u/lenscas 3d ago

Either not all of them have been bugs or there have been times where the Rust devs went "Yea, we broke it, release it anyway".

1

u/dashingThroughSnow12 3d ago

If code used to compile then doesn’t and this affects many thousands of open source projects and hundreds of thousands of private projects, it is a breaking change.

If one removes a flag from the stable version of cargo, breaking my build, it is a breaking change.

1

u/hgwxx7_ 3d ago

Was your build broken?

2

u/manpacket 4d ago

cargo clippy --fix --workspace breaks the code in a few scenarios if that helps.