On Wed, 16 Dec 2009 00:57:59 -0500, Walter Bright <newshou...@digitalmars.com> wrote:

Steven Schveighoffer wrote:
type constructor. it has no meaning as a storage class since it's entirely transient (it only has any meaning inside functions).

I meant does it only apply at the top level, or does it apply down inside types?

I've been giving this some thought. inout is a strange beast, and it has some interesting rules. For example, let's take a struct with an already const member:

struct S
{
   const(char)[] str;
}

Now, we have a function that uses inout on S:

inout(char)[] getStr(inout S s)
{
   return s.str;
}

This should NOT compile, because if you pass in a mutable or immutable S, then the compiler casts the result back to mutable or immutable! So inout is transitive only for mutable members of data types. It's sort of similar to applying const to a struct with an immutable member, the const doesn't apply to the immutable member, only the mutable ones.


BTW, I'm unsure if U[inout(T)] should work.

I just meant it as a compound type. It could as easily be:

     bar!(inout(T)) foo(inout X) { ... }

It might be workable. The only monkey wrench thrown in is that bar can do conditional compilation based on the constancy of T:

template bar(T)
{
  static if(is(T == const))
     alias T[] bar;
  else
     struct bar { T t1, t2; }
}

This is no good, because you don't know how to build bar when your unsure if T is const or not (which is the whole point of inout). If the compiler can determine if bar!(T), bar!(const(T)), bar!(immutable(T)) and bar!(inout(T)) generate identical code (except for the constancy of T), then maybe it can forcibly cast the result once the return happens. This might be the only time where inout can be applied to member variables because it's a temporary situation inside an inout function.

It's a complex situation, one that probably requires a lot of thinking. My recommendation at this time is to only allow bar!(inout(T)) if it is an alias to something that normally would be returnable/passable to an inout function e.g.:

template bar(T)
{
  alias T[] bar;
}

as for AA's, it might be a case where we should allow it, since we know AA's have the same implementation regardless of type info.

-Steve

Reply via email to