Thread overview
only parameters or stack-based variables can be `inout`
November 25

I suspect a bug in conv.to, am I right?

import std;

enum E
{
    One,
    Two
}

// OK:
inout(int) fun(inout(int) i)
{
    writeln(i.to!string);
    return i;
}

// Fishy:
inout(E) gun(inout(E) e)
{
    //writeln(e.to!string); // only parameters or stack-based variables can be `inout`
    writeln((cast(Unqual!E)e).to!string); // OK
    return e;
}

void main()
{
    fun(1);
    gun(E.One);
}

-- Bastiaan

November 25

On Monday, 25 November 2024 at 14:24:44 UTC, Bastiaan Veelo wrote:

>

I suspect a bug in conv.to, am I right?

Yes, this is a bug. Because of the weird restrictions on inout, it's very easy to write template code that doesn't handle it correctly.

November 25

On Monday, 25 November 2024 at 15:09:46 UTC, Paul Backus wrote:

>

Yes, this is a bug. Because of the weird restrictions on inout, it's very easy to write template code that doesn't handle it correctly.

I see you reported it. Thank you.
https://issues.dlang.org/show_bug.cgi?id=24880

-- Bastiaan.

November 25
On Monday, November 25, 2024 8:09:46 AM MST Paul Backus via Digitalmars-d- learn wrote:
> On Monday, 25 November 2024 at 14:24:44 UTC, Bastiaan Veelo wrote:
> > I suspect a bug in conv.to, am I right?
>
> Yes, this is a bug. Because of the weird restrictions on `inout`, it's very easy to write template code that doesn't handle it correctly.

Yeah, dealing with inout in templated code is surprisingly annoying. There are cases where it just works, but there are also too many cases where the compiler gets weirdly picky (whether it should or not), and unless code is specifically tested with inout, it can be pretty easy for bugs related to that to make it in. I've been hitting this surprisingly frequently at work recently when refactoring code, and if it weren't for the fact that there already existed code calling the functions in question which used inout, it probably wouldn't have worked properly when used with inout later.

So, I should probably add inout to the list of things that the Phobos v3 test helpers will need to include help for to at least try to make it easier to catch.

- Jonathan M Davis



November 26

On Monday, 25 November 2024 at 14:24:44 UTC, Bastiaan Veelo wrote:

>

// Fishy:
inout(E) gun(inout(E) e)
{
//writeln(e.to!string); // only parameters or stack-based variables can be inout
writeln((cast(Unqual!E)e).to!string); // OK
return e;
}

Longstanding issue. When inout was first proposed, the point was to prevent people from using in nonsensical ways. But this really prevents reasonable template usage without all kinds of static checks.

I went over this in my 2016 talk: https://dconf.org/2016/talks/schveighoffer.html

  1. inout should just be allowed to be returned when parameters are not inout. The equivalent would just be const.
  2. inout member fields should be fine.

-Steve

November 26

On Tuesday, 26 November 2024 at 04:15:35 UTC, Steven Schveighoffer wrote:

>

On Monday, 25 November 2024 at 14:24:44 UTC, Bastiaan Veelo wrote:

>

// Fishy:
inout(E) gun(inout(E) e)
{
//writeln(e.to!string); // only parameters or stack-based variables can be inout
writeln((cast(Unqual!E)e).to!string); // OK
return e;
}

Longstanding issue. When inout was first proposed, the point was to prevent people from using in nonsensical ways. But this really prevents reasonable template usage without all kinds of static checks.

I went over this in my 2016 talk: https://dconf.org/2016/talks/schveighoffer.html

  1. inout should just be allowed to be returned when parameters are not inout. The equivalent would just be const.
  2. inout member fields should be fine.

In this case the specific limitation getting in the way is that you cannot pass an inout value as an argument to a template value parameter.