[1] https://stackoverflow.com/questions/4239121/code-compatibili...
[2] https://stackoverflow.com/questions/179492/f-changes-to-ocam...
Besides, all of this is necessary for soundness. Turning off the borrow checker won't magically get you a compiler that is less permissive, it will get you a compiler that will very likely produce nonsense if your program would have failed the borrow checker had it been present.
If you give an invalid program to the regular compiler it will be rejected, but if you give the same program to this compiler it might produce nonsense. So the developer of a program would feed it to the regular compiler for checking, but others could take the finished release of the program, assume that it's valid and feed it to this compiler instead, as I understand it.
Assuming the input is sound, mrustc will do the right thing. Ignoring the borrow checker will not make things magically work.
Do you really want that?
My point is that the borrow checker is explicitly meant to protect against data races and such. There are situations where I write code I can prove does not violate any hazards but Rust's "validation" is overly-zealous.
The few times I do have an issue I'm usually writing FFI code to interact with C, and I try to minimise that code as much as possible.
It's often a good exercise to craft your program to the language you're targetting, to take advantage of it's strengths or embrace it's traditions.
-------------------
Jokes, aside, if you aren't there for Rust borrow-checker, then I wonder, do you really need Rust at all?
Which is more appropriate for this scene I think.
LOL
When one doesn't have a pervasive GC to dynamically clean things up, things still need to be freed but have to be freed in static locations (either explicit free calls in C or end of scopes in Rust and C++). Making this safe means defending against pointers becoming dangling which Rust does by restricting mutation. This restriction translates into some things that can't be copied, such as mutable references (that can lead to iterator invalidation and use after free, among every other undefined behaviour).
In other words, explicit/scope-based freeing being unsafe means the only way to safely manage memory is a garbage collector (tracing or reference counting), which limits how many programs can be written that are verified-safe by a computer. I believe Ada takes the approach you suggest, but this limits it to be most useful for programs that don't allocate (or only do O(1) allocation during startup).
Affineness also allows modeling things like session types better, letting programmers construct their own APIs that defend against mistakes.
You could, and people have, argue that some types could be "autoclone", as in, have `clone` calls automatically inserted where necessary, but when it is raised, a lot of people express dislike because they feel it will encourage slow code and mean people aren't guided towards the (usually) better solution of using references.
For the second one, consider Box<T> vs uniq_ptr<T>; Rust can statically prevent use after-move, C++ cannot, and you'll get a NPE. That is, you can totally get rid of a GC through only RAII, but you can't guarantee memory safety (as far as we know!) without affine/linear types.
Affine typing (plus the rest of Rust's system) on top of scoped memory management is needed to avoid problems like returning a pointers into something that is deallocated at the end of a function:
int &foo() {
std::vector<int> v = ...;
return v[0];
} // return value is dangling
And similarly, avoiding having pointers into things that are destroyed when their parent is modified: std::vector<std::unique_ptr<int>> v = ...;
int &ref = *v[0];
v.clear();
// ref is dangling