www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - This code completely breaks the compiler:

reply Ruby The Roobster <rubytheroobster yandex.com> writes:
This snippet compiles.  Even if `dsds` and `sadsad` are defined 
nowhere, this code compiles.

```d
import std.typecons : Tuple;

sadsad executeFunction(Mtypes...)(dstring func, Tuple!(Mtypes) 
args)
{
     static foreach(type; typel.keys)
     {
         mixin(typel[type] ~ " ret"d ~ type ~ ";");
     }

     dstring returnType = "Number"d;

     Switch: final switch(returnType)
     {
         static foreach(type; typel.keys)
         {
             case type:
                 mixin("alias ret = ret"d ~ type ~ ";");
                 break Switch;
         }
     }
     dsds ret;
     return ret;
}
```

The reason why this compiles is because of the varidic template 
parameter, `Mtypes`.

Either there is something I'm missing, or the compiler completely 
breaks when it sees varidic template arguments.
Aug 18 2022
parent reply Ruby The Roobster <rubytheroobster yandex.com> writes:
On Friday, 19 August 2022 at 03:10:38 UTC, Ruby The Roobster 
wrote:
 This snippet compiles.  Even if `dsds` and `sadsad` are defined 
 nowhere, this code compiles.

 [SNIP]

 The reason why this compiles is because of the varidic template 
 parameter, `Mtypes`.

 Either there is something I'm missing, or the compiler 
 completely breaks when it sees varidic template arguments.
The only way to get the code to not compile is to actually call the function.
Aug 18 2022
parent reply JG <someone simewhere.com> writes:
On Friday, 19 August 2022 at 03:13:03 UTC, Ruby The Roobster 
wrote:
 On Friday, 19 August 2022 at 03:10:38 UTC, Ruby The Roobster 
 wrote:
 This snippet compiles.  Even if `dsds` and `sadsad` are 
 defined nowhere, this code compiles.

 [SNIP]

 The reason why this compiles is because of the varidic 
 template parameter, `Mtypes`.

 Either there is something I'm missing, or the compiler 
 completely breaks when it sees varidic template arguments.
The only way to get the code to not compile is to actually call the function.
I think it might help to post the entire code you think should not compile (which does). I guess you are aware that templated code is only "fully checked" when it is instantiated. E.g. this will compile. ```d import std; auto nonsense(T)(T t) { return 5+"six"; } void main() { } ```
Aug 18 2022
parent reply Ruby The Roobster <rubytheroobster yandex.com> writes:
On Friday, 19 August 2022 at 04:16:28 UTC, JG wrote:
 On Friday, 19 August 2022 at 03:13:03 UTC, Ruby The Roobster 
 wrote:
 On Friday, 19 August 2022 at 03:10:38 UTC, Ruby The Roobster 
 wrote:
 This snippet compiles.  Even if `dsds` and `sadsad` are 
 defined nowhere, this code compiles.

 [SNIP]

 The reason why this compiles is because of the varidic 
 template parameter, `Mtypes`.

 Either there is something I'm missing, or the compiler 
 completely breaks when it sees varidic template arguments.
The only way to get the code to not compile is to actually call the function.
I think it might help to post the entire code you think should not compile (which does). I guess you are aware that templated code is only "fully checked" when it is instantiated. E.g. this will compile. ```d import std; auto nonsense(T)(T t) { return 5+"six"; } void main() { } ```
So that's why it compiled. Still, I believe that stuff like this ought to be detected at compile time, as supposed to in a unittest or, if someone forgot to write the tests, in production.
Aug 18 2022
parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 19 August 2022 at 04:25:25 UTC, Ruby The Roobster 
wrote:

 So that's why it compiled.  Still, I believe that stuff like 
 this ought to be detected at compile time, as supposed to in a 
 unittest or, if someone forgot to write the tests, in 
 production.
If the template is never instantiated, it never makes it into the executable. It doesn't matter if it's in production or not, and has nothing to do with tests. It doesn't exist. How could the compiler catch any problems if it has no idea what `Mtypes` is? This is true for any template parameter. Consider this: ```d import std.stdio; T derp(T)(T val) { val += 10; return val; } void main() { writeln("Hello D"); } ``` `derp` obviously isn't going to work with every type. But this code compiles because `derp` is never instantiated. The compiler can't check if the code in `derp` is valid because it has no idea what `T` might be. If it's `int`, then no problem. If it's `string` then no way: ```d void main() { writeln(derp!string("No way")); } ``` Now you'll get this: ``` onlineapp.d(4): Error: slice `val` is not mutable onlineapp.d(10): Error: template instance `onlineapp.derp!string` error instantiating ```
Aug 18 2022
parent Ruby The Roobster <rubytheroobster yandex.com> writes:
On Friday, 19 August 2022 at 05:50:17 UTC, Mike Parker wrote:
 On Friday, 19 August 2022 at 04:25:25 UTC, Ruby The Roobster 
 wrote:

 [...]
If the template is never instantiated, it never makes it into the executable. It doesn't matter if it's in production or not, and has nothing to do with tests. It doesn't exist. How could the compiler catch any problems if it has no idea what `Mtypes` is? This is true for any template parameter. Consider this: ```d import std.stdio; T derp(T)(T val) { val += 10; return val; } void main() { writeln("Hello D"); } ``` `derp` obviously isn't going to work with every type. But this code compiles because `derp` is never instantiated. The compiler can't check if the code in `derp` is valid because it has no idea what `T` might be. If it's `int`, then no problem. If it's `string` then no way: ```d void main() { writeln(derp!string("No way")); } ``` Now you'll get this: ``` onlineapp.d(4): Error: slice `val` is not mutable onlineapp.d(10): Error: template instance `onlineapp.derp!string` error instantiating ```
This makes sense. Still, in my code, where the function has the same return type regardless of instantiation, the compiler should at least check that expressions independent of the template parameter are valid.
Aug 19 2022