Jump to page: 1 2
Thread overview
[Issue 19126] Compiler removes inout on templated parameter and then complains it's not there
Aug 01, 2018
anonymous4
Aug 01, 2018
anonymous4
Aug 02, 2018
anonymous4
Aug 02, 2018
anonymous4
Aug 03, 2018
Ali Ak
Aug 03, 2018
anonymous4
Aug 03, 2018
Ali Ak
Aug 05, 2018
Ali Ak
Jul 18, 2019
Ali Ak
Dec 17, 2022
Iain Buclaw
July 30, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

Steven Schveighoffer <schveiguy@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
                 CC|                            |schveiguy@yahoo.com
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=13006

--- Comment #1 from Steven Schveighoffer <schveiguy@yahoo.com> ---
Really, the issue here is that the compiler disallows inout returns without inout parameters. If we fixed issue 13006, this would resolve itself.

However, we have the option to fix this issue, or at least fix the error message to indicate what the compiler has done.

--
August 01, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

anonymous4 <dfj1esp02@sneakemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|x86                         |All
                 OS|Mac OS X                    |All

--- Comment #2 from anonymous4 <dfj1esp02@sneakemail.com> ---
struct W(T) {
    this(inout(T) val) inout {}
}

auto wrap0(T)(inout(T) t) {
    return inout W!T(t);
}

void main() {
    wrap0!int(3); // ok
    wrap0!(const int)(3); // ok
    wrap0!(immutable int)(3); // Error: inout on return means inout must be on
a parameter
}

The code has a mistake: it should be return inout W!T(t); - the constructor has an inout parameter, but the error is the same. Looks more like a bug than an enhancement.

--
August 01, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

--- Comment #3 from anonymous4 <dfj1esp02@sneakemail.com> ---
inout on return means inout must be on a parameter as well for pure nothrow
@nogc @safe inout(W!(immutable(int)))(immutable(int) t)
Looks like it's a signature of wrap0 function - the name is missing.

--
August 01, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

Steven Schveighoffer <schveiguy@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|enhancement                 |normal

--- Comment #4 from Steven Schveighoffer <schveiguy@yahoo.com> ---
Aye, the compiler is stripping inout from the type because it knows that
inout(immutable(T)) can be rewritten as immutable(T). It's not necessarily a
bug in the translation (though the error really is questionable). It's a bug in
the diagnostic message -- it's saying you didn't put inout on the parameter,
when you clearly did.

The bug in the first comment was not in the original example that showed the error, it was a copy-paste error (as you have discovered, it still fails).

--
August 02, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

--- Comment #5 from anonymous4 <dfj1esp02@sneakemail.com> ---
(In reply to Steven Schveighoffer from comment #4)
> Aye, the compiler is stripping inout from the type because it knows that
> inout(immutable(T)) can be rewritten as immutable(T).
Then wrap1 would suffer from it too, but it doesn't.

--
August 02, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

--- Comment #6 from anonymous4 <dfj1esp02@sneakemail.com> ---
Uh, no, it does.

--
August 03, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

--- Comment #7 from Ali Ak <ali.akhtarzada@gmail.com> ---
Wait how does wrap1 suffer form it? wrap1 compiles fine?

And if this is not a bug a more diagnostic, what should the error message be here?

--
August 03, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

--- Comment #8 from Steven Schveighoffer <schveiguy@yahoo.com> ---
(In reply to Ali Ak from comment #7)
> Wait how does wrap1 suffer form it? wrap1 compiles fine?

It compiles fine because it returns it's parameter without specifying inout. Essentially, the instantiated function looks like this:

auto wrap1(immutable(int) t) {
   return t;
}

> And if this is not a bug a more diagnostic, what should the error message be here?

It is a bug that has diagnostic problems. I put the diagnostic tag in because it's telling you something that is false.

What could be done is adding a note to the error like "Note:
inout(immutable(int)) is reduced to immutable(int)" when an inout error such as
the above occurs.

If we simply got rid of the restriction, everything gets better.

--
August 03, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

anonymous4 <dfj1esp02@sneakemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                URL|                            |https://forum.dlang.org/pos
                   |                            |t/echredbjbgzfylxzwbpz@foru
                   |                            |m.dlang.org
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=9983

--- Comment #9 from anonymous4 <dfj1esp02@sneakemail.com> ---
See also issue 9983 comment 1 - if you want to invoke a templated inout constructor, you will first need to completely remove inout qualifier from it.

--
August 03, 2018
https://issues.dlang.org/show_bug.cgi?id=19126

--- Comment #10 from Ali Ak <ali.akhtarzada@gmail.com> ---
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"?

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();
    }
}

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?

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?

--
« First   ‹ Prev
1 2