Jump to page: 1 2
Thread overview
[Issue 9286] New: std.conv fails to compile with Nullable
[Issue 9286] std.conv.parse fails to compile with Nullable
Jan 09, 2013
Jonathan M Davis
Jan 09, 2013
Jonathan M Davis
Jan 09, 2013
Jonathan M Davis
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286

           Summary: std.conv fails to compile with Nullable
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: regression
          Priority: P2
         Component: Phobos
        AssignedTo: nobody@puremagic.com
        ReportedBy: jens.k.mueller@gmx.de


--- Comment #0 from jens.k.mueller@gmx.de 2013-01-09 02:47:57 PST ---
dmd 2.061 introduced the following regression.
The code

unittest
{
    import std.typecons;
    import std.conv;
    auto f = to!(Nullable!(uint))("12");
    assert(f == 12);
}

used to compile and work with dmd 2.060. Now it fails with

/usr/local/bin/../src/phobos/std/conv.d(274): Error: template std.conv.toImpl
does not match any function template declaration. Candidates are:
/usr/local/bin/../src/phobos/std/conv.d(330):        std.conv.toImpl(T, S)(S
value) if (isImplicitlyConvertible!(S, T) && !isEnumStrToStr!(S, T) &&
!isNullToStr!(S, T))
/usr/local/bin/../src/phobos/std/conv.d(436):        std.conv.toImpl(T, S)(ref
S s) if (isRawStaticArray!(S))
/usr/local/bin/../src/phobos/std/conv.d(450):        std.conv.toImpl(T, S)(S
value) if (is(S : Object) && !is(T : Object) && !isSomeString!(T) &&
hasMember!(S, "to") && is(typeof(S.init.to!(T)()) : T))
/usr/local/bin/../src/phobos/std/conv.d(471):        std.conv.toImpl(T, S)(S
value) if (is(typeof(S.init.opCast!(T)()) : T) && !isExactSomeString!(T))
/usr/local/bin/../src/phobos/std/conv.d(502):        std.conv.toImpl(T, S)(S
value) if (!isImplicitlyConvertible!(S, T) && is(T == struct) &&
is(typeof(T(value))))
/usr/local/bin/../src/phobos/std/conv.d(274):        ... (16 more, -v to show)
...
/usr/local/bin/../src/phobos/std/conv.d(330): Error: template std.conv.toImpl
cannot deduce template function from argument types !(Nullable!(uint))(string)
/usr/local/bin/../src/phobos/std/conv.d(274): Error: template instance
toImpl!(Nullable!(uint)) errors instantiating template
test.d(9): Error: template instance std.conv.to!(Nullable!(uint)).to!(string)
error instantiating

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286


jens.k.mueller@gmx.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|std.conv fails to compile   |std.conv.parse fails to
                   |with Nullable               |compile with Nullable


--- Comment #1 from jens.k.mueller@gmx.de 2013-01-09 02:51:25 PST ---
Actually std.conv.parse is called by std.conv.to. Thus, the better example is:

unittest
{
    import std.typecons;
    import std.conv;
    auto f = parse!(Nullable!(uint))("12");
    assert(f == 12);
}

which fails with

test.d(9): Error: template std.conv.parse does not match any function template
declaration. Candidates are:
/usr/local/bin/../src/phobos/std/conv.d(1724):        std.conv.parse(Target,
Source)(ref Source s) if (isSomeChar!(ElementType!(Source)) &&
isIntegral!(Target) && !is(Target == enum))
/usr/local/bin/../src/phobos/std/conv.d(1978):        std.conv.parse(Target,
Source)(ref Source s, uint radix) if (isSomeChar!(ElementType!(Source)) &&
isIntegral!(Target) && !is(Target == enum))
/usr/local/bin/../src/phobos/std/conv.d(2075):        std.conv.parse(Target,
Source)(ref Source s) if (isExactSomeString!(Source) && is(Target == enum))
/usr/local/bin/../src/phobos/std/conv.d(2134):        std.conv.parse(Target,
Source)(ref Source p) if (isInputRange!(Source) &&
isSomeChar!(ElementType!(Source)) && !is(Source == enum) &&
isFloatingPoint!(Target) && !is(Target == enum))
/usr/local/bin/../src/phobos/std/conv.d(2620):        std.conv.parse(Target,
Source)(ref Source s) if (isExactSomeString!(Source) &&
staticIndexOf!(Unqual!(Target), dchar, Unqual!(ElementEncodingType!(Source)))
>= 0)
test.d(9):        ... (7 more, -v to show) ...
/usr/local/bin/../src/phobos/std/conv.d(1724): Error: template std.conv.parse
cannot deduce template function from argument types !(Nullable!(uint))(string)
test.d(9): Error: template instance parse!(Nullable!(uint)) errors
instantiating template

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286



--- Comment #2 from jens.k.mueller@gmx.de 2013-01-09 02:56:06 PST ---
Tracking it further down:
isIntegral!(Nullable!(uint)) used to be true now it is false.

Is this expected to be true or false?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286


bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #3 from bearophile_hugs@eml.cc 2013-01-09 03:13:32 PST ---
(In reply to comment #2)
> Tracking it further down:
> isIntegral!(Nullable!(uint)) used to be true now it is false.
> 
> Is this expected to be true or false?

From a recent discussion I think this is now desired.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286



--- Comment #4 from jens.k.mueller@gmx.de 2013-01-09 03:18:37 PST ---
(In reply to comment #3)
> (In reply to comment #2)
> > Tracking it further down:
> > isIntegral!(Nullable!(uint)) used to be true now it is false.
> > 
> > Is this expected to be true or false?
> 
> From a recent discussion I think this is now desired.

Can you point me to this discussion?
Because I'm unsure whether this is a good move. What if write my own integral
type? That type won't be usable with code using isIntegral. If you want to make
sure that you have a built-in integral you should to something like isBuiltIn!T
&& isIntegral!T.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286


Jonathan M Davis <jmdavisProg@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg@gmx.com


--- Comment #5 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-01-09 03:32:01 PST ---
std.traits is purposefully _not_ taking implict conversion into account (doing otherwise would cause havoc with template constraints), and isIntegral specifically says "Detect whether $(D T) is a built-in integral type." And it's not like isIntegral could be made to work for user-defined types, as integral types don't have an API specific to themselves. The trait has to know all of the types that count as being integral types.

To do the conversion that you're looking for, just convert to uint first:

    auto f = to!(Nullable!uint)(to!uint("12"));

or

    auto f = Nullable!uint(to!uint("12"));

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286



--- Comment #6 from jens.k.mueller@gmx.de 2013-01-09 03:43:24 PST ---
(In reply to comment #5)
> std.traits is purposefully _not_ taking implict conversion into account (doing otherwise would cause havoc with template constraints), and isIntegral specifically says "Detect whether $(D T) is a built-in integral type." And it's not like isIntegral could be made to work for user-defined types, as integral types don't have an API specific to themselves. The trait has to know all of the types that count as being integral types.

I perfectly agree that isIntegral now conforms to the documentation. Just the
name is misleading.
Why is it impossible to make isIntegral work for user-defined types in the same
way as e.g. isInputRange works?
They do have an API. Just to mention some you use +, -, *, / etc. You just need
to fix this set.

> To do the conversion that you're looking for, just convert to uint first:
> 
>     auto f = to!(Nullable!uint)(to!uint("12"));
> 
> or
> 
>     auto f = Nullable!uint(to!uint("12"));

Can't do this as this happens inside getopt. I pass getopt a Nullable and later check whether it was actually set by getopt.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286



--- Comment #7 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-01-09 03:51:47 PST ---
> Why is it impossible to make isIntegral work for user-defined types in the
> same way as e.g. isInputRange works?
> They do have an API. Just to mention some you use +, -, *, / etc. You just
> need to fix this set.

Because those operations aren't unique to integral types. They're not even necessarily unique to _numeric_ types. Input ranges have fairly a unique API, so you can test for it, but integral types don't have an API that's even vaguely unique.

> Can't do this as this happens inside getopt. I pass getopt a Nullable and later check whether it was actually set by getopt.

Well, with getopt's design, you're pretty much stuck either using uint (and assuming that 0 means that nothing was set or just use 0 as the default for whatever you're doing), or you have to take the string and do what you want to yourself. It's just not designed to distinguish between an option not being set and it being set to the default. I suppose as an alternative, you could use a floating point type and if it's not NaN, test to make sure that the result is an integral.

I suppose that a possible solution to the design issue with getopt would be to make it special-case Nullable so that you'd get the behavior that you're looking for.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286



--- Comment #8 from jens.k.mueller@gmx.de 2013-01-09 04:07:20 PST ---
(In reply to comment #7)
> > Why is it impossible to make isIntegral work for user-defined types in the
> > same way as e.g. isInputRange works?
> > They do have an API. Just to mention some you use +, -, *, / etc. You just
> > need to fix this set.
> 
> Because those operations aren't unique to integral types. They're not even necessarily unique to _numeric_ types. Input ranges have fairly a unique API, so you can test for it, but integral types don't have an API that's even vaguely unique.

I believe the set of operations is unique. But I would need to try it out. Do you happen to know of an example that supports the set of integral oprations yet is no integral?

> > Can't do this as this happens inside getopt. I pass getopt a Nullable and later check whether it was actually set by getopt.
> 
> Well, with getopt's design, you're pretty much stuck either using uint (and assuming that 0 means that nothing was set or just use 0 as the default for whatever you're doing), or you have to take the string and do what you want to yourself. It's just not designed to distinguish between an option not being set and it being set to the default. I suppose as an alternative, you could use a floating point type and if it's not NaN, test to make sure that the result is an integral.
> 
> I suppose that a possible solution to the design issue with getopt would be to make it special-case Nullable so that you'd get the behavior that you're looking for.

Yah. Same here. I will look for a way to fix this in my code.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 09, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9286


jens.k.mueller@gmx.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2