> It's possible for a Rust program to be technically compilable but still semantically wrong.
This was my biggest problem when I used to write Rust. The article has a small example but when you start working on large codebases these problems pop up more frequently.
Everyone says the Rust compiler will save you from bugs like this but as the article shows you can compile bugs into your codebase and when you finally get an unrelated error you have to debug all the bugs in your code. Even the ones that were working previously.
> Rust does not know more about the semantics of your program than you do
Also this. Some people absolutely refuse to believe it though.
Yes, that's a very common misconception.
Of course, if your program compiles, that doesn't mean the logic is correct. However, if your program compiles _and_ the logic is correct, there's a high likelihood that your program won't crash (provided you handle errors and such, you cannot trust data coming from outside, allocations to always work, etc). In Rust's case, this means that the compiler is much more restrictive, exhaustive and pedantic than others like C's and C++'s.
In those languages, correct logic and getting the program to compile doesn't guarantee you are free from data races or segmentation faults.
Also, Rust's type system being so strong, it allows you to encode so many invariants that it makes implementing the correct logic easier (although not simpler).
> Some people absolutely refuse to believe it though.
Who says this? I've never seen someone argue it makes it impossible to write incorrect code. If that were the case then there's no reason for it to have an integrated unit testing system. That would be an absurd statement to make, even if you can encode the entire program spec into the type system, there's always the possibly the description of a solution is not aligned with the problem being solved.
"If it compiles it works" isn't true. But "If it compiles it won't eat your homework" sort of is.
I don't think anyone believes the “if it compile it works” phrase literally.
It's just that once it compiles Rust code will work more often than most languages, but that doesn't mean Rust code will automatically be bug free and I don't think anyone believes that.
I think the key idea is that Rust gives you a lot of tools to encode semantics into your program. So you've got a much greater ability for the compiler to understand your semantics than in a language like JavaScript (say) where the compiler has very little way of knowing any information about lifetimes.
However, you've still got to do that job of encoding the semantics. Moreover, the default semantics may not necessarily be the semantics you are interested in. So you need to understand the default semantics enough to know when you need something different. This is the big disadvantage of lifetime elision: in most cases it works well, but it creates defaults that may not be what you're after.
The other side is that sometimes the semantics you want to encode can't be expressed in the type system, either because the type system explicitly disallows them, or because it doesn't comprehend them. At this point you start running into issues like disjoint borrows, where you know two attributes in a struct can be borrowed independently, but it's very difficult to express this to the compiler.
That said, I think Rust gives you more power to express semantics in the type system than a lot of other languages (particularly a lot of more mainstream languages) which I think is what gives rise to this idea that "if it compiles, it works". The more you express, the more likely that statement is to be true, although the more you need to check that what you've expressed does match the semantics you're aiming for.