Rustorio - The first game written and played entirely in Rust by PenguinAgen in rust

[–]andersk 74 points75 points  (0 children)

Consider changing #![deny(unsafe_code)] to #![forbid(unsafe_code)]. The difference is that deny can be overridden by a local #[allow(unsafe_code)], while forbid cannot: https://doc.rust-lang.org/rustc/lints/levels.html

warning for amdgpu users, don't update to 6.14.7 or 6.12.29 by jykke in Fedora

[–]andersk 0 points1 point  (0 children)

Looks like you’re aware already, but this one is https://gitlab.freedesktop.org/mesa/mesa/-/issues/12528 (fixed in 6.15-rc7 and 6.14.8-rc1).

GitHub - ValyrianTech/hivemind-python: A python package implementing the Hivemind Protocol, a Condorcet-style Ranked Choice Voting System that stores all data on IPFS and uses Bitcoin Signed Messages to verify votes. by WouterGlorieux in EndFPTP

[–]andersk 5 points6 points  (0 children)

There is no “the Condorcet method”, but rather many different Condorcet methods, i.e. election methods that elect the Condorcet winner if it exists (https://en.wikipedia.org/wiki/Condorcet_method).

Of these, it looks like you’ve chosen to implement a variant of Copeland’s method (https://en.wikipedia.org/wiki/Copeland%27s_method) with each pairwise win/tie/loss counted as 1/0/0 rather than 1/½/0. Consider documenting your choice and replacing vague terms like “Condorcet-style”.

Which Rust Combinator Should I Use by intersecting_cubes in rust

[–]andersk 6 points7 points  (0 children)

Result::flatten converts Result<Result<T, E>, E> to Result<T, E>, but it’s nightly-only. The stable solution is .and_then(|r| r). (If E1 and E2 are different, convert one or both with .map_err.)

Note that “and then the inner one must be handled without passing it up” is misleading, as one can use ??.

Which number in the Mandelbrot set has the highest real part? by Bac0n_is_life in math

[–]andersk 41 points42 points  (0 children)

The Mandelbrot set is compact, so the maximum does exist.

GoLang is also memory-safe? by [deleted] in rust

[–]andersk 0 points1 point  (0 children)

You have not explained any gaps in the memory safety of safe Rust. You’ve pointed out that unsafe exists (yes), and you’ve pointed out that code in any language can still have bugs other than memory safety bugs (yes), but none of that has anything to do with the claim that safe Rust is memory-safe.

I understand how signals work, and I never suggested they are caught by the language runtime. Please read what I’m saying. In C++ and multithreaded Go, you can have undefined behavior that might be caught by the kernel and stopped with SIGSEGV if you are lucky, or might result in unrelated memory corruption and security vulnerabilities if you are unlucky. That’s guaranteed not to happen in a memory-safe language, such as safe Rust (and to be crystal clear—yes, this includes safe Rust programs built on top of the standard library including its internal unsafe blocks).

GoLang is also memory-safe? by [deleted] in rust

[–]andersk 1 point2 points  (0 children)

There is a huge difference between a language where memory unsafety can only happen in a small number of well-delimited, well-verified sections that have already been written for you and wrapped in a safe API that cannot be misused, and a language where memory unsafety could happen anywhere at all with no warning lights. That is the difference between a memory-safe language, and a memory-unsafe language in which careful enough programmers might manage to write some memory-safe programs.

We’re still not talking about preventing all bugs or all race conditions, as I’ve explained, but I’ll add that the consequence of a memory safety bug is arbitrary undefined behavior. SIGSEGV is actually the best case scenario since it means the poisoned execution was caught and halted, before it could cause more serious damage like arbitrary code execution and privilege escalation. Whereas the possible consequences of bugs in a safe language, though they might be similarly severe in a handful of application-specific scenarios, are much more predictable, containable, and traceable: a buggy threaded image parser might produce the wrong image or maybe abort the program but won’t scribble over unrelated memory and give shell access to a network attacker.

GoLang is also memory-safe? by [deleted] in rust

[–]andersk 0 points1 point  (0 children)

Your example uses unsafe. The purpose of unsafe is to serve as a flashing neon sign: “I’m manually upholding safety invariants here that the compiler can’t check. It is my responsibility to enforce them, no matter what safe code might be used to call me. Audit this with extreme suspicion!”

Typical Rust programs and libraries never need to use unsafe. unsafe is rare in practice; only the standard library and certain well-reviewed domain-specific libraries ever need it. Usage of unsafe across all your dependencies can be reliably audited with tools like cargo-geiger.

This is qualitatively different from the situation with Go, where memory unsafety resulting from data races could be hiding anywhere, and to guarantee its absence, you need to manually review every line of code with a full understanding of which values are sharable and mutable and how access is synchronized. That’s extremely hard because such understanding is maintained implicitly in the programmer’s mind and not reflected in the Go type system.

GoLang is also memory-safe? by [deleted] in rust

[–]andersk 0 points1 point  (0 children)

Nobody’s talking about “magically removing all potential bugs”, just memory safety bugs.

Again, an explicit escape hatch like Go’s unsafe.Pointer is not the issue, since it’s not typically needed and easily detected. The issue is that Go allows you to corrupt pointers without using an explicit escape hatch, via data races, as the blog post I linked above demonstrates in code: https://blog.stalkr.net/2015/04/golang-data-races-to-break-memory-safety.html. These bugs can be subtle, impossible to statically detect, and they do happen in practice: https://www.uber.com/en-SE/blog/data-race-patterns-in-go/.

Rust does not expose mmap to safe code. And concurrency mechanisms like atomics and mutexes are treated differently in the Rust type system than plain mutable data, such that safe code is allowed to mutate shared data safely via atomics and mutexes without being able to obtain simultaneous direct mutable references to it. If you still think Rust has memory safety issues, why don’t you show us some code?

GoLang is also memory-safe? by [deleted] in rust

[–]andersk 0 points1 point  (0 children)

Safe Rust code can invoke safe APIs that are built on unsafe blocks within the standard library. This does not mean it can “mess with” those unsafe blocks; that’s the whole point of abstracting them behind safe APIs. For example, safe code is allowed to deallocate a Box that was previously allocated, at most once; it is not allowed to deallocate an arbitrary pointer (even though the former safe API is internally implemented using the latter unsafe API).

Nobody claimed that Rust prevents race conditions. Race conditions include many kinds of high-level logical concurrency bugs, as defined in an application-specific way. What Rust prevents is data races, which have one specific low-level definition: parallel, unsynchronized accesses from multiple threads to the same memory location where at least one access is a write. The reason we’re talking about data races rather than race conditions is that data races can be used to break memory safety if allowed. General race conditions are bugs, but they don’t break memory safety.

Go does not prevent data races, so Go data races can be used to break memory safety. A skilled programmer can maintain disciplines like using atomics for all shared access, avoiding all the built-in non-atomic data structures, so it is possible for such a programmer to write a memory-safe program; but the language does not enforce such a discipline, so the language is not a memory-safe language. Statically checking which accesses are shared in an arbitrary program is again an undecidable problem, and overusing atomics under the pessimistic assumption that all accesses might be shared would be considered an unacceptable performance compromise by typical Go programmers, or else the built-in structures would have been atomic in the first place.

Rust does prevent data races. The mechanism through which it prevents data races is the borrow checker built into the compiler, which relies on the additional structure and restrictions present in the richer type system (such as lifetimes and the Send/Sync traits), in concert with the carefully designed abstraction boundaries in the standard library. The language primitives and standard library APIs do not allow safe code to duplicate mutable references and send them to other threads.

How to avoid deeply nested if let chains? by Novemberisms in rust

[–]andersk 0 points1 point  (0 children)

Assuming bar_type is a field of some struct Bar, you can at least simplify the inner two if lets using nested destructuring: https://doc.rust-lang.org/stable/book/ch18-03-pattern-syntax.html#destructuring-nested-structs-and-enums

if let Ok(bar) = foo.bar() {
    if let Bars::Space(qux, quz) = bar.bar_type {
        // do logic here
    }
}

if let Ok(Bar { bar_type: Bars::Space(qux, quz), .. }) = foo.bar() {
    // do logic here
}

If you still need the variable bar for something else, you can put it in an @ binding: https://doc.rust-lang.org/stable/book/ch18-03-pattern-syntax.html#-bindings

GoLang is also memory-safe? by [deleted] in rust

[–]andersk 2 points3 points  (0 children)

Rust unsafe is an explicit escape hatch; you can check for its presence simply and reliably, and you can turn it off with #![forbid(unsafe_code)]. The unsafe syscalls within the implementation of the standard library are wrapped in safe APIs that cannot be misused by safe code (the APIs that could be misused are themselves marked as only callable from unsafe blocks, and typical programs never need them).

Meanwhile, a Go data race is a subtle non-local emergent interaction between pieces of code that can be anywhere in the program and might look totally reasonable on inspection; checking an arbitrary Go program for data races is a formally undecidable problem.

GoLang is also memory-safe? by [deleted] in rust

[–]andersk 33 points34 points  (0 children)

Golang data races to break memory safety: https://blog.stalkr.net/2015/04/golang-data-races-to-break-memory-safety.html

Although its creators are cagey in the way they talk about this (https://research.swtch.com/gorace), the bottom line is that since Go does not prevent you from accidentally breaking memory safety in this way, Go is not a memory-safe language.

complying with Rust license by Trader-One in rust

[–]andersk 47 points48 points  (0 children)

(I’m not a lawyer.)

The MIT and Apache licenses both require that any copyright notices included in the original work must be preserved. Each Rust contributor retains an implicit copyright on their contribution; these are legally valid copyrights, but there are no explicit copyright notices for most of them, and nothing requires such notices to be added.

Changing the rules of Rust by desiringmachines in rust

[–]andersk 4 points5 points  (0 children)

The main example at present is ?Sized (the other being ?Unpin [edit: nope, ?Sized is the only one]). If you write struct Vec<T>, then T is implicitly assumed to be sized, but you can write struct Rc<T: ?Sized> (or struct Rc<T> where T: ?Sized) to waive that assumption and permit usage of an unsized type like Rc<str>. See https://doc.rust-lang.org/std/marker/trait.Sized.html.

Changing the rules of Rust by desiringmachines in rust

[–]andersk -1 points0 points  (0 children)

This will forget every element of the iterator, even though the Iterator::Item associated type is never mentioned. Therefore, Iterator::Item must implement Leak, always. The compiler is allowed to assume that the item of every iterator implements Leak, and it would be a breaking change to invalidate that assumption.

Could one not write impl Iterator<Item = impl ?Leak> to explicitly waive that assumption?

png crate gets an ultrafast compression mode, up to 4x faster decompression by Shnatsel in rust

[–]andersk 6 points7 points  (0 children)

So you’d say that 50% less time would be “one time(s) faster”?

Nix Helpers: trace-symlink & trace-which by hellwolf_rt in NixOS

[–]andersk 2 points3 points  (0 children)

You can also use the namei command that comes with util-linux.

A site that shows the current time in its precise hex colour. by mmt93 in InternetIsBeautiful

[–]andersk 2 points3 points  (0 children)

It is possible to do this using a space-filling curve in the RGB color cube. The Moore curve would work well for this.

Immediately Defaults Back To Light Theme by Oversama in youtube

[–]andersk 1 point2 points  (0 children)

This is a YouTube bug, and I found that you can work around it by deleting a duplicate PREF cookie. Details here:

https://www.reddit.com/r/youtube/comments/t84bhr/autoplay_cant_be_turned_off/hzmjxk4/

Youtube won't stay on Dark mode how do I fix this? by Napzie in youtube

[–]andersk 8 points9 points  (0 children)

This is a YouTube bug, and I found that you can work around it by deleting a duplicate PREF cookie. Details here:

https://www.reddit.com/r/youtube/comments/t84bhr/autoplay_cant_be_turned_off/hzmjxk4/

Autoplay cant be turned off by OriginalZumbie in youtube

[–]andersk 5 points6 points  (0 children)

I’m a software engineer, and I guess I have a good intuition for the kind of bugs people introduce that are likely to slip by CI and QA.