www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 18339] New: Variant.coerce is unable to convert between types

https://issues.dlang.org/show_bug.cgi?id=18339

          Issue ID: 18339
           Summary: Variant.coerce is unable to convert between types that
                    std.conv.to is able to convert
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: hsteoh quickfur.ath.cx

Code:
----------
import std.conv;
import std.variant;

struct MyValue {
        int impl;
        auto opCast(T : MyOtherValue)() {
                return MyOtherValue(impl);
        }
}

struct MyOtherValue {
        int impl;
}

void main() {
        auto mv = MyValue(123);
        MyOtherValue mov2 = mv.to!MyOtherValue; // OK

        Variant v = mv;
        MyOtherValue mov = v.coerce!MyOtherValue; // NG
}
----------

Compiler output:
----------
/usr/src/d/phobos/std/variant.d(844): Error: static assert:  "unsupported type
for coercion"
----------

Given the current implementation of Variant, I'm not sure how possible this is,
but it would be *very* nice if there were some way of saying, given an object
of type Variant, "I don't care what the actual underlying type is, just convert
it to T using std.conv.to or throw an exception if that's not possible". 
Currently, you have to know that the stored type is MyValue, then you can
extract a MyValue and convert it to MyOtherValue.  However, in generic code,
it's often not possible (or desirable) to have to know what the original type
is; sometimes the code just knows it wants some desired type T, and Variant
should either convert to T somehow (preferably with std.conv.to, since that's
the standard conversion tool in D), or throw an exception if the underlying
types are incompatible.

Related: issue #12997.

--
Jan 30