Jump to page: 1 2
Thread overview
The most confusing error message
Jan 24, 2018
Shachar Shemesh
Jan 24, 2018
Jonathan M Davis
Jan 24, 2018
Shachar Shemesh
Jan 24, 2018
Jonathan M Davis
Jan 24, 2018
Ali Çehreli
Jan 24, 2018
Meta
Jan 24, 2018
Nick Treleaven
Jan 25, 2018
Jonathan M Davis
Jan 25, 2018
Jonathan M Davis
January 24, 2018
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.
January 24, 2018
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
January 24, 2018
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.
January 24, 2018
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

January 24, 2018
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
January 24, 2018
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

January 24, 2018
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.
January 24, 2018
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
January 24, 2018
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

January 24, 2018
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

« First   ‹ Prev
1 2