[Issue 9626] New: More precise error message in some cases when failed template constraint

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Mar 1 12:36:16 PST 2013


http://d.puremagic.com/issues/show_bug.cgi?id=9626

           Summary: More precise error message in some cases when failed
                    template constraint
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: diagnostic
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody at puremagic.com
        ReportedBy: bearophile_hugs at eml.cc


--- Comment #0 from bearophile_hugs at eml.cc 2013-03-01 12:36:11 PST ---
This experimental branch of the GCC C++ compiler implements constraints for
template arguments, named "concepts lite", that seem very similar to D template
constraints:

http://isocpp.org/blog/2013/02/concepts-lite-constraining-templates-with-predicates-andrew-sutton-bjarne-s

http://concepts.axiomatics.org/~ans/


In that page they show an example of error message:

template<Sortable Cont>
void sort(Cont& container);

list<int> lst = ...;
sort(lst);


It gives a small amount of readable error messages:

error: no matching function for call to ‘sort(list<int>&)’
   sort(l);
         ^
note: candidate is:
note: template<Sortable T> void sort(T)
   void sort(T t) { }
        ^
note: template constraints not satisfied because
note:   'T' is not a/an 'Sortable' type [with T = list<int>] since
note:     'declval<T>()[n]' is not valid syntax



For a similar wrong D program:


import std.container: DList;
import std.algorithm: sort;
void main() {
    auto lst = DList!int([10, 3, 14]);
    sort(lst); // Line 5.
}



Currently DMD 2.063alpha gives a little worse error messages:


test.d(5): Error: template std.algorithm.sort does not match any function
template declaration. Candidates are:
...\dmd2\src\phobos\std\algorithm.d(8103):        std.algorithm.sort(alias less
= "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss ==
SwapStrategy.unstable && (hasSwappableElements!(Range) ||
hasAssignableElements!(Range)) || ss != SwapStrategy.unstable &&
hasAssignableElements!(Range)) && isRandomAccessRange!(Range) &&
hasSlicing!(Range) && hasLength!(Range))
test.d(5): Error: template std.algorithm.sort(alias less = "a < b",
SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss ==
SwapStrategy.unstable && (hasSwappableElements!(Range) ||
hasAssignableElements!(Range)) || ss != SwapStrategy.unstable &&
hasAssignableElements!(Range)) && isRandomAccessRange!(Range) &&
hasSlicing!(Range) && hasLength!(Range)) cannot deduce template function from
argument types !()(DList!(int))



Currently these are the template constraints for std.algorithm.sort:


SortedRange!(Range, less)
sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable,
        Range)(Range r)
    if (((ss == SwapStrategy.unstable && (hasSwappableElements!Range ||
                                          hasAssignableElements!Range)) ||
         (ss != SwapStrategy.unstable && hasAssignableElements!Range)) &&
        isRandomAccessRange!Range &&
        hasSlicing!Range &&
        hasLength!Range)
    /+ Unstable sorting uses the quicksort algorithm, which uses swapAt,
       which either uses swap(...), requiring swappable elements, or just
       swaps using assignment.
       Stable sorting uses TimSort, which needs to copy elements into a buffer,
       requiring assignable elements. +/
{ ...



In D template constraints have two (or more) related but different purposes: to
exclude one or more templates from the list of possible templates to
instantiate, and to restrict a single template to be instantiated correctly
(like this sort), to avoid error messages inside the implementation of sort().

Like in the error message generated by that concepts lite compiler, I think
it's possible to improve the error message generated by the D compiler for this
second usage, when there is only one (or two?) templates available, like in the
case of sort().

In this case the compiler, after the current error messages, can print one more
error message that shows what parts of the following template constraint have
failed:

(((ss == SwapStrategy.unstable &&
   (hasSwappableElements!Range ||
    hasAssignableElements!Range)) ||
  (ss != SwapStrategy.unstable &&
   hasAssignableElements!Range)) &&
 isRandomAccessRange!Range &&
 hasSlicing!Range &&
 hasLength!Range)


In this case SwapStrategy is unstable. And for a DList!int all the unstable
requirements fail:

import std.container: DList;
import std.range: hasSwappableElements, hasAssignableElements,
                  isRandomAccessRange, hasSlicing, hasLength;
void main() {
    alias Range = DList!int;
    pragma(msg, hasSwappableElements!Range);
    pragma(msg, hasAssignableElements!Range);
    pragma(msg, isRandomAccessRange!Range);
    pragma(msg, hasSlicing!Range);
    pragma(msg, hasLength!Range);
}


Output:

false
false
false
false
false

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list