467 karma · joined July 16, 2018
As in the sibling comment, "scope" could be used, but indeed maybe we should have just called lifetimes "scopes" or something (though they are not lexical, whereas scopes are usually thought of as lexical pyramids).
I probably would just say lifetime usually, but I would be being imprecise and potentially unclear!
Variables don't have a "lifetime," references do. When we talk about lifetimes we talk about the lifetime of references to variables, during which time the variable cannot be moved, dropped, etc. The "lifetime of the variable must be greater than the lifetime of the reference" is a common mental model but this lifetime of the variable doesn't really come into play in reality.
Your 1) and 2) always coincide in the abstract model, though the compiler may optimize out memcpys that have no impact. When you move a pointer around, you don't move the object it points to.
The guarantees of Pin are now even being used beyond self-referential types but also for intrusive data structures in tokio's concurrency primitives. Pin is not for everyday users, but it is one of the greatest success stories of Rust's unsafe system. That you would call it a mess to a forum of non-users is quite disspiriting.
The first is that the Rust community on Reddit is in a feedback loop of groupthink and outrage, making it into a powerful vector for harassment. The maintainer of the actix project had a particularly terrible experience of escalating harassment from the users of this subreddit, and its extremely sad. This has caused a lot of grief for the maintainer of actix and prevented real (but far overblown) code issues from being fixed in a productive way.
But I think Steve undersells the absurdity of the unsafe anxiety. Some Rust commmunity members are conflating two wildly different scenarios together. The first is a library exposing an API which, if used in an unlikely and contrived way, could result in a program using that library containing undefined behavior. Then, since that program has undefined behavior, it could contain a memory bug. If that were the case, someone could potentially exploit that bug to attack a user of that program. You'll notice this is a series of conditional statements - its a funnel of decreasing probability.
So yes, library APIs which can allow UB in safe code - even unlikely and contrived safe code - must be fixed. The goal of Rust is that safe APIs can never cause UB. But people should have a proportionate understanding of the risk profile of these bugs (again: a programmer using this API in an unlikely way could create a program with a bug that could potentially be exploitable). This is a miniscule increase in the risk of another heartbleed, it is not the same thing as heartbleed.
The spark that lit the kindling of the toxic Reddit community was a blog post by Shnatsel, a member of the RustSec team. This blog post didn't get attention here, but I want to take a moment to look at how ridiculously it frames things by examining its analysis of a different project: reqwest (sort of the most standard HTTP client library in Rust).
Here's the link: https://medium.com/@shnatsel/smoke-testing-rust-http-clients...
The fuzz test, which is what the library is about, found no security issues. It found some hangs in 6% of cases and Shnatsel traces them to a known deadlock issue. This is a great result.
But Shnatsel spends most of this talking about a custom hashmap implemented in the http library, which the RustSec group did a security audit of just a few months ago. That security audit found only two issues, both UB that would result from a contrived use of a minor library API (they are linked in the blog post, but not explained). These two issues were fixed, and the fix released, by the maintainers of the http crate in 10 days.
This is an incredible success! The security audit of a foundational library found two minor issues which were promptly fixed, and the fuzz confirms that the entire stack on top of it seems to contain no memory issues. Wonderful result, but how does Shnatsel frame this?
> First things first: it didn’t segfault! I am actually impressed because I had really low expectations going into this.
Come on! The blog post is full of these kinds of snide zingers which are totally unfounded in the face of the actual evidence presented. When you have someone writing in this disingenuous, meanspirited way about open source maintainers and then putting this in front of a groupthinking rage machine community like Reddit, of course you're going to get harassment. This behavior is totally unacceptable, and it's very sad to see it promoted in the Rust community.
The idea that someone could think an issue is theoretical and then discover it is practically significant is obvious and no insight at all - it reduces to "people are sometimes wrong." I am declaring based on my significant relevant expertise that this issue is not practically important. Your comment contributes nothing but baseless contradiction.
Since (to a first approximation) every individual who has the expertise and contextual knowledge to really evaluate this issue is a poster on internals.rust-lang.org, its pretty surprising to find this thread on the front page of Hacker News. I imagine some Hacker News users who upvoted this link did so out of technical interest, but I suspect a large portion of the attention comes from some combination of these misconceptions:
- The misconception that this could have a practical impact on users (the code being discussed on the thread is all obviously pathological & contrived).
- The misconception that Rust's type system and standard library never contain soundness issues and that this is an exceptional event (in fact we have a number of longstanding soundness issues).
We have a policy of fixing all soundness issues, so this issue will be fixed. In the meantime, while we decide the best solution, it will have no practical impact on Rust users. And none of the solutions we are considering would involve significant breakage to users, or invalidate any real code.
At a high level: the soundness issue occurs because the Pin API was designed based on certain reasoning about the behavior of pointers. This reasoning would be sound but for the fact that we have allowed certain exceptions in relationship to pointers to what are called the "orphan rules" (which usually enable local reasoning like this). These exceptions allow users to introduce code which, while contrived, allows them to violate the guarantees of the Pin API. Such is life.
My suspicion is that people object to calling this persons' claims essentially a lie, which is just the truth. It is dishonest to use the performance numbers of an incomplete project while listing the features of the complete project, which will certainly decrease performance. The website is replete with obviously absurd claims, like a completely baseless claim about throughput that assumes compile time is linear in code size.
But what's actually pathetic in this affair is the anguish and upset of a bunch of internet nerds over a project that has received, in its 3 months of existence, less than $2500 USD. This is peanuts, but everyone is outraged over a "scam" because the real scam is open source getting a bunch of people to work for free, hoping at a chance of getting peanuts like this.
EDIT: No idea why this was flagged, I don't understand the norms of this strange website.
The problems I refer to are, as I stated in the post, UX problems, and they arise ultimately from Rust's guarantees generics will be monomorphized, that allocations will be explicit, that arguments are passed by value, and so on. None of this applies to Haskell. We don't need to "improve on" Haskell (though I think our coherence and instance resolution rules are superior), we have different design constrants resulting in different problems.
These two blog posts have really nothing to do with one another, are describing unrelated problems with unrelated things, sharing only the fact that they both have to do with the Rust language and both describe something as difficult (but meaning pretty different things by the word) and you draw a conclusion that "Rust is not a language to 'get things done.'"
I don't know how to prove that Rust is "a language to 'get things done'" - this seems like an almost meaningless qualifier - but many people (including me) are getting things done using Rust every day.
However, in many cases, a well designed generic API will be able take a trait object in the place of `T`. That way, at the application layer, you can decide to pass trait objects around, reducing code size and - maybe more importantly to you - compile times. cargo does this for example in some places where the performance regression is insignificant but it saves noticeable compile time.
Sometimes libraries accidentally don't set things up so that you can pass either a concrete `T` or a dynamically dispatched trait object to their APIs; we're hoping to find a way of making it less likely for this to go wrong in the future.
This is separate from effect systems, which I never said was not possible. rpjohnst's parallel response sums up the key differences between monads and an effect system.
Higher kinded polymorphism results in trivially undecidable type inferences without something like currying; the restrictions needed to support it would be arbitrary and weird given that Rust does not have currying (essentially some rules to reconstruct the restrictions of currying in type operator context).
Instances of both Future and Iterator do not implement the Monad type class as defined in Haskell, because the "fmap" operator does not return the "self" type parameterized by a new type, it returns it own new type. This is because the state machine they represent is leaked through their function signature.
Do notation doesn't work with the imperative control flow that Rust has, which other people have already discussed.
Sticking to the first part: an effect system is not what the user I was responded to was talking about. They were talking about building do notation on top of type classes with higher kinded polymorphism, which cannot effectively abstract over the monadic operations in Rust.