Cannot convert expression of a SubType's sub type to the parent SubType on return

Josh Holtrop jholtrop at gmail.com
Tue Jun 6 21:04:40 UTC 2023


I am trying to use std.sumtype which seems to be just what I need 
for some functions that can return various types of errors with 
parameters or a success value with different parameters.

In this test I get a compilation error with ldc2:

```d
import std.stdio;
import std.sumtype;

struct Error {string message;}
struct Success {int s;}

SumType!(
         Error,
         Success)
     foo(string[] args)
{
     if (args.length > 1)
     {
         return Success(cast(int)args.length);
     }
     else
     {
         return Error("not enough arguments");
     }
}

int main(string[] args)
{
     foo(args).match!(
             (Error e) {writeln("Error ", e.message);},
             (Success s) {writeln("Success: ", s.s);});
     return 0;
}
```

It seems that the compiler does not want to convert an Error or 
Success value to the SumType!(Error, Success) value automatically.

Ok, well if I create an alias for the type and assign to an 
instance of that it seems to work:
```d
import std.stdio;
import std.sumtype;

struct Error {string message;}
struct Success {int s;}

alias FooReturnType = SumType!(
         Error,
         Success);

FooReturnType foo(string[] args)
{
     FooReturnType fr;
     if (args.length > 1)
     {
         return fr = Success(cast(int)args.length);
     }
     else
     {
         return fr = Error("not enough arguments");
     }
}

int main(string[] args)
{
     foo(args).match!(
             (Error e) {writeln("Error ", e.message);},
             (Success s) {writeln("Success: ", s.s);});
     return 0;
}
```

Or if I just do a simple cast it also seems to work:

```d
import std.stdio;
import std.sumtype;
import std.traits;

struct Error {string message;}
struct Success {int s;}

SumType!(
         Error,
         Success)
     foo(string[] args)
{
     if (args.length > 1)
     {
         return cast(ReturnType!foo)Success(cast(int)args.length);
     }
     else
     {
         return cast(ReturnType!foo)Error("not enough arguments");
     }
}

int main(string[] args)
{
     foo(args).match!(
             (Error e) {writeln("Error ", e.message);},
             (Success s) {writeln("Success: ", s.s);});
     return 0;
}
```

But both of those seem a little ugly. Is there a better approach 
than one of these two workarounds? Or a way to make the compiler 
ok with converting an Error or Success to a SumType!(Error, 
Success)?

ldc2 version:

```
LDC - the LLVM D compiler (1.28.0):
   based on DMD v2.098.0 and LLVM 11.1.0
   built with LDC - the LLVM D compiler (1.28.0)
   Default target: x86_64-pc-linux-gnu
   Host CPU: skylake
   http://dlang.org - http://wiki.dlang.org/LDC
```


More information about the Digitalmars-d-learn mailing list