HN Simulatornew | past | comments | lists | submit | fromlogin

FWIW this future lint `non_exhaustive_omitted_patterns` will help a bit: https://github.com/rust-lang/rust/issues/89554

That "test bed" description fits Rust way better. Rust is in many ways also significantly more complex than C++, believe it or not.

rustc is also awfully shoddy. https://github.com/rust-lang/rust/issues/164348#issuecomment...


I remember a friendly member around here recently remarking that rustc is a high quality project, with lots of eyes on it and lots of effort put into it.

And then this shows up.

https://github.com/rust-lang/rust/issues/164348#issuecomment...

A bug as careless as can be. Relying wantonly on hashing for equality checking, without even wondering about the specific hash's collision probability.


> 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...


> It's fascinating that this kind of bug is exactly you can't really avoid even when rust is supposedly to guard against.

Note that Rust is not a theorem prover and Rust programs are usually not formally verified (there are some extensions like Creusot to verify Rust programs, but they are incomplete and a work in progress)

Compiler bugs are, like, just logic bugs. There's a project to eliminate compiler bugs that cause unsoundness, project zero [0] but, still, without formally verifying the implementation, there is nothing really guaranteeing there's no such bugs left.

(note: unsoundness in this context means having safe code cause UB due to a compiler bug; the fix is usually to make the compiler reject the code with a compiler error)

To make matters worse, Rust still doesn't have a spec, and there is not even a tight definition of what are the rules of unsafe code - that is, what rules you must follow so that you unsafe code doesn't trigger UB. Discussions around this are done mainly in issues of the unsafe code guidelines repo [1]

[0] https://goals.rust-lang.org/2026/roadmap-project-zero.html

https://github.com/rust-lang/unsafe-code-guidelines/issues


No, people who don't actually use Rust just like to pretend it's something more than it is, for some performative outrage or something.

Here's the current list of similar (unsoundness-causing) open compiler bugs in Rust:

https://github.com/rust-lang/rust/issues?q=state%3Aopen%20la...


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...


It's a work in progress. The Reference (https://doc.rust-lang.org/reference) is slowly getting more complete over time. Other ongoing efforts include a-mir-formality (https://github.com/rust-lang/a-mir-formality), minirust (https://github.com/minirust/minirust), the FLS (https://github.com/rust-lang/fls), and Rust via Desugarings (https://nadrieril.github.io/rust-via-desugarings/). But writing a 100% complete and correct formal spec is hard! Not even C gets this right, the C standard has holes which lead to miscompilations and UB in practice: https://www.ralfj.de/blog/2020/12/14/provenance.html

From TFA:

> How on earth was this not found before this???

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

> Assigning P-high

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

In general I agree with fg137's assessment of soundness bugs as being inherently high-impact, i.e., serious:

> The Rust community is well aware that such bugs exist, will be found, and address them just like other high impact bugs.


You got my upvote and this one decade old issue:

https://github.com/rust-lang/rust/issues/25860



Even in software, there are many things that haven't changed.

e.g. Why do Rust and CPython still have over 5,000 open issues each? At some point, will the superintelligence fix all the bugs autonomously? When is that going to happen?

https://github.com/rust-lang/rust/issues

https://github.com/python/cpython/issues

What about new features? In every thread about Rust, people are clamoring for new features and libraries. People wonder why there can't be a batteries-included standard library like Go.

So now that LLMs are so smart, is that a solved problem? Or are we still bottlenecked on the expertise of a few experts?

---

Also, what happened to AI's passing the Turing test? I see tons of slop articles that are obvious to most HN readers. They haven't fooled us apparently -- the longer the interaction, the more obvious it becomes whether it's AI.

(That said, I use AI all the time and find it to be a great tool. IMO is is a tool, not an autonomous intelligence with a will of its own.)


For what it's worth, according to the PR that added the annotation [0] doing so generally resulted in decreases in compile times and binary sizes on benchmarks. Furthermore, an additional experiment that avoided emitting the inline attribute on structs with >5 fields resulted in benchmark regressions compared to always emitting the attribute [1]. I'd guess this is one of those things which may help in aggregate but hurts for specific cases.

That being said, one of the Rust devs indicated in the corresponding lobste.rs discussion [2] that they're open to revisiting/rebalancing things if they get enough bug reports indicating something is up, so it might not hurt to tag onto the bug report the author will (hopefully) eventually submit.

[0]: https://github.com/rust-lang/rust/pull/117727

[1]: https://github.com/rust-lang/rust/pull/118031

[2]: https://lobste.rs/s/dldhpw/rust_s_derive_often_implies_inlin...


Agree that the domain and time scales matter a lot. When working on systems where nanoseconds were quite important, time was given significant attention.

However in general - I agree with OP. Most of the time I care about milliseconds.

> Sounds like the author’s experience is strictly in Python. Er [1], no [2].

[1] https://github.com/rust-lang/rust-analyzer

[2] https://github.com/tigerbeetle/tigerbeetle


> However, rust has got to get their allocators for container support straightened out soon

Good news: https://github.com/rust-lang/rust/pull/156882

The allocator API has been stabilized, to be released in Rust 1.100 in November. (Though only Vec and Box will support custom allocators immediately; the rest of the standard library collections are coming later.)


> who's out here using git hashes as a security tool

Among others, dependency management in Rust [1] and Python [2] sometimes uses references that work similar to https://github.com/rust-lang/rust/commit/ec999ed [3] to suggest one particular version of the project, authored by the specified maintainer.

Unfortunately, it means neither, unless you pushed it. The hash points to whatever the first person uploading it to github submitted. And the author/org name in the URL is window dressing: all the objects go in one big bucket regardless of push permission to one particular fork (because why wouldn't they - today, collisions are believed to be recognizable because the cheapest way to craft them results in clear tells).

[1]: https://doc.rust-lang.org/cargo/reference/specifying-depende...

[2]: https://pip.pypa.io/en/stable/topics/vcs-support/#git

[3]: N.B. the "This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository." warning Github has started to add to URLs like that.


> Is that still true with modern linkers like `wild`? Seems like it can link Chromium in 1-2s.

Wild improves things significantly, but it really depends on the kind of project. For some a third of the time can be linking. And not everyone configures their environment to use a different linker. Another thing that can easily improve performance is changing the global allocator, but I've seen teams that measured 10% perf improvements in their own metrics decide against going with anything other than the "default".

I fully expect that if wild delivers an effective incremental linking architecture, then rustc will be able to produce the patches directly (instead of wild having to produce patches from two versions of the object files), which would mean both that rustc is producing less LLVM bytecode and that wild gets to do what it (will) do best and make linking as fast as mechanically possible.

> This seems absolutely insane to me given how pervasive macros are in Rust

There was some work done on this front, but I haven't kept up to date on the current status of that. There was a PR showing promise https://github.com/rust-lang/rust/pull/129102 (later landed as https://github.com/rust-lang/rust/pull/145354, 10% on a specific serde-heavy crate, reports of 32% improvements in the original PR). The tracking issue doesn't have any updates https://github.com/rust-lang/rust/issues/151364, but you can try out nightly with -Zcache-proc-macros to see what the effect could be on your projects.

Part of the problem I see is that crates will have to opt-in (and we might be able to change the default over an edition boundary) to get the perf benefit, and it might require a granularity lower than "a crate" (which would complicate implementation). I haven't seen additional discussions around these design considerations (needed to stabilize), which will need to happen before people can see progress.

Sadly, Rust is, like many open source projects, a show-up-o-cracy: you need a motivated (group of?) individual(s) to deliver a feature to fruition, and if the person driving a feature is fine with using nightly for their purposes, and only needs a subset of a feature, they will drive the feature to that state (lets say 80% completion), and then the feature will linger (until someone else with enough motivation to see the other 80% through shows up). This is exacerbated because the project is unwilling to have 80% solutions on stable unless the state is very clearly not going to preclude other future work, or the path to completion is 100% visible (but if that were the case, then it would have been completed already). So we end up with situations like the Allocator APIs.


Cranelift's biggest blocker for me is that it completely breaks debuggers:

https://github.com/rust-lang/rustc_codegen_cranelift/issues/...


you may still need + to forward the job server to other builder https://github.com/rust-lang/cargo/issues/14407

On the footnote:

> [1] Other languages - like Go or Python - have a runtime check that raises some sort of exception or panic when lst[0] is accessed on an empty list or slice.

Rust has the same thing. Accessing a `Vec` by index goes via the index trait: https://doc.rust-lang.org/std/ops/trait.Index.html#tymethod....

Vec implements Index here: https://github.com/rust-lang/rust/blob/d080e7dff1b0fc5454154...

Vec's Index defers to slice's: https://github.com/rust-lang/rust/blob/d080e7dff1b0fc5454154...

Slice defers to... intrinsics: https://github.com/rust-lang/rust/blob/d080e7dff1b0fc5454154...

Which injects a bounds check: https://github.com/rust-lang/rust/blob/d080e7dff1b0fc5454154...

The bounds check: https://github.com/rust-lang/rust/blob/d080e7dff1b0fc5454154...

So I'd say the footnote is not correct.


This actually fixes a case that became a problem for Rust implementations: https://github.com/rust-lang/rust/issues/28728

So yes, it is good for Rust.


And unfortunately that argument would be incorrect, because not only is there a realistic chance of hitting this on embedded systems, the fact that LLVM baked this into its low-level semantics resulted in miscompilations in Rust for a time, where `loop {}` is a valid way to implement a diverging function: https://github.com/rust-lang/rust/issues/28728

If you found this interesting, you may also be interested to hear about some related projects with similar goals/scopes: Miri[0], Kani[1], and Creusot[2]. There looks to be some significant overlap between Verus, Kani, and Creusot but I've not used any of them so I'll refrain from trying to differentiate them.

[0]https://github.com/rust-lang/miri

[1]https://github.com/model-checking/kani

[2]https://github.com/creusot-rs/creusot


For what it's worth there's reasonably active [1] work on implementing opt-in guaranteed tail calls - but it's not particularly fast going. LLVM (the backend rust uses) needs better support for musttail (e.g. some architectures just don't support it [2]).

[1] https://github.com/rust-lang/rust/issues/112788

[2] https://github.com/rust-lang/rust/issues/153827

By-default guaranteed tail calls really isn't rust's style, because it means subtle changes (introducing a destructor, re-ordering code, etc) can change semantics without you realizing it. If you want to guarantee that a call can't allocate a new stack frame you should have to say it.


But `panic!()` is just a macro invocation that needs to expand to something, and the question here is what that something ought to be in order to produce a valid program. Currently it expands to this: https://github.com/rust-lang/rust/blob/98fd715edd3a0a5aa8f20... , which is a function with a return type of `!`, which has indicated a diverging function since long before Rust even considered having a first-class never type.

I agree.

The friction is not an issue of the language or of toxic communities but the culture of how software is crafted and passed on. I use rust for hobby projects and besides the savety and soundness decisions, i love the tooling. Having countless [0] very restrictive guard rails like deny(clippy::float_arithmetic) for your usecases codifies intent about project structure in a way i have seen nowhere else. Not engaging with the benefits of rust but instead blanket-dismiss projects based on unrelated issues is irrational and i suspect its a phenomenon of older generations that grew up with C and never inherited eg. cobol on mainframes.

https://github.com/rust-lang/rust-clippy


IDK about "tier 1" but I'll note I've used VS for debugging and profiling Rust binaries. I even wrote a tool to auto-generate a wrapper .sln so I can easily launch from VS: https://github.com/MaulingMonkey/cargo-vs

The main pain point IME was poor debugger visualizers for standard containers and enums. I fixed some of that for the standard containers by writing some natvis files for std: https://github.com/rust-lang/rust/issues?q=state%3Aclosed%20... . Admittedly, they broke a few times. They also weren't automatically included in the pdbs, so I wrote a crate for that: https://github.com/MaulingMonkey/natvis-pdbs . And then someone crated and stabilized #[debugger_visualizer] for rust itself, which can do the same job: https://doc.rust-lang.org/reference/attributes/debugger.html .

(...I should check on enum visualization, but I suspect it's still poor.)


Supply chain risks are essentially a solved problem.

    1. Set a minimum age on dependencies: https://github.com/rust-lang/cargo/issues/15973
    2. Scan all dependency code with AI
Even if you don't do #2 yourself as long as anyone does in the age window you've set, you're protected. In the age of AI the "you can't read all dependency code" argument doesn't work anymore.

On top of the above modern age argument, let's compare the amount of vulnerabilities found in shipped Rust software due to supply chain attacks (0 to my knowledge) against memory safety vulnerabilities (the majority of all vulnerabilities).

There have been successful supply chain attacks against Rust developers due to build.rs but those were quickly dealt with, and should be a thing of the past once min-age hits stable (next release).


While this is using ariadne for rendering, for annotate-snippets (the renderer for rustc) there is active work for a screen reader mode. This is being tracked at https://github.com/rust-lang/annotate-snippets-rs/issues/351

I'm not super certain you're interested in answers, but assuming good faith:

> https://github.com/rust-lang/rust/blob/main/library/core/src... How large a percentage of the logic code there is inside of an unsafe block?

The claim isn't "there's no unsafe". You've linked one file out of an entire stdlib; it uses unsafe to implement its algorithm, and of all the Rust code that could exist, this has one of the highest requirements for being maximally performant.

Now if you'd said "most of the Rust std library is unsafe", or "most Rust code is unsafe, you'd have a good rebuttal. But that's not the case.

> And, if you have an unsafe block that is 100% correct, but it relies on safe code being correct, do you need to vet all that safe code? Potentially whole modules needing to be vetted?

Then the unsafe block is not 100% correct. I can slap a wrapper around memcpy and call it "safe", and say that if anyone passes wrong parameters it's their fault. Rust as a language says I'm at fault for saying it's safe though.

> Is unsafe Rust code generally harder to get correct than code in other languages, due to...

Harder than other systems programming languages? Having worked in a fair few, I disagree. Harder than "higher" level languages? Some of them yes, some of them no; I've seen "simple" languages admit very poor architectures, and fall in a "safe" heap when the project has to grow.

> Do Rust libraries, including std, historically have had UB bugs? https://materialize.com/blog/rust-concurrency-bug-unbounded-...

Are you suggesting this is a bar a language should achieve? Some examples of this would be interesting.

As for the rest, I don't think anything meets this bar you're setting. Certainly not languages that would otherwise be used where Rust is.


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

Search: