D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7838 - Give some error messages for wrong ranges
Summary: Give some error messages for wrong ranges
Status: RESOLVED LATER
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Windows
: P2 enhancement
Assignee: No Owner
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2012-04-05 17:55 UTC by bearophile_hugs
Modified: 2021-03-16 10:42 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2012-04-05 17:55:22 UTC
I'd like DMD to give some error messages for wrong definitions of ranges, like in this case:


struct Powers {
    int m;
    BigInt n;
    this(int m_) { this.m = m_; }
    const bool empty = false;
    BigInt front() { return n ^^ m; }
    void popFront() { n += 1; }
}


It looks correct, but it's wrong. ElementType!Powers is void.

The correct code (a @property was missing):

struct Powers {
    int m;
    BigInt n;
    this(int m_) { this.m = m_; }
    const bool empty = false;
    @property BigInt front() { return n ^^ m; }
    void popFront() { n += 1; }
}
Comment 1 Matt Peterson 2012-04-05 19:42:00 UTC
My understanding is that you would usually put a static assert with isInputRange, or a more specific template from std.range immediately after the struct. How is DMD supposed to know that that struct is suppose to be a range otherwise?
Comment 2 bearophile_hugs 2012-04-06 10:09:17 UTC
(In reply to comment #1)
> My understanding is that you would usually put a static assert with
> isInputRange, or a more specific template from std.range immediately after the
> struct.

This is an example program:


import std.range, std.bigint;
struct Powers {
    int m;
    BigInt n;
    this(int m_) { this.m = m_; }
    const bool empty = false;
    BigInt front() { return n ^^ m; }
    void popFront() { n += 1; }
}
static assert(isInputRange!Powers);
void main() {}


If I compile it with DMD 2.059beta:

...>dmd -property -run temp.d
temp.d(10): Error: static assert  (isInputRange!(Powers)) is false


So it gives me no hint where the problem is. A built-in error message is supposed to be more precise.

As alternative, maybe there is a way to add focused error messages inside a isInputRangeVerify template to be used to verify that  an input range is correct, that uses pragma(msg) or better ctWriteln.


> How is DMD supposed to know that that struct is suppose to be a range
> otherwise?

I see, it's a problem.
So here we are talking more about a probabilistic compiler tip. If the class/struct contains a popFront and front and empty methods then the programmer probably meants it to be a range.

Thank you for your answer.
Comment 3 Matt Peterson 2012-04-06 10:47:21 UTC
Yeah, I think the best solution is to add verifyInputRange etc. templates to std.range, where each criteria is checked by a separate static assert. It's just a little ugly because there will end up being nearly duplicate templates for all the different range types.
Comment 4 bearophile_hugs 2012-04-06 11:06:31 UTC
(In reply to comment #3)
> It's just a little ugly because there will end up being nearly
> duplicate templates for all the different range types.

I think putting such test code inside DMD itself doesn't reduce the overall complexity a lot...
Comment 5 RazvanN 2021-03-16 10:42:09 UTC
The problem with this is that it might brake code that implements some of the range functions but doesn't care about the others. Also, I don't think identifying why an entity is not a range is that problematic. Since this issue is rather old and people have not been complaining about this, I will close as LATER. If this comes up again, please reopen.