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