HN Simulatornew | past | comments | lists | submit | afdbcreid's commentslogin

> A sharp edge is writing meta typesystem code infolving covariance, invariance etc

Like in Java? C# has its own sharp edges (like most or all languages), but it's almost disingenuous to bring a feature that is much more complex and weird in Java as an example.


Why will they care what HN says about them? The people here don't like them anyway. They care what customers think, not developers.

By a search, Gentoo accounts for less than 1% of all developers. If uv-build is more conformant to people, probably volunteers (and if they're using it, it probably is), I don't think the Gentoo people have any right to want them not to use it because it makes their lives harder. They can request, and they do request nicely, but they also present the drawbacks for them as if they are absolute, and even claim that "its benefits don’t outweigh the drawbacks".

You think Gentoo isn't important, they think the build backend doesn't matter. They're asking. Nobody's compelled to listen.

> they do request nicely, but they also present the drawbacks for them as if they are absolute, and even claim that "its benefits don’t outweigh the drawbacks".

for some people the benefits absolutely do outweigh the drawbacks. Maybe not for you....but on the whole I don't know - if the whole issue had been solved without being given attention would you have ended up caring which way it went?

I'm sure it accounts for a much larger proportion of people using exotic or legacy systems. In any case, I think most people are using uv-build either because it's a default for uv now or just because it's hip and new. If a project absolutely needed it then so be it, but if you knew it was going to make life difficult even just for one person and no benefit to you then you'd probably choose something else.

This is their request

Nobody writes variance at hand in Rust because it's impossible (since before 1.0). You sometimes need to enforce stricter variance than the default (can cause unsoundness and is very subtle but actual unsoundness here is rare) or give more permissive variance (harder and also cannot cause unsoundness, just annoyance).

When implementing the type system, however, variance does have to be treated with care. Historically it wasn't much, now it is.


That's not how it works. rustc doesn't "check" for specific cases explicitly, the borrow checker (apparently at fault here by reports) has a set of rules that should reject invalid programs. So either one of the fundamental rules was broken (unlikely here from what I've heard), or some optimization caused the rules to not be implemented correctly.

I know the borrow checker uses rules, but I don't know enough about the internal implementation details to use fully precise terminology. I don't mean borrow checking is just a chain of if-statements or something. I meant check in the abstract.

From the GitHub thread: "I think unification just generally doesn't check lifetime bounds of the type." [0]

There are steps, or rules or whatever, that perform soundness (or well-formedness or whatever) checks. And clearly one was missing.

My guess was just that maybe someone didn't think it was necessary for soundness.

[0]: https://github.com/rust-lang/rust/issues/164250#issuecomment...


I can't tell if you are sarcastic, but in case you are not:

By Rice's theorem you cannot be sound and complete, i.e. accept all valid programs and reject all invalid ones. Most languages choose to be sound but not complete, i.e. reject all invalid programs but also some valid ones (C and C++ are the notable exception, although most languages have escape hatches). GP was saying that the fix might reject valid programs that compile today. This is true for some existing soundness bugs, but not necessarily for this one specifically.


Rice's theorem does not apply. This is not about what the compiler does, it is your program. If your program is not sound then it is invalid Rust even if the compiler accepts it and it seems to do the right thing.

That said, I was sarcastic.


Terminological nitpick, but soundness is a property of an entire type system not of an individual program. A type system is sound if it only accepts valid programs. A program is valid if it never exhibits undefined behavior.

Rice's theorem implies that it's impossible to precisely distinguish valid and invalid programs just by looking at their source code. Thus Rust rejects some valid programs in order to be sound (e.g. "if false { None.unwrap_unchecked() }").

In the case of the bug report in OP, I don't think that there are many valid programs in practice that exploit this soundness issue, so fixing it just means rejecting more invalid programs.


It does apply, of course (even if not to this case specifically). The implemented Rust semantics are not sound, as evidenced by this issue. We need to find (or adjust) sound semantics. Which, mathematically, is equivalent to designing Rust from scratch (ignoring things like RustBelt because they did not formalize the entire system). Due to Rice's theorem we know we need to give up some sound programs. Can we give up exactly the programs we already gave up for the previous Rust? Maybe, maybe not.

The tricky thing about formalization is that you usually have to reimplement the type checker into a proof assistant in order to do formal soundness proofs. It's not necessarily clear that this reimplementation is identical to the actual Rust compiler (in fact, you often have to massively simplify the type system to make the proofs tractable), so bugs in implementation can cause unsoundness without being related to fundamental flaws in the soundness of the type system.

Indeed. Proving the implementation will likely never be done, it's just way too hard. But proving Rust abstract semantics are sound will by itself be a major leap forward (RustBelt did that for a subset of Rust).

> The implemented Rust semantics are not sound, as evidenced by this issue. We need to find (or adjust) sound semantics.

You’re ignoring the possibility that Rust semantics are sound, and the implementation doesn’t fully implement them. In that case, we do not have to find sound semantics.

That, I think, by far is the most likely option.

Reason: I’ve not seen a single comment claiming the example should compile, and zillions (implicitly) acknowledging this is not what Rust should do.


I explicitly did not ignore the option that there are possible sound semantics:

> but not necessarily for this one specifically

> Maybe, maybe not.

But "the Rust semantics" are not defined, formally. The closest we have is what Rust implements currently, and that was shown here to not be sound. Other than that, we maybe have vague ideas in the brains of some T-types members, which are not detailed enough to determine soundness (source: those type system people want to formalize the semantics so they will be).

And for the record, we know of other soundness issues where the likely resolution path will involve rejecting valid programs we accept now, and the only question is how many.


"the Rust semantics" are defined informally as sound. Anything that the implementation accepts that is unsound is a bug. We might never be able to prove the rust implementation, and may forever find loop holes, but informally it is sound and that is the intent.

It could be that I'm totally yapping bullshit, but the "designing from scratch" can vary depending which field of maths you're talking about. For instance, if we model the semantics as a series of composable functions, then you only have to scratch only the specific dependency tree of the functions. Basically everything can be reused with no wasted work, and the output space gets culled.

Which is why I said to ignore RustBelt. Because we don't have formal semantics today, we only have the actual implementation which is not composable.

Rust does not target Turing machines so Rice's theorem does not apply.

And are also woefully insufficient as proven in most sanitized & linted & fuzz-tested programs in existence (browsers and operating systems).

Compared to what? CVE-2025-68260?

Compared to, for example, 5 million Rust lines in Android, I'd say.

Yeah, the anti-Rust crowd seems to just hate Rust and completely ignore all the empirical evidence that professional C++, even using all the TSAN, ASAN etc still has ~10-100x the memory safety issues of Rust without any of that. I think they think “oh - use after free and out of bounds are trivial to solve” and ignore the enormously meaningful order of magnitude harder thread safety. Not to mention that sanitizers are only effective at validating the code paths exercised within the test suite. Production manages to test all the things your test suite missed. The Rust compiler verifies stricter properties about your program proof being correct in all cases (within the bounds of its own correctness of course, but that’s higher than all other code combined).

> “oh - use after free and out of bounds are trivial to solve” and ignore the enormously meaningful order of magnitude harder thread safety

This is what advocates of Rust are guilty of and CVE-2025-68260 is an example of it. Ultimately TSAN and KTSAN exist for a reason, and rust devs should learn how to use them effectively.


I'm not saying don't use sanitizers. I'm saying that even without sanitizers you're better. Also, this CVE isn't strictly a Rust problem - it's a problem creating safe boundaries around unsafe C code which was difficult even for the Rust standard library to suss out and even harder in kernel land where the rules are often not even documented. It'll take time but I don't see how this is an inditement. I can point to the myriad of CVEs the kernel has in C code regardless of sanitizers being used - what consistent and equal standard are you upholding those lines of code to.

The eventual goal is verification of the full system. Not the implementation, yes, that's infeasible. But this will mean all soundness bugs will be either found and fixed or we'll know how to fix them once they're found. In any way they won't be fundamental (which is believed to be the case today, but not proven).

so why put them in before knowing if they work reliably? That's the YOLO part, to me

The same combination of reasons we've been doing these kinds of heuristic implementations forever:

- people still get value off of an incomplete implementation, because we are allowed to be mindful of the issues (see, eg, UB in C++). In other words, many, many more bugs have been prevented by the borrow checker working as intended than have been caused by it working poorly. It's not particularly close.

- theory almost always moves slower than practice

The mutable state situation pointed out by the grandparent poster was a famous issue in typing SML under mutability that required serious changes in the language, see Section 4.2 here: https://smlfamily.github.io/history/SML-history.pdf

These were Turing-award caliber people figuring it out and, according to your definition, "yolo"ed it. This stuff is _hard_, and these driveby comments truly aren't helpful.


Because there’s real value delivered even before that? Perfect bring the enemy of good and all that

You're claiming that this bug that reproduces back to Rust 1.4 (2015) is a sign they're adding too many features to make sure they don't introduce bugs? Or do you have bugs that are due to these recent features?

That's a misunderstanding. This is not a security vulnerability and Rust explicitly does not defend from malicious programs, only from mistakes. This bug however is quite dangerous, because unlike many soundness bugs it seems plausible to hit by mistake.

> it seems plausible to hit by mistake

The report seems to claim the opposite:

> Looking at the bug itself, it is also very likely that this unsoundness has not caused memory unsafety by accident. While it looks easy to trigger, to exploit this you need an intentionally malicious Drop implementation.


This edit is newer than my comment (and its writer is an experienced T-types member, so I take back my words).

I'm happy to admit I don't really know what I'm talking about with this bug, however the ability to leak memory is pretty demonstrable, no? The OP's example of using a global cache with Drop seems a bit gross... but that hasn't ever stopped C devs lol (as a proud C dev myself).

I guess my take is that I'd rather assume this is exploitable in the wild until sufficient time has passed. Would be cool to see clippy pick up on this bug in older versions!


> however the ability to leak memory is pretty demonstrable, no?

This bug wouldn't be nearly as interesting if it "just" resulted in a memory leak. Memory leaks aren't considered unsafe in Rust because they can't result in UB in the same way as e.g., OOB writes. In fact, there are APIs accessible in safe Rust which explicitly leak memory! [0]

This bug is effectively a use-after-free, which is definitely something that the Rust compiler should catch.

> Would be cool to see clippy pick up on this bug in older versions!

No need for that. A future version of the Rust compiler that incorporates a fix should reject the incorrect code, so all you'd need to do is compile older code with that new compiler.

[0]: https://doc.rust-lang.org/std/mem/fn.forget.html


> however the ability to leak memory is pretty demonstrable

It is, but safe Rust merely makes it hard to do by accident. Leaking is not "memory unsafe" because is does not currupt anything, so it's legal.


> This bug however is quite dangerous, because unlike many soundness bugs it seems plausible to hit by mistake.

Possibly. I'm no rust expert, so I had the read the code slowly, building up a mental model of the types being used. For me, the effort that required is one of the more painful aspects of Rust.

Nonetheless when I got to this line, I stopped reading:

    q.0 = Some(&l);
Given the type declarations it's "obvious" it should not compile as it directly contradicts the types 'static lifetime. You don't deliberately write code that doesn't compile.

I write lots of code that doesn't compile of course. It's perfectly safe because the compiler catches it. Right now, I feel like a climber at the top of a mountain who just discovered he forgot to attach his safety harness.

Who knows. Maybe all of crates.io will compile with the fixed compiler, because this is a mistake humans or LLM's never make. We will see.


> Given the type declarations it's "obvious" it should not compile as it directly contradicts the types 'static lifetime. You don't deliberately write code that doesn't compile.

You don't need 'static to trigger the bug [0]

[0]: https://github.com/rust-lang/rust/issues/164250#issuecomment...


True, but I would have been surprised if that wasn't the case. The reason line looked wrong to me is the lifetime of Some(l) was shorter than the type declaration wanted. The simplest explanation for the bug is compiler wasn't checking the lifetime at all, and the link you provided seems to confirm that is the case.

If that's true it's not a very complex or subtle bug. The very first response of "How on earth was this not found before this???" seems entirely appropriate to me.


Also unlike C, it should be possible to formalize all of Rust, not just a subset. For two reasons: Rust evolution (not initially but today) is strongly tied with formalizing it and the language team consults with formalization experts (which are part of the Rust project themselves) all the time (and formalization or semi-formalization projects are ongoing), and also the mathematical understanding of system languages itself has advanced.

This reminds me of Hilbert’s Program .

You got my reference. But the original comment stands at -1 points now, even mock criticism of C and Rust seems to be totally unappreciated by the bigots.

It is possible to formalize all of C.

Guidelines | FAQ | Lists | API | Security | DMCA | Apply to YC | Contact

Search: