I guess it depends on what exactly you mean by "successfully". For example, while C is used for Linux and Linux is quite successful by most measures, that doesn't necessarily meant that there aren't areas where C isn't successful - in this case, a significant reason there's so much interest in Rust is precisely because there has not been success in producing reliably memory-safe code in C.
I think "forcing" might be a bit of a strong word for what's going on as well, but that's neither here nor there.
I feel "just because Rust" leans a bit towards the overly-dismissive side. I'd imagine Linus isn't interested in potentially adding support for Rust "just because Rust" - presumably he thinks there are potential concrete upsides that Rust offers over C that are worth expending time and effort to investigate despite the potential complications from introducing a new language.
> In the long run it will cause fragmentation and increase complexity to such a point that it could destabilize the original project in its entirety.
This sounds scary and all, but I'm admittedly a bit skeptical about this argument. Why would introducing Rust support necessarily lead to the outcome you describe? Are there examples of such an outcome happening to other projects?
Personally I wish libraries would just never remove/change anything from their API, that we'd be able to have some sort of immutable API. Only additions could be made, or you can fork it into another project if you want a different API.
While these ideas are good defaults, unfortunately they lead to unmaintainable, monolithic, insecure code. One needs to make decisions on tradeoffs based on current needs and balance on how to move forward.
Remember how Tor anonymity was broken due to Postal's law? Or how many encryption downgrade attacks have resulted in breaches?
IMHO the better option, but a hard sell, is to focus on externalization and methods like ports and adapters and DDD to help you write interfaces that are more likely to be stable, while still having polices in place to help you move forward when needed.
The chaos report from the 90's and many many more studies since have showed that trying to get software projects perfect from the beginning is impossible.
There are just to many unknowns and trying to plan for them all is impossible.
In some situations like REST it is easier so that breaking changes can be released in a new API version, with a deprecation schedule.
With other things like graphql, ffi etc... it becomes far harder.
If changing the language results in API breakage, you weren't following the inversion principle.
Even with language features, what you call a 'stack' is an abstract data type, not a concrete implementation. While there may be very strong disintegration drivers like performance or language limitations that drive you leaking implementation details or limit your ability to confirm to the ADT while maintaining the other properties you want, that is not specifically the concrete implementation that results in that breaking.
ADT's like lists, stacks, or queues are defined by their semantics from the user's perspective.
Obviously Rust's design decisions may make duplicating the semantics while gaining the advantage of the switch challenging or possibly impossible.
While not really the target audience for either language, I would prefer zig's crashing behavior to hyper using unsafe evaluations of macros as an example.
https://github.com/hyperium/hyper/blob/30f2961e89eb306780d85...
Both are better than c's problems like `x[4]` actually being `*x` though. (IMHO)
The point being is, do target a forever API as a default ideal, but don't stick to that ideal too strongly or it will result in an outcome that is far worse for anything more complicated than say UNIX file operations which are simple enough to do so.
We are in a industry where the 'best' option rarely if ever exists and we almost always have to choose the least worst options.
If some external party can figure out how to refactor without breaking the ADT/API semantics, you shouldn't care except be impressed that they avoided leaking their implementation details to you.
> https://github.com/hyperium/hyper/blob/30f2961e89eb306780d85...
This looks basically like a port of something like Kotlin or C#'s ?. operator - the macro checks whether the pointer is null, returns err if it is, and dereferences the pointer otherwise. The part highlighted in the link looks like it's part of the macro implementation - there don't seem to be any "direct" uses of that particular rule in calling code and it's only invoked via the other rules in that macro definition. I think that should make that bit null-safe at least.
Lifetime safety might be a bit trickier, especially since that bit is part of hyper's C API so idk if there's anything Rust (or Zig, for that matter) could do to ensure the pointer is still valid when dereferenced.
cURL already supports other Rust-written backends as the article pointed out. See https://everything.curl.dev/internals/backends.html.
Any reason why? On paper C doesn't seem to offer any benefit that Rust doesn't, nor Rust any harm that C doesn't.