Thread overview
[Issue 16665] static assert is only checked after the following dependent type declaration
Jan 04, 2020
Mathias LANG
Jan 04, 2020
Basile-z
Jan 05, 2020
Mathias LANG
Mar 21, 2020
Basile-z
Dec 17, 2022
Iain Buclaw
Nov 12
Manu
Nov 12
Manu
Nov 12
Dennis
Nov 12
Manu
Nov 12
Dennis
January 04, 2020
https://issues.dlang.org/show_bug.cgi?id=16665

Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pro.mathias.lang@gmail.com

--- Comment #1 from Mathias LANG <pro.mathias.lang@gmail.com> ---
Just hit this bug, but straight in Druntime.

Test case:
```
version (NonExistent)
{
    alias FILE = void*;
}
else
    static assert("Unsupported platform");

FILE getSomething();
```

This will output "test.d(8): Error: undefined identifier FILE" with a recent
compiler.
This is a common pattern for platform support. I'm not sure we could guarantee
the order of evaluation here, but if we don't, we need to go through our libs
and provide dummy declarations.

--
January 04, 2020
https://issues.dlang.org/show_bug.cgi?id=16665

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |b2.temp@gmx.com

--- Comment #2 from Basile-z <b2.temp@gmx.com> ---
Yes but you indirectly assert the .length property of the message. If you

   static assert(0, "Unsupported platform");

Then the static assert is displayed at least. Maybe it was just a typo ?

--
January 05, 2020
https://issues.dlang.org/show_bug.cgi?id=16665

--- Comment #3 from Mathias LANG <pro.mathias.lang@gmail.com> ---
Right, it was a typo.

The case I encountered though, was triggered inside of druntime because the C
runtime I was targeting did not have a definition for 'FILE'.
As a result, the compiler hit a limit in the number of error (apparently 20).

Correct test case:
```
version (NonExistent)
{
    alias FILE = void*;
}
else
    static assert(0, "Unsupported platform");

FILE getSomething1();
FILE getSomething2();
FILE getSomething3();
FILE getSomething4();
FILE getSomething5();
FILE getSomething6();
FILE getSomething7();
FILE getSomething8();
FILE getSomething9();
FILE getSomething10();
FILE getSomething11();
FILE getSomething12();
FILE getSomething13();
FILE getSomething14();
FILE getSomething15();
FILE getSomething16();
FILE getSomething17();
FILE getSomething18();
FILE getSomething19();
FILE getSomething20();
```

This does not display the assert. Commenting one of the function does.

--
March 21, 2020
https://issues.dlang.org/show_bug.cgi?id=16665

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|b2.temp@gmx.com             |

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=16665

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P3

--
November 12
https://issues.dlang.org/show_bug.cgi?id=16665

Manu <turkeyman@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |turkeyman@gmail.com
           Severity|normal                      |major

--- Comment #4 from Manu <turkeyman@gmail.com> ---
druntime and phobos are riddled with this issue!

static assert needs to tell you the error it's checking for _before_ the errors relating to the symptoms of the error it's checking for, otherwise it's useless.

In druntime, all the cases like:

```
version (Posix)
    public import core.sys.posix.stdc.time;
else version (Windows)
    public import core.sys.windows.stdc.time;
else
    static assert(0, "unsupported system");

@system time_t  mktime(scope tm* timeptr);
```

1> time.d(37): error : undefined identifier `tm`

The static assert doesn't emit any error message at all!
It's difficult to imagine how the compiler could be certain that `tm` is not a
thing before it's able to resolve `assert(0)`. The version sequence can be
resolved immediately, and static assert(0) can be resolved immediately too...

This is actually a pretty serious bug; we can't write portable code if we can't expect top-level static assert's to inform us that symbols are missing or that a platform is not supported!

--
November 12
https://issues.dlang.org/show_bug.cgi?id=16665

Manu <turkeyman@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|major                       |critical

--- Comment #5 from Manu <turkeyman@gmail.com> ---
I got rid of everything, this is all that's left:

```
static assert(0, "unsupported system");

@system time_t  mktime(scope tm* timeptr);
```

No version's, no imports, nothing... even in this code, here's the compiler's output:

time.d(20): error : undefined identifier `tm`

Why did it complain about `tm` but not `time_t`?
Why did it completely ignore the static assert?

I'm raising the importance on this bug... it's actually severe.

--
November 12
https://issues.dlang.org/show_bug.cgi?id=16665

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dkorpel@live.nl

--- Comment #6 from Dennis <dkorpel@live.nl> ---
(In reply to Manu from comment #5)
> No version's, no imports, nothing... even in this code, here's the compiler's output:
> 
> time.d(20): error : undefined identifier `tm`

What compiler version are you using? I'm getting:

2.109
```
time.d(3): Error: undefined identifier `time_t`
time.d(3): Error: undefined identifier `tm`
time.d(1): Error: static assert:  "unsupported system"
```

2.110 (nightly):
```
time.d(1): Error: static assert:  "unsupported system"
```

--
November 12
https://issues.dlang.org/show_bug.cgi?id=16665

--- Comment #7 from Manu <turkeyman@gmail.com> ---
LDC 1.39.0 (DMD v2.109.1, LLVM 18.1.6)

--
November 12
https://issues.dlang.org/show_bug.cgi?id=16665

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|critical                    |normal

--- Comment #8 from Dennis <dkorpel@live.nl> ---
This will be fixed once dmd 2.110 and LDC 1.40 are released. The static assert(0, "unsupported system") static asserts are short-circuited as of the fix for issue 24645. That also fixes Mathias' test case. The remaining issue is from OP:

```
alias AliasSeq(T...) = T;
alias tuple = AliasSeq!();
static assert(tuple.length == 2);
alias t0 = tuple[0];
```

The problem here is that `alias t0 = tuple[0]` is semantic1, while static assert is semantic2, as can be seen with the `-v` switch:

```
semantic  app
app.d(4): Error: sequence index `0` out of bounds `[0 .. 0]`
semantic2 app
app.d(3): Error: static assert:  `0LU == 2LU` is false
```

This could be fixed by evaluating static asserts in semantic1, but there probably was a reason to do it in semantic2, so I'm not sure.

--