digitalmars.D.bugs - [Issue 9626] New: More precise error message in some cases when failed template constraint
- d-bugmail puremagic.com (116/116) Mar 01 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9626
- d-bugmail puremagic.com (8/26) Mar 04 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9626
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 puremagic.com ReportedBy: bearophile_hugs eml.cc 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: -------
Mar 01 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9626 An example of the problems this enhancement request should help solve. A question from "deed" in D.learn: http://forum.dlang.org/thread/djynnhlbfdxyurxvxuzs forum.dlang.orgWhy randomAccessRange.array() before calling sort? The std.algorithm.sort doc says: "Sorts a random-access range ..." import std.algorithm, std.array; long[] source = [2, 0, 1]; auto mapped = source.map!("a * 10"); assert (isRandomAccessRange!(typeof(mapped))); // Passes. Implies possibility // to to use std.algorithm.sort? auto mappedThenSorted = mapped.sort(); // Error auto mappedThenSorted = mapped.array.sort(); // Works (and used in examples) What am I missing in the documentation?-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 04 2013