It’s surely interesting though that people continuously complain about them and then praise a language whose equivalent feature is much more restrictive!
Surely the compiler could delay optimizations until the entire project is built, no? Then it knows what implementations exist, and the developer could then decide how to deal with that
It’s not really about optimizations but rather:
when checking some impls for overlap, the compiler assumes that impls that the orphan rules block will never exist. You thus need to either disallow them (which would make the compiler more restrictive for non-application crates!) or a way to track them (which is easier said than done since coherence and trait checking is very complex)
when generating code where specialization and/or vtables are involved. This could be delayed until the last crate is compiled, but at the expense of longer compile times and worse incremental compilation performance.
Sure, and ideally those cases would be accounted for,
AFAIK there’s nothing yet that can account for them without allocating everything on the heap.
or at the very least the dev could annotate each use to turn the borrow checker off for each instance, and that could print something at build time and a linter could flag over it. Unsafe blocks aren’t feasible for everything here.
You want some annotations to break out of the safe subset of the language but aren’t unsafe blocks basically that? Or perhaps you want something more ergonomic, at the expense of safety?
Yes, that’s what I’m suggesting. Injecting some kind of metadata that gets stripped at code gen time would probably work.
worse incremental compilation performance
Would it really be that significant?
without allocating everything on the heap
I’m talking about compile time.
Start with all of the known safe cases (basic types should be fine), then move on to more dubious options (anything that supports iteration). Then allow iterable types but don’t allow iterating over a mutable reference. And so on. If it’s a priority to loosen up the rules without sacrificing safety, surely some solutions could be found to improve ergonomics.
Or perhaps there could be some annotations to make a reference as “unsafe” or similar instead of just a block. If something is safe in practice but not verifiably safe, there should be a way to communicate that.
You want some annotations to break out of the safe subset of the language
The annotations would indicate that something unsafe is going on, so it’s like an unsafe block, but on a reference. That way it’s clear that it’s not being checked by the borrow checker, but the rest of the application can be checked.
I really liked the idea of an optional, built-in GC w/ pre-1.0 Rust where specific references could be GC’d. If that were a thing in modern Rust (and the GC would only be enabled if there’s a GC’d reference included), we could get a lot more ergonomics around things like linked lists.
It’s surely interesting though that people continuously complain about them and then praise a language whose equivalent feature is much more restrictive!
It’s not really about optimizations but rather:
when checking some impls for overlap, the compiler assumes that impls that the orphan rules block will never exist. You thus need to either disallow them (which would make the compiler more restrictive for non-application crates!) or a way to track them (which is easier said than done since coherence and trait checking is very complex)
when generating code where specialization and/or vtables are involved. This could be delayed until the last crate is compiled, but at the expense of longer compile times and worse incremental compilation performance.
AFAIK there’s nothing yet that can account for them without allocating everything on the heap.
You want some annotations to break out of the safe subset of the language but aren’t
unsafe
blocks basically that? Or perhaps you want something more ergonomic, at the expense of safety?Yes, that’s what I’m suggesting. Injecting some kind of metadata that gets stripped at code gen time would probably work.
Would it really be that significant?
I’m talking about compile time.
Start with all of the known safe cases (basic types should be fine), then move on to more dubious options (anything that supports iteration). Then allow iterable types but don’t allow iterating over a mutable reference. And so on. If it’s a priority to loosen up the rules without sacrificing safety, surely some solutions could be found to improve ergonomics.
Or perhaps there could be some annotations to make a reference as “unsafe” or similar instead of just a block. If something is safe in practice but not verifiably safe, there should be a way to communicate that.
The annotations would indicate that something unsafe is going on, so it’s like an unsafe block, but on a reference. That way it’s clear that it’s not being checked by the borrow checker, but the rest of the application can be checked.
I really liked the idea of an optional, built-in GC w/ pre-1.0 Rust where specific references could be GC’d. If that were a thing in modern Rust (and the GC would only be enabled if there’s a GC’d reference included), we could get a lot more ergonomics around things like linked lists.