[Issue 7355] inout incorrectly resolved if the same type has both mutable and immutable parts

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Feb 3 16:26:33 PST 2012


http://d.puremagic.com/issues/show_bug.cgi?id=7355



--- Comment #16 from timon.gehr at gmx.ch 2012-02-03 16:26:32 PST ---
(In reply to comment #13)
> Once again you are right Timon!
> 
> I was neglecting to see in the original example that the call was id(foo(y))
> instead of just id(y)!  I sometimes cannot penetrate your inadvertent
> obfuscation :)  Your original example was (should have been) sufficient.
> 

OK. What measures can I take to less obfuscate my code? =)

> I see now that inout(const) must be a consideration for substituting inout.
> 
> Now, regarding overload resolution as it pertains to resolving what inout
> means, I still think a simple algorithm as I previously stated should work.  We
> just need to add inout(const) as a possible substitute.  I think the ordering
> should be something like:
> 
> mutable, immutable, inout, inout(const), const
> 
> Note that inout and inout(const) are the local version (not the wildcard
> version).  Also note that mutable, immutable, and inout could be in any order.
> 
> The algorithm I stated earlier needs to be modified.  The easiest way to state
> it is, try each of the above substitutes for inout in order, and the first one
> that type-checks, wins.  I think it works because there are no cycles in the
> implicit conversion graph:
> 
> mutable -----------------------+
>                                |
> immutable --+--> inout(const) -+-> const 
>             |                  |
> inout ------+------------------+
> 
> But I don't see why we need complex overload rules as you stated.  Can you show a counter-example to my simple design? 

I think what you propose would work.

But the overload rule I want to add (see issue 7431) is actually quite
intuitive and I think it is a good move to make the overload rules consistent
enough so that we could re-use them for inout matching. It benefits code that
does not use inout too.

Not fixing the overload rules would result in inout being _more_ powerful than
three overloads => inout could not be replaced by three overloads
transparently, if it was later determined that the different const versions
need different function bodies.

immutable(int)[] foo(immutable(int)[] x,float){return x;}
const(int)[] foo(const(int)[] x, float){return x;}
int[] foo(int[] x,float){return x;}

inout(int)[] bar(inout(int)[] x,float){return x;}

void main(){
    foo([1,2,3],4); // would not work
    bar([1,2,3],4); // would work!
}


> I'd like to keep things simple, because
> inout is already difficult to understand and making it simple to explain is a
> huge benefit.

I think 'create pseudo-overloads and use the rules for overloading' is simplest
(with the additional overloading rule, so that it works), but what you propose
should work too. The only difference between using the repaired overload
resolution and your proposal I can see is that yours introduces possible
disambiguation in the case of multiple alias this. I don't know if this is good
or bad (my initial proposal had the same characteristic).

inout(int)[] foo(inout(int)[] x){return x;}

class C{
    int[] x(){writeln("x!");return new int[10];}
    immutable int[] y(){writeln("y!");return new immutable(int)[10];}
    alias x this;
    alias y this;
}

void main(){
    C c = new C;
    foo(c); // should this work or fail?
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list