That seems to me like it stems from an orthogonal issue. Let me elaborate:
Danger is inherent to unsafe code. (Well, that statement is a bit redundant, isn’t it.) However you twist the syntax and/or the semantics of the language, writing unsafe code (viewed either from the “consumer of unsafe abstractions” or “author of unsafe abstractions” side) is always going to require more thinking and vigilance than usual. Yes, this can be true even for very basic concepts and operations. But I’m sure that is not a unique feature of programming in Rust. If you have studied some sort of scientific discipline at a (say) intermediate level, you probably very well know the feeling of sitting on a 1-line maths of physics problem for a couple of hours or days before being able to grasp an otherwise basic idea.
I don’t want to get too philosophical or generally off-topic here, but the problem is that our monkey brains are just not designed to do what we are doing with them.
So at the end of the day, implying that intrinsically hard problems are only hard because we are not approaching them ergonomically enough and not because they are hard looks like a fallacy to me.
the amount of people who are constantly confused about what is perhaps the most dangerous feature of the Rust language worries me.
I understand and agree with that; what I am saying is that this is an inherent issue, and not something that can be mitigated completely or nearly completely by improved language design. Either interpretation of unsafe means “give up some safety guarantees”. That’s not going to be pretty either way for the reasons described above, and at the same time, the complexity introduced by the language changes laid out in this pre-RFC is, in my opinion, does not have a good enough investment-return rate. I’m not saying that ergonomic improvements to unsafe would be completely useless – I’m just trying to argue that the advantages they would bring to the table wouldn’t be worth the increased complexity.
In the world of life-threatening systems, the more dangerous a tool is, the harder you make it to use it incorrectly. Knives have a handle shaped in such a way that it is pretty clear how you are supposed to pick them up.
I absolutely agree with all of this too; in fact I’m generally the biggest fan of designing systems so that they have the least chance to be used incorrectly. However, and I don’t want to repeat myself over and over again, but the very purpose and nature of unsafe code renders attempts at making it safer very hard to achieve (I would even say contradictory).
Basically, what @gbutler wrote:
You made three other very good points:
Unsafe Rust should never trust Safe Rust’s abstractions, yet there is no safeguard in place to lint against reaching for these.
I’m always in for more compiler warnings and lints! This, I think, is probably the easiest issue to address. Adding more rules/patterns to be recognized by the compiler or e.g. Clippy is an easy and in my opinion uncontroversial action, and we should go for it. If it’s likely wrong – warn about it!
As you can see, I’m in favor of these sorts of improvements as long as they don’t offset the balance towards just adding more stuff to the language in an unhealthy manner. A core language addition is a scene which always requires extremely careful consideration, and in 99.9% of the cases, the right thing to do with a new feature is to omit it. Compiler warnings and linter rules are nothing like it, they are basically free and completely safe (“safe” here meaning “does not break earlier code/concepts/assumptions or introduces bugs”).
Yet the method’s entire implementation is automatically turned into an unsafe block, silently enabling all kind of unsafe operations without any compiler warning/lint.
It’s not exactly silent, because it has a big honkin’ unsafe at the beginning. Still, I understand your concerns, I do think they are valid, and indeed, it would absolutely make sense to be able to mark a function unsafe without turning the entire body into an unsafe block. This is yet another change that likely wouldn’t need any sort of core language addition. It’s merely that the compiler should consider the body block safe rather than unsafe. If I recall correctly, that literally means flipping a one-bit flag in the compiler. (Maybe in several places, but you get the idea.)
TrustedLen is another example of unsafe abstraction design gone wrong. […]
That’s right too! I’m in favor of replacing TrustedLen with something more explicit and harder-to-forget/abuse. I still strongly doubt that this can only be done using, or that it is best achieved by, additions to the core language.
Finally:
People who, in addition, try to build unsafe abstractions which other developers (including future maintainers of the same crate) can rely upon.
Indeed, that puts the issue in a somewhat different perspective, although my comments about how more syntax wouldn’t help much still apply.