TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Some mistakes Rust doesn't catch

337 pointsby jacobwgover 3 years ago

14 comments

JoshTriplettover 3 years ago
While Rust won&#x27;t catch the use of subtraction in an arbitrary function named &quot;add&quot;, it&#x27;ll catch (in clippy) the use of subtraction in an implementation of the Add or AddAssign traits: <a href="https:&#x2F;&#x2F;rust-lang.github.io&#x2F;rust-clippy&#x2F;master&#x2F;#suspicious_arithmetic_impl" rel="nofollow">https:&#x2F;&#x2F;rust-lang.github.io&#x2F;rust-clippy&#x2F;master&#x2F;#suspicious_a...</a>
评论 #30256675 未加载
评论 #30257245 未加载
dhosekover 3 years ago
I think the rust making you aware of what you need to do is a good thing. I have a vague memory of writing C code when I was a teenager where I directly manipulated a string from argv[] doing some concatenation or other and it worked fine until it didn&#x27;t because I was merrily stomping on memory I didn&#x27;t own (I was thinking in Pascal terms while writing C code). The whole String vs &amp;str thing in Rust can feel a bit fiddly at times, but it does make you aware of what&#x27;s happening (and I&#x27;ve found that it has improved my JVM coding as well although I do have to occasionally remind myself that I don&#x27;t need to worry about borrows and lifetimes).
评论 #30265337 未加载
评论 #30256100 未加载
Animatsover 3 years ago
Deadlock detection is an interesting problem. As the author points out, Rust will not detect this at compile time, but there are run time analyzers.<p>It&#x27;s worth looking at deadlock detection at compile time today. Not just to prevent bugs. Sometimes, on some CPUs, the compiler could potentially turn some mutexes into fence operations and become &quot;lock free&quot;.<p>In Rust, code tends to do a lot of scope-based locking. There&#x27;s a lot of<p><pre><code> item.lock().unwrap().dosomething() </code></pre> Now, if the compiler detects that 1) every lock on <i>item</i> is scoped, and 2) everything done inside the lock is short and non-blocking, then that lock could potentially be optimized into fence instructions. Worth thinking about.<p>There&#x27;s an analogous case for RefCell items. RefCell is a lot like Mutex, except that you call &quot;borrow&quot; instead of &quot;lock&quot;, and if the item is ever &quot;busy&quot;, waiting won&#x27;t help, because your own thread made it busy. If every use is a scoped borrow and there are no inner borrows of the same object within the scope of the outer borrow, that&#x27;s the good case. Reference counts aren&#x27;t needed at all.<p>I think that somewhere in this space lies the solution to the back-reference problem, but I haven&#x27;t gotten there yet.
评论 #30256362 未加载
评论 #30255833 未加载
评论 #30255888 未加载
评论 #30258442 未加载
codefloover 3 years ago
Near the end, the blog posts mentions patterns to avoid accidental deadlocks in structs that wrap a Mutex. Here&#x27;s another one that I like use:<p><pre><code> struct FooInter { actual_data: HashMap&lt;...&gt;, } impl FooInner { fn do_something(&amp;mut self) { ... } } pub struct Foo(RwLock&lt;FooInner&gt;); impl Foo { pub fn do_something(&amp;self) { self.0.write().do_something(); } } </code></pre> The rule is that FooInner doesn&#x27;t know about the lock (so calling other methods is safe), while Foo methods can&#x27;t call other Foo methods (so you can&#x27;t lock anything twice). You can even move Foo and FooInner to different modules to hide FooInner&#x27;s contents from Foo, though I rarely find that necessary.<p>I know this is subjective, but for me, this works better than what the blog post suggests -- at least, I haven&#x27;t gotten it wrong by accident yet.
评论 #30258990 未加载
jerfover 3 years ago
&quot;I guess that&#x27;s why the Go compiler is so fast - it barely checks for anything!&quot;<p>Any serious Go programmer ought to have golangci-lint or equivalent running somewhere. I prefer pre-commit, but CI&#x2F;CD will do too.<p>An advantage of golangci-lint is that is not in the core compiler, so you can get some <i>really</i> opinionated linters from the community, some of which you&#x27;re going to love and some of which you&#x27;re going to hate, or linters written really quickly and hammered out in the real world rather than waiting for the full release cycle.<p>A disadvantage of golangci-lint is that it&#x27;s not in the core compiler, so you have to actually fetch it yourself, maintain it (configure it), etc.<p>With golangci-lint, Go is still not Rust, of course, but it gets it a pretty decent way towards being a serious, quality language. Most languages need some augmenting to be serious, quality languages, because it isn&#x27;t generally appropriate to put <i>all</i> the requirements for code into the compiler, for many reasons. Rust is somewhat exceptional in how much they&#x27;ve put in their compiler. Things like C and C++ need immense, high-quality support from static analyzers to be even remotely safe to use on a network. (So, yes, I don&#x27;t consider C or C++ &quot;serious, quality&quot; languages in the absence of that static support. I don&#x27;t even consider it close, honestly. I don&#x27;t consider very many languages to be serious, quality languages out of the box.)
评论 #30259236 未加载
评论 #30259250 未加载
评论 #30259354 未加载
emptyseaover 3 years ago
Something to note about the JS examples, if you throw them into TypeScript you&#x27;ll get similar error messages to go vet and rustc.<p>The first example: <a href="https:&#x2F;&#x2F;www.typescriptlang.org&#x2F;play?#code&#x2F;GYVwdgxgLglg9mABMOcAUMCUiDeBYAKEUQgQGc4AbAUwDpK4BzNAIhThYBpEsBuQgL6FCoSLASIARgEMATmmz4iJclToNmLGbICELTPwJCCI8NHhIAttJhgFuQsRSzEGRAF5EABl49EAHkQAZl8YAGowxUdiZFQMA2jjYllqKBBZMENibQVDY0JrW1ygA" rel="nofollow">https:&#x2F;&#x2F;www.typescriptlang.org&#x2F;play?#code&#x2F;GYVwdgxgLglg9mABMO...</a><p><pre><code> Unreachable code detected </code></pre> Along with some typos since `i` isn&#x27;t declared.
评论 #30259105 未加载
评论 #30255431 未加载
athoraxover 3 years ago
This is unbelievably awesome. Learning by breaking things is one of my favorite things and the level of detail here is astounding!
评论 #30255360 未加载
wokwokwokover 3 years ago
I wonder if there&#x27;s a future where you have a language model that actually inspects the name of your functions, does an automatic code-gen of them from the context and then compares your implementation and gives you lint errors like:<p><pre><code> fn add() { ... }: mispleading name or incorrect implementation `a - b` </code></pre> You know, once upon a time I would have thought that was categorically impossible, but now, you know, it actually seems like something that might not be that far off.<p>&gt; It&#x27;s just not something Rust is designed to protect against - at least, not today.<p>...maybe, one day. :)
评论 #30255413 未加载
评论 #30256374 未加载
评论 #30256416 未加载
评论 #30256720 未加载
评论 #30255007 未加载
评论 #30255227 未加载
评论 #30255025 未加载
demindiroover 3 years ago
Seeing the RwLock deadlock surprised me. I tried making the standard library&#x27;s implementation deadlock instead and I&#x27;m unable to reproduce it (even with 1 million iterations). The parking_lot implementation does seem to deadlock however.<p>I suppose the parking_lot implementation elides some checks for the sake of performance.<p>EDIT: It seems it can happen with the standard library&#x27;s RwLock too[1]. Perhaps it&#x27;s a Linux peculiarity?<p>[1]: <a href="https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;sync&#x2F;struct.RwLock.html" rel="nofollow">https:&#x2F;&#x2F;doc.rust-lang.org&#x2F;std&#x2F;sync&#x2F;struct.RwLock.html</a>
评论 #30257671 未加载
评论 #30255894 未加载
dotekaover 3 years ago
I’d just like to take a moment to compliment the author on repeatedly producing content that is deeply technical yet very entertaining. As someone who has used both Rust and Go in anger, I enjoyed this one and it’s predecessors a lot. A big step up from a lot of the typical blogspam.
Dylan16807over 3 years ago
&gt; add(&quot;foo&quot;.to_string(), &quot;bar&quot;)<p>&gt; It&#x27;s a pretty radical design choice, to force you to be aware that, yeah, since you&#x27;re creating a new value (out of the two parameters), you will have to allocate. And so it forces you to allocate outside of the Add operation itself.<p>Forcing you to think about allocation is good for many situations.<p>Making you do an <i>extra</i> allocation is a bad way to do that. And the only way I can think of to avoid that would give up having the function be generic.
评论 #30255300 未加载
bjarnehover 3 years ago
Wow, what a horrid and cool way to create a function that accepts generic types in Go :-)<p><pre><code> func add(a interface{}, b interface{}) interface{} { if a, ok := a.(int); ok { if b, ok := b.(int); ok { return a + b } } if a, ok := a.(string); ok { if b, ok := b.(string); ok { return a + b } } panic(&quot;incompatible types&quot;) }</code></pre>
评论 #30256955 未加载
评论 #30258006 未加载
评论 #30257017 未加载
phibzover 3 years ago
Isn&#x27;t subtraction just addition in the negative direction? :-)
评论 #30257261 未加载
评论 #30256361 未加载
iainmerrickover 3 years ago
This is a very long post! The bit that actually addresses the title, after all the &quot;here&#x27;s a thing I tried, here&#x27;s the weird error message, here&#x27;s the mistake I made&quot; business, starts way down towards the bottom, with this text:<p><i>Before we move on, I&#x27;d like to congratulate you on reading this far. Believe it or not, you&#x27;re in the minority!</i><p>The title is very misleading when the content is a very, very general discussion of compile-time versus runtime errors, mostly focusing on problems that Go doesn&#x27;t catch at compile time.<p>TL;DR: the mistake Rust doesn&#x27;t catch is recursive mutex locks.<p>It does seem like it would be good to catch that one, and that the borrow checker in some form ought to be able to do it -- it should be able to track the static scope of a mutex lock, and block further attempts to lock it inside that scope.
评论 #30259179 未加载
评论 #30259012 未加载