On Tuesday, 21 July 2015 at 12:53:37 UTC, Steven Schveighoffer
wrote:
Again, it has nothing to do with code generation, it has to do
with type conversion. The compiler doesn't know how to convert
Rebindable!(inout(T)) to something that can be returned from an
inout function. We haven't figured out how to tell it what to
do there, so it has to give up.
So the way that I see it is that "inout" is preserved until code
generation. For example, Rebindable can keep inout(T) in the
internals. Then "inout" should be replaced by compiler with 3
versions of type (const, mutable, immutable) for a check. Then
the code will be generated one time. One of the problems here is
that, for example, Rebindable!(const(T)) can be specialized and
have different behavior, unlike Rebindable(inout(T)) for the case
inout(T) = const(T).
It has to not only successfully generate code, the code itself
has to be exactly the same for all 3 versions (and actually, if
you have multiple inout parameters, it potentially has to run
3^parameter tests). It could potentially do this, but inout
works just as effectively with the current rules. It still does
not provide a way to convert a struct with an inout member to a
struct without one.
Yes, the code itself will be the same, I meant just checks.
3^n possible checks -- that is an excellent point, can be a
problem (as well as several other possible problems that I didn't
take into account).
Finally, I'm sure that there are a lot of reasons to make inout
in the present way and I can accept it (regardless of the fact
that inout doesn't fit now for cases more complex than trivial
ones). Of course, it would be great if D type system is perfect
some day :)