In this use case, my instinct tells me that trait specialization is the wrong tool for the job. The author is trying to dispatch different functions based on a flag set in the caller. I can think of two more elegant ways to do this:
* Make the file system itself a trait, with implementations for read-only and read/write. Pass the concrete implementation as a parameter to the function using it.
* Store the capabilities as a variable in the file system object and query it at runtime. This can be done with an if.
Sometimes the simpler approach is better.
> Make the file system itself a trait, with implementations for read-only and read/write
Those are separate concrete implementations between read-only and read-write; a write operation can be implemented on the read-write implementation only.
But from their description it sounded like exactly two concrete implementations, one read-only, one read-write. If you want to share code or implementations, there's lots of ways still. For example, if the read-write filesystem implementation is a superset of the read-only, put a read-only struct inside the read-write.
On the surface, this addition doesn't seem significant. However, it opens up a world of possibilities for enabling powerful design patterns that are based on trait implementations that are named, generic, and overlappable. One of the greatest strengths of CGP is to enable safe, zero-cost, compile-time dispatching through the trait system to accomplish the things that in OOP would typically require dynamic dispatch with runtime errors.
Just a FYI from their main page:
As of 2025, CGP remains in its early stages of development. While promising, it still has several rough edges, particularly in areas such as documentation, tooling, debugging techniques, community support, and ecosystem maturity.
...
At this stage, CGP is best suited for early adopters and potential contributors who are willing to experiment and help shape its future.
Look: patterns like this might unblock people locally but they point to a gap between what people want to say and what the base language allows them to express. In the long term, it's better to expand the language than devise increasingly heroic workarounds for syntactic sclerosis.
The issue is really that `specialization` *has* to deal with lifetimes, even when there is apparently none. The example core with `Read` and `Read + Seek` also suffers from lifetime issues: some type could implement `Seek` depending on some lifetime and this would make your specialization unsound. For this reason `min_specialization` does not accept your specialization.
You can have default implementation for some methods and implementors of the trait can specialise.
Specifically, you can have couple functions that takes a type that implements some stuff (different based on the wanted specialisation) and gives you a trait object.
This should be simpler and should have better compile time than doing macros or adding more generics
Of course you‘re right if you can‘t alloc, you can‘t use Box or similar stuff.
Also you can avoid a lot of performance hits if you just implement most stuff on the dyn Trait directly!
.. yep, I’ll try everything before introducing virtual functions just out of warm fuzzies rather than anything measurable
isn't the problem that rw is still r, so passes checks for both?
can't you make one rw and the other r(-w)?