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)`
This commit is contained in:
Paul Backus 2022-02-09 11:00:20 -05:00 committed by The Dlang Bot
parent ab4008c13f
commit 5ca44b74a5

View file

@ -262,6 +262,8 @@ private enum isHashable(T) = __traits(compiles,
private enum hasPostblit(T) = __traits(hasPostblit, T);
private enum isInout(T) = is(T == inout);
/**
* A [tagged union](https://en.wikipedia.org/wiki/Tagged_union) that can hold a
* single value from any of a specified set of types.
@ -419,6 +421,7 @@ public:
(
allSatisfy!(isCopyable, Map!(InoutOf, Types))
&& !anySatisfy!(hasPostblit, Map!(InoutOf, Types))
&& allSatisfy!(isInout, Map!(InoutOf, Types))
)
{
/// Constructs a `SumType` that's a copy of another `SumType`.
@ -1492,6 +1495,23 @@ version (D_BetterC) {} else
immutable SumType!(int*) si = ∋
}
// Immutable member type with copy constructor
// https://issues.dlang.org/show_bug.cgi?id=22572
@safe unittest
{
static struct CopyConstruct
{
this(ref inout CopyConstruct other) inout {}
}
static immutable struct Value
{
CopyConstruct c;
}
SumType!Value s;
}
/// True if `T` is an instance of the `SumType` template, otherwise false.
private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...);