[Issue 19126] Compiler removes inout on templated parameter and then complains it's not there

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sat Aug 4 11:17:25 UTC 2018


https://issues.dlang.org/show_bug.cgi?id=19126

--- Comment #11 from Steven Schveighoffer <schveiguy at yahoo.com> ---
(In reply to Ali Ak from comment #10)
> Ahhh this inout just hurts my head. So is fixing inout on return a much
> bigger bug than the more simple "don't remove inout from a parameter if the
> return value has inout"?

I'm thinking now that actually, even removing the restriction of saying inout
can't be on the return unless it's on the parameter (i.e. issue 13006) doesn't
fix the code exactly, but it will move the error to where it makes more sense.
In other words, it will error on the line where you try to pass in an
immutable(T) to an inout W!T. Then the error is more obvious.

So you are right, it's not as simple as that. My analysis in comment 2 is not
correct.

> 
> Currently you can do this and then things behave consistently. Fixes this
> problem but does't solve the "allowing inout on return" problem.
> 
> auto wrap0(T)(inout(T) t) {
>     static if (is(T == immutable)) {
>     	return immutable W!T();
>     } else {
>         return inout W!T();
>     }
> }

I'm still finding trouble understanding why you want to specify immutable
explicitly as the T value. Why not just mutable T? Then you don't need that
machinery at all.

> When T is an immutable it seems like the compiler should be doing this by
> itself. If it decides to "replace" inout(immutable) with just immutable,
> then it should replace inout everywhere with immutable. SO why doesn't
> inout(W!(immutable int)) become immutable(T!int)? That would also make this
> error go away right?

But that's not what you specified. inout(SomeTemplate!(immutable(T))) cannot be
replaced in all cases with immmutable(SomeTemplate!T). In this case, it would
be OK, but the compiler would have to do a lot to prove that.

> Maybe the compiler shouldn't be reducing inout in the first place? It is
> supposed to be (IIUC) qualifiers in => qualifiers out right? So why does it
> remove it before the it "lands" somewhere? This makes no sense regardless of
> immutable being the strongest qualifier. The purposes of inout and immutable
> seem orthogonal. It's not a mutability qualifier, it's a "transport of
> mutability information" qualifier right?

Its behavior is the least common denominator of all 3 mutability parameters.
The things you can do with inout are all the things you could do with a
mutable, immutable, or const version, and nothing more.

However, any qualifier that is added on top of immutable is immutable, so the
compiler is stripping away inout to simplify things.

But it can only do this on types that are fully immutable. In the case of the
struct, only the member is immutable, it's not immutable on the whole struct.

Again, the best fix for this is simply not to instantiate with immutable(T).
You can achieve everything without it.

--


More information about the Digitalmars-d-bugs mailing list