www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - The most confusing error message

reply Shachar Shemesh <shachar weka.io> writes:
test.d(6): Error: struct test.A(int var = 3) is used as a type

Of course it is. That's how structs are used.

Program causing this:
struct A(int var = 3) {
     int a;
}

void main() {
     A a;
}

To resolve, you need to change A into A!(). For some reason I have not 
been able to fathom, default template parameters on structs don't work 
like they do on functions.
Jan 23 2018
next sibling parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Wednesday, 24 January 2018 at 07:21:09 UTC, Shachar Shemesh 
wrote:
 test.d(6): Error: struct test.A(int var = 3) is used as a type

 Of course it is. That's how structs are used.

 Program causing this:
 struct A(int var = 3) {
     int a;
 }

 void main() {
     A a;
 }

 To resolve, you need to change A into A!(). For some reason I 
 have not been able to fathom, default template parameters on 
 structs don't work like they do on functions.
Because IFTI is short for implicit function
Jan 23 2018
parent Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Wednesday, 24 January 2018 at 07:32:17 UTC, Petar Kirov 
[ZombineDev] wrote:
 On Wednesday, 24 January 2018 at 07:21:09 UTC, Shachar Shemesh 
 wrote:
 test.d(6): Error: struct test.A(int var = 3) is used as a type

 Of course it is. That's how structs are used.

 Program causing this:
 struct A(int var = 3) {
     int a;
 }

 void main() {
     A a;
 }

 To resolve, you need to change A into A!(). For some reason I 
 have not been able to fathom, default template parameters on 
 structs don't work like they do on functions.
Because IFTI is short for implicit function
(Heh, the Send button is too easy to press on the mobile version of the forum.) Because IFTI is short for implicit function template instantiation. We don't have this feature for any other type of template, though IIRC it has been discussed before. Though one may argue that we have this feature for mixin templates: https://dlang.org/spec/template-mixin.html If the TemplateDeclaration has no parameters, the mixin form that has no !(TemplateArgumentList) can be used.
Jan 23 2018
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, January 24, 2018 09:21:09 Shachar Shemesh via Digitalmars-d 
wrote:
 test.d(6): Error: struct test.A(int var = 3) is used as a type

 Of course it is. That's how structs are used.

 Program causing this:
 struct A(int var = 3) {
      int a;
 }

 void main() {
      A a;
 }

 To resolve, you need to change A into A!(). For some reason I have not
 been able to fathom, default template parameters on structs don't work
 like they do on functions.
It's because in the general case, it would be ambiguous. For instance, what would this mean? alias B = A; Right now, B is an alias of the template A, but if we had implicit instantiation for types, B would be ambiguous. There are specific cases where it would not be ambiguous, and arguably, the compiler could be made to implicitly instantiate the template in those cases, but in general, it can't, so it never does. https://issues.dlang.org/show_bug.cgi?id=1012 As it stands, the only time that templates are ever implicitly instantiated is when a function template is called, because those instantiations are not ambiguous. A function template with default template arguments isn't instantiated either if it's not called, because it's the syntax of making the function call that makes it unambiguous. Hence we talk about IFTI (Implicit Function Template Instantiation) when we talk about templates being implicitly instantiated. - Jonathan M Davis
Jan 24 2018
parent reply Shachar Shemesh <shachar weka.io> writes:
On 24/01/18 10:01, Jonathan M Davis wrote:
 On Wednesday, January 24, 2018 09:21:09 Shachar Shemesh via Digitalmars-d
 wrote:
 test.d(6): Error: struct test.A(int var = 3) is used as a type

 Of course it is. That's how structs are used.

 Program causing this:
 struct A(int var = 3) {
       int a;
 }

 void main() {
       A a;
 }

 To resolve, you need to change A into A!(). For some reason I have not
 been able to fathom, default template parameters on structs don't work
 like they do on functions.
It's because in the general case, it would be ambiguous. For instance, what would this mean? alias B = A; Right now, B is an alias of the template A, but if we had implicit instantiation for types, B would be ambiguous.
So there is a reason this is an error. Fine. Is there also a reason why the error message doesn't say "Cannot instantiate template test.A(int var = 3) with no arguments" or something? Right now, the error says that "Struct (something) is used as a type", to which my instinctive response is "yeah, why is that an error?" Shachar
Jan 24 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, January 24, 2018 15:15:30 Shachar Shemesh via Digitalmars-d 
wrote:
 On 24/01/18 10:01, Jonathan M Davis wrote:
 On Wednesday, January 24, 2018 09:21:09 Shachar Shemesh via
 Digitalmars-d

 wrote:
 test.d(6): Error: struct test.A(int var = 3) is used as a type

 Of course it is. That's how structs are used.

 Program causing this:
 struct A(int var = 3) {

       int a;

 }

 void main() {

       A a;

 }

 To resolve, you need to change A into A!(). For some reason I have not
 been able to fathom, default template parameters on structs don't work
 like they do on functions.
It's because in the general case, it would be ambiguous. For instance, what would this mean? alias B = A; Right now, B is an alias of the template A, but if we had implicit instantiation for types, B would be ambiguous.
So there is a reason this is an error. Fine. Is there also a reason why the error message doesn't say "Cannot instantiate template test.A(int var = 3) with no arguments" or something? Right now, the error says that "Struct (something) is used as a type", to which my instinctive response is "yeah, why is that an error?"
Then open a bugzilla issue about how bad the error message is. It's probably a result of whatever code generating the error message being shared between explicit templates and other sorts of templates where the template keyword isn't used, and it doesn't handle the non-explicit templates very well. Walter is quite open to improving error messages, but usually, the complaint is that error messages aren't good enough without any examples given, and he wants specific examples. You have one, so he (or one of the other compiler devs) should be able to fix it. You should always feel free to report error messages that you think are bad. - Jonathan M Davis
Jan 24 2018
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 01/24/2018 05:36 AM, Jonathan M Davis wrote:

 It's probably
 a result of whatever code generating the error message being shared 
between
 explicit templates and other sorts of templates where the template 
keyword
 isn't used, and it doesn't handle the non-explicit templates very well.
It's more general than templates. Here are two quick cases with the same error message: enum Color { Red } void main() { int i; i j; // <-- Same error with (Color) { Red r; // <-- Same error } } Error: i is used as a type Error: Red is used as a type Ali
Jan 24 2018
prev sibling parent reply Meta <jared771 gmail.com> writes:
On Wednesday, 24 January 2018 at 07:21:09 UTC, Shachar Shemesh 
wrote:
 test.d(6): Error: struct test.A(int var = 3) is used as a type

 Of course it is. That's how structs are used.

 Program causing this:
 struct A(int var = 3) {
     int a;
 }

 void main() {
     A a;
 }

 To resolve, you need to change A into A!(). For some reason I 
 have not been able to fathom, default template parameters on 
 structs don't work like they do on functions.
IMO the error message is not too bad once you understand what's going on (which probably means it's really not a good error message). struct A(int var = 3) is short for: template A(int var = 3) { struct A { //... } } As I'm sure you know. If it's written out like this then I think it makes it obvious what the problem is. When you write `A a`, you're trying to use this template like a type, but templates are not types; they are used to _construct_ types. Therefore, to construct a valid type from the template A, you have to instantiate it by declaring an `A!() a`. The compiler could allow implicit insatntiation if the template has 0 arguments or only default arguments, but as Jonathan showed, this causes a lot of ambiguous cases that are better avoided. One way we could probably improve the error message is to change it to "template struct test.A(int var = 3) is used as a type. It must be instantiated", or something along those lines, to make it clear why you can't use A as a type.
Jan 24 2018
next sibling parent reply Nick Treleaven <nick geany.org> writes:
On Wednesday, 24 January 2018 at 14:22:59 UTC, Meta wrote:
 One way we could probably improve the error message is to 
 change it to "template struct test.A(int var = 3) is used as a 
 type. It must be instantiated", or something along those lines, 
 to make it clear why you can't use A as a type.
https://github.com/dlang/dmd/pull/7769
Jan 24 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, January 24, 2018 16:21:39 Nick Treleaven via Digitalmars-d 
wrote:
 On Wednesday, 24 January 2018 at 14:22:59 UTC, Meta wrote:
 One way we could probably improve the error message is to
 change it to "template struct test.A(int var = 3) is used as a
 type. It must be instantiated", or something along those lines,
 to make it clear why you can't use A as a type.
https://github.com/dlang/dmd/pull/7769
Even better than a bug report. :) Thanks. - Jonathan M Davis
Jan 24 2018
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, January 24, 2018 14:22:59 Meta via Digitalmars-d wrote:
 IMO the error message is not too bad once you understand what's
 going on (which probably means it's really not a good error
 message).
It's not that uncommon for me to see a question in D.Learn where someone is asking a question about an error message, and I have no idea why the error message isn't clear. After all, it's saying exactly what's wrong. It's just that it's saying it in compiler-speak, and when you know less about D or about the compiler, that tends to be less clear. As such, on some level, the more you know, the worse you're probably going to be at knowing when an error message is bad - which makes it all that more critical that folks report error messages that they think are bad and give suggestions on how they could be improved. I know that I've fallen way short on that - in part, because I usually understand the error messages and don't spend time trying to figure out how they might be improved, and in part because even when I know that an error message is poor, I'm usually far more interested in fixing my code and getting on with life than spending the time to open a bug report. But more of us need to take the time to open those bug reports if we want the error messages to improve - or even better, take the time to open a PR to fix them, but that tends to take a much greater level of knowledge than is required to report the bad message, and most of us aren't compiler devs. - Jonathan M Davis
Jan 24 2018