Re: Pure Factory Functions 💔 `inout`
Steven Schveighoffer
schveiguy at gmail.com
Thu Feb 9 18:47:17 UTC 2023
On 2/9/23 12:41 PM, Quirin Schroll wrote:
> In [Pure Factory
> Functions](https://dlang.org/spec/function.html#pure-factory-functions),
> it says what conversions are enabled for the result of a strongly pure
> function because the result is unique.
>
> For one of my last PRs, I went through all possible combination of
> qualifiers and all pairs of these types. While I found no problematic
> conversion that was allowed, I did find conversions that should be
> allowed, but DMD rejects them. All of those involve `inout`; in
> particular, whatever of _mutable,_ `const`, and `immutable` you replace
> `inout` on both sides with (if at both sides), the conversion is allowed
> for a pure factory function, but not for `inout`. As far as I understand
> `inout`, this makes no sense and they should be allowed by D’s type system.
>
> Can someone take a look at the list and tell me if I’m mistaken with
> some (or all) of them?
>
> | “From” Type | “To” Type |
> |--------------------------|--------------------------|
> | _unshared_ `inout const` | `shared inout const` |
> | _unshared_ `inout` | `shared inout` |
> | _unshared_ `inout` | `shared inout const` |
> | _unshared_ `inout` | _mutable unshared_ |
> | _unshared_ `inout` | _mutable_ `shared` |
> | _unshared_ `const` | _unshared_ `inout const` |
> | _unshared_ `const` | `shared inout const` |
> | `shared inout const` | _unshared_ `inout const` |
> | `shared inout` | _unshared_ `inout` |
> | `shared inout` | _unshared_ `inout const` |
> | `shared inout` | _mutable unshared_ |
> | `shared inout` | _mutable_ `shared` |
> | `shared const` | _unshared_ `inout const` |
> | `shared const` | `shared inout const` |
> | _mutable unshared_ | _unshared_ `inout` |
> | _mutable unshared_ | _unshared_ `inout const` |
> | _mutable unshared_ | `shared inout` |
> | _mutable unshared_ | `shared inout const` |
> | _mutable_ `shared` | _unshared_ `inout` |
> | _mutable_ `shared` | _unshared_ `inout const` |
> | _mutable_ `shared` | `shared inout` |
> | _mutable_ `shared` | `shared inout const` |
>
> [Here](https://wandbox.org/permlink/DHdKvSrfXO512Kxh) is the code, for
> those interested.
a `pure` function which takes an `inout` reference and returns a
`mutable` reference should always be implicitly convertible to anything
you want. It's no different from `const` in this regard.
Now, `inout` doesn't implicitly convert to/from `shared`. So throwing
`shared` into the mix is likely to cancel some otherwise-correct
conversions, but that's on the *argument* conversion, not the *return*
conversion. The return conversion should always be valid. The idea is
that the return value must be unique.
I had a hard time following your code. Instead of using boilerplate
generation, generate the boilerplate, run it, and then generate a
complete file with the boilerplate that shows the conversions that don't
work.
-Steve
More information about the Digitalmars-d
mailing list