Thread overview
BetterC Bug? Intended Behavior? Asking Here As Unsure
Jul 06, 2020
Kayomn
Jul 06, 2020
Stanislav Blinov
Jul 06, 2020
Kayomn
Jul 06, 2020
Kayomn
Jul 06, 2020
kinke
Jul 06, 2020
Kayomn
Jul 07, 2020
kinke
July 06, 2020
Something discovered in the D Language Code Club Discord server with the help of Wild is that the following code:

struct Test { ~this() {} }
void tester(Test test, Test[] tests...) { }

extern(C) void main() {
    tester(Test(), Test());
}

Raises the "TypeInfo cannot be used with ~betterC" error. It seems to be due to an inclusion of both the destructor and the non-vararg and vararg argument matching from testing.

Anyone know a way around this without resulting to the rather hacky solution of just having 1 argument and always assuming that at least 1 argument is present?

Here is a code demo setup for demonstrating the potential problem:
https://run.dlang.io/is/A6oIpl
July 06, 2020
On Monday, 6 July 2020 at 20:06:51 UTC, Kayomn wrote:
> Something discovered in the D Language Code Club Discord server with the help of Wild is that the following code:
>
> struct Test { ~this() {} }
> void tester(Test test, Test[] tests...) { }
>
> extern(C) void main() {
>     tester(Test(), Test());
> }
>
> Raises the "TypeInfo cannot be used with ~betterC" error. It seems to be due to an inclusion of both the destructor and the non-vararg and vararg argument matching from testing.
>
> Anyone know a way around this without resulting to the rather hacky solution of just having 1 argument and always assuming that at least 1 argument is present?
>
> Here is a code demo setup for demonstrating the potential problem:
> https://run.dlang.io/is/A6oIpl

This seems to compile:

struct Test { ~this() {} }
void tester(size_t n)(Test[n] tests...)
if (n > 0)
{}

extern(C) void main() {
    tester(Test(), Test());
}

No assumptions, though `tester` does become a template.

I'd say the original error should be reported on bugzilla, if it isn't already; if only for the error message which is ridiculously obscure.
July 06, 2020
On Monday, 6 July 2020 at 20:20:44 UTC, Stanislav Blinov wrote:
> I'd say the original error should be reported on bugzilla, if it isn't already; if only for the error message which is ridiculously obscure.

Yeah, you're tellin' me lol. I spent the better part of the day tracking this one down, and the error file and line numbers display it as having occured at the callsite rather than the actual problem areas.

Though, admittedly I'm kind of used to seeing this error message since it appears any time you try and do something that relies on type info in betterC, intentionally or not. A notable example is forgetting to supply an arrange length when declaring a stack array, or it'll try to create a runtime-allocated array.

I'll open a report for this shortly if it is a bug if there isn't one already. For now, that template is an adequate workaround.
July 06, 2020
On Monday, 6 July 2020 at 20:25:11 UTC, Kayomn wrote:
> example is forgetting to supply an arrange length when

array length*
July 06, 2020
On Monday, 6 July 2020 at 20:25:11 UTC, Kayomn wrote:
> Though, admittedly I'm kind of used to seeing this error message since it appears any time you try and do something that relies on type info in betterC, intentionally or not. A notable example is forgetting to supply an arrange length when declaring a stack array, or it'll try to create a runtime-allocated array.

Similar case here; the 'varargs' end up in a GC-allocated array. I've recently changed `scope` slice params, so that array literal arguments are allocated on the caller's stack instead; so adding `scope` for these variadics *should* probably do the same:

void tester(Test test, scope Test[] tests...);
July 06, 2020
On Monday, 6 July 2020 at 21:09:57 UTC, kinke wrote:
> Similar case here; the 'varargs' end up in a GC-allocated array. I've recently changed `scope` slice params, so that array literal arguments are allocated on the caller's stack instead; so adding `scope` for these variadics *should* probably do the same:
>
> void tester(Test test, scope Test[] tests...);

This doesn't seem to be the case as the issue persists in the same manner.
https://run.dlang.io/is/LcaKeu
July 07, 2020
On Monday, 6 July 2020 at 22:02:37 UTC, Kayomn wrote:
> On Monday, 6 July 2020 at 21:09:57 UTC, kinke wrote:
>> Similar case here; the 'varargs' end up in a GC-allocated array. I've recently changed `scope` slice params, so that array literal arguments are allocated on the caller's stack instead; so adding `scope` for these variadics *should* probably do the same:
>>
>> void tester(Test test, scope Test[] tests...);
>
> This doesn't seem to be the case as the issue persists in the same manner.
> https://run.dlang.io/is/LcaKeu

I meant 'should' as in 'should be fixed to do the same', as this works with -betterC:

struct Test { ~this() {} }
void tester(Test test, scope Test[] tests) { }

extern(C) void main() {
    tester(Test(), [Test()]);
}
July 07, 2020
On 7/6/20 5:09 PM, kinke wrote:
> On Monday, 6 July 2020 at 20:25:11 UTC, Kayomn wrote:
>> Though, admittedly I'm kind of used to seeing this error message since it appears any time you try and do something that relies on type info in betterC, intentionally or not. A notable example is forgetting to supply an arrange length when declaring a stack array, or it'll try to create a runtime-allocated array.
> 
> Similar case here; the 'varargs' end up in a GC-allocated array. I've recently changed `scope` slice params, so that array literal arguments are allocated on the caller's stack instead; so adding `scope` for these variadics *should* probably do the same:
> 
> void tester(Test test, scope Test[] tests...);

Note that without the initial parameter, or without the destructor, they do NOT end up on the heap.

I think this is a bug, and not a "feature". I can't see any reason why in those two cases it can construct it on the stack, and in this case it cannot.

Note that I was under the impression that a Typesafe Variadic would always be on the stack. Reading the spec, it says it "may" put it on the stack, which makes me like those types of functions a lot less. Is there any reason a Typesafe Variadic function called with individual values cannot be required to put the values on the stack?

-Steve
July 07, 2020
On 7/7/20 8:26 AM, Steven Schveighoffer wrote:
> On 7/6/20 5:09 PM, kinke wrote:
>> On Monday, 6 July 2020 at 20:25:11 UTC, Kayomn wrote:
>>> Though, admittedly I'm kind of used to seeing this error message since it appears any time you try and do something that relies on type info in betterC, intentionally or not. A notable example is forgetting to supply an arrange length when declaring a stack array, or it'll try to create a runtime-allocated array.
>>
>> Similar case here; the 'varargs' end up in a GC-allocated array. I've recently changed `scope` slice params, so that array literal arguments are allocated on the caller's stack instead; so adding `scope` for these variadics *should* probably do the same:
>>
>> void tester(Test test, scope Test[] tests...);
> 
> Note that without the initial parameter, or without the destructor, they do NOT end up on the heap.
> 
> I think this is a bug, and not a "feature". I can't see any reason why in those two cases it can construct it on the stack, and in this case it cannot.

I should clarify:
1. Removing the destructor, but leaving the initial parameter => stack allocated
2. Removing the initial parameter, but leaving the destructor => stack allocated

This is why I think it's at least inconsistent. A bug might be too far, since the spec clearly gives leeway to implementations to allocate on the heap.

But I would love to see the spec changed to require stack allocation.

-Steve