Bug 22572 – Cannot define SumType over immutable struct with Nullable

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-12-06T12:24:06Z
Last change time
2022-02-09T22:50:16Z
Keywords
industry, pull
Assigned to
No Owner
Creator
FeepingCreature

Comments

Comment #0 by default_357-line — 2021-12-06T12:24:06Z
Not sure if Phobos or DMD issue. Consider this code: import std; immutable struct Value { Nullable!string n; } void main() { SumType!Value value; } This gets /dlang/dmd-nightly/linux/bin64/../../src/phobos/std/sumtype.d(1985): Error: static assert: "`handlers[0]` of type `template` never matches" If we replace Nullable with a simpler struct: struct CopyConstruct { this(ref CopyConstruct other) { } } immutable struct Value { CopyConstruct c; } void main() { SumType!Value value; } Then we get the revealing error: Error: Generating an `inout` copy constructor for `struct onlineapp.Value` failed, therefore instances of it are uncopyable It looks like Nullable's copy constructor does not play well with immutable structs. The strange `handler never matches` error above seems to only arise because DMD manages to defer this error until the SumType handler. But this is not the primary issue.
Comment #1 by snarwin+bugzilla — 2022-02-09T14:46:36Z
There's definitely a SumType issue here: --- import std.sumtype; struct CopyConstruct { this(ref inout CopyConstruct other) inout { } } immutable struct Value { CopyConstruct c; } alias _ = SumType!Value; --- The example above produces the following error message, as of DMD/Phobos 2.098.1: --- /dlang/dmd/linux/bin64/../../src/phobos/std/sumtype.d(1998): Error: static assert: "`handlers[0]` of type `template` never matches" /dlang/dmd/linux/bin64/../../src/phobos/std/sumtype.d(1590): instantiated from here: `matchImpl!(inout(SumType!(immutable(Value))))` /dlang/dmd/linux/bin64/../../src/phobos/std/sumtype.d(452): instantiated from here: `match!(inout(SumType!(immutable(Value))))` onlineapp.d(13): instantiated from here: `SumType!(immutable(Value))` --- The source of the error is this line: https://github.com/dlang/phobos/blob/v2.098.1/std/sumtype.d#L452 Compiling with -verrors=spec reveals the following gagged error, which is ultimately responsible for the failure: --- (spec:1) src/sumtype.d(389): Error: `inout` on `return` means `inout` must be on a parameter as well for `pure nothrow @nogc @safe inout(Storage)(ref immutable(Value) value)` --- SumType's copy constructor incorrectly assumes that, when copying from an `inout(SumType) other`, the value stored in `other` will also be inout-qualified. However, this is not the case when one of other's members is an immutable struct, because the qualifier combination `immutable inout` collapses to just `immutable`.
Comment #2 by snarwin+bugzilla — 2022-02-09T16:00:00Z
Fixed in sumtype v1.2.1 on code.dlang.org by this PR: https://github.com/pbackus/sumtype/pull/78
Comment #3 by dlang-bot — 2022-02-09T16:07:43Z
@pbackus created dlang/phobos pull request #8377 "Fix Issue 22572 - Cannot define SumType over immutable struct with Nu…" fixing this issue: - Fix Issue 22572 - Cannot define SumType over immutable struct with Nullable Previously, SumType incorrectly assumed that all members of an inout(SumType) must themselves be inout-qualified. However, this is not the case when one of those member types is declared as immutable, since the qualifier combination `immutable inout` collapses to just `immutable`. Attempting to copy an immutable member type as though it were inout caused matching to fail in SumType's copy constructor, due to the following (gagged) error: Error: `inout` on `return` means `inout` must be on a parameter as well for `pure nothrow @nogc @safe inout(Storage)(ref immutable(Value) value)` https://github.com/dlang/phobos/pull/8377
Comment #4 by dlang-bot — 2022-02-09T22:50:16Z
dlang/phobos pull request #8377 "Fix Issue 22572 - Cannot define SumType over immutable struct with Nu…" was merged into master: - 32924e3fc34676bb4e89efcbcbd202e6e9af911f by Paul Backus: Fix Issue 22572 - Cannot define SumType over immutable struct with Nullable Previously, SumType incorrectly assumed that all members of an inout(SumType) must themselves be inout-qualified. However, this is not the case when one of those member types is declared as immutable, since the qualifier combination `immutable inout` collapses to just `immutable`. Attempting to copy an immutable member type as though it were inout caused matching to fail in SumType's copy constructor, due to the following (gagged) error: Error: `inout` on `return` means `inout` must be on a parameter as well for `pure nothrow @nogc @safe inout(Storage)(ref immutable(Value) value)` https://github.com/dlang/phobos/pull/8377