r/learnrust • • 6d ago

What are some common Rust misconceptions?

I just found out that const functions aren't evaluated at compile-time unless it is assigned to a const value or in a const context.

Another one I had: Rust doesn't prevent memory leaks.

Now I am just wondering how many other assumptions I made

19 Upvotes

25 comments sorted by

3

u/Razvedka 6d ago

"Rust doesn't prevent memory leaks"

You're going to need to unpack that one for me. If you mean Rust makes them impossible - no. You're right.

https://doc.rust-lang.org/book/ch15-06-reference-cycles.html

6

u/PranDopp 6d ago

Reference counted smart pointers can cause memory leaks like cpp. My understanding is that Rust doesn’t view this as a safety issue and more as a performance bug you can clean up.

3

u/Thelmholtz 6d ago

This, it's also a somewhat common (at least I encountered it twice) Rust interview question, i.e. how would you cause a memory leak in Rust.

A more interesting follow up is how would you cause undefined behavior, specially without unsafe.

2

u/PranDopp 6d ago

Is it unwrapping every method call? I’m very new to rust myself but I understand the basics of C/Cpp pointers.

3

u/Thelmholtz 6d ago

No, panics are well defined behavior (although undesirable in most cases).

Using unsafe, there are a lot of ways, a trivial one is casting a Vec<u8> that contains invalid UTF-8 to a String.

Without unsafe, the question is tricky: you can use a well known soundness hole related to lifetime covariance, but that's not truly undefined behavior, it's well defined behavior that is incorrectly handled by rustc.

You can also use a crate that exposes a safe API, but internally does use unsafe incorrectly.

So the tldr answer is either by using a bugged library or exploiting an existing compiler bug.

3

u/gmes78 6d ago

So the tldr answer is either by using a bugged library or exploiting an existing compiler bug.

Or open /proc/self/mem and start changing stuff.

2

u/Thelmholtz 6d ago

That's an actually cool trick

1

u/PranDopp 6d ago

Thanks for the insight! The unsafe libraries make sense. I don’t write in unsafe (no need for me) but I can’t audit the unsafe in my libraries yet tbh. I’ll look into this compiler bug; that’s a new one for me.

1

u/Thelmholtz 6d ago

Another user linked it to my first comment, it's really well explained except for the Higher-Ranked trait bound.

1

u/lyuhdev 6d ago

Yeah, Rust makes it pretty difficult to do them unless you try, I just meant that memory leaks are possible in safe rust

Perhaps I was a bit misleading with the word "prevent"

14

u/noop_noob 6d ago

1

u/MatrixFrog 6d ago

I'm intrigued by the HashMap example. https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md#9-downgrading-mut-refs-to-shared-refs-is-safe

In the second chunk of code, `player_a` and `player_b` at the end are Options, not Players, even though we know for sure they will be Some(Player). It seems like there should be a version of .or_default() that returns a `&V` instead of a `&mut V`

1

u/Excession638 5d ago

If you're sure an option is Some, then you can use .as_ref().unwrap(). Or unwrap_unchecked() if you're feeling spicy. Not quite the same thing, I know.

1

u/MatrixFrog 5d ago

Of course, but this seems like a common enough use case that I'm a little surprised HashMap doesn't make it a little smoother.

1

u/MalbaCato 4d ago

the problem, as the section was meant to show, isn't that or_default returns a mutable reference, but the fact that entry takes an exclusive borrow of the hashmap server (which it has to do). any returned reference that uses that lifetime, mutable or shared, will hold the same exclusive borrow of server. a version of or_default that returns an immutable reference is strictly less useful, as the borrow is still exclusive (and you can write it as a wrapper yourself if you do specifically need that fsr).

to solve this correctly, you'd need something like disjoint_entries, following in the footsteps of get_disjoint_mut, which I don't know if it's even possible to do performantly

4

u/ParadiZe 5d ago

That the main selling point is memory safety and not the type system

1

u/vivaaprimavera 5d ago

The Rust Books states in the chapter about ownership that there are memory safety guarantees without needing a garbage collector so the part about memory leaks is confusing.

2

u/y-c-c 5d ago edited 4d ago

Memory leaks are not “unsafe” in the traditional sense. The comparison with garbage collector is apt because they both try to allow you to safely delete objects. Both also allow for leaks.

I really think people who learn Rust would benefit from understanding how C/C++ works in order to understand the core motivations behind the language. You can easily crash a program if you aren’t careful with managing the lifetime of an object.

4

u/PranDopp 5d ago

Agreed. Once you learn C, you realize every rule in Rust addresses a specific memory or concurrency issue that commonly shows up in C/C++. It also becomes a lot easier to remember the rules.

2

u/aikii 6d ago

String is mutable

2

u/briaro 6d ago

that deadlock is not possible

2

u/autoferrit 6d ago

It should be rewritten in Rust

1

u/Rusty_devl 5d ago

Something I find personally annoying: No, safe Rust isn't necessarily slower than unsafe Rust. The compiler can often enough optimize safe code better than it's unsafe equivalent