Bug 8577 – static assert is triggered after tuple bounds check
Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-08-21T13:17:04Z
Last change time
2022-09-08T08:49:13Z
Assigned to
No Owner
Creator
Ellery Newcomer
Comments
Comment #0 by ellery-newcomer — 2012-08-21T13:17:04Z
I find it very annoying that the following code results in a tuple out of bounds error message and not only the static assert message.
template T(Ts...) {
static assert(Ts.length > 1);
alias Ts[1] Z;
}
void main() {
alias T!(int).Z Z2;
}
gives
wiz.d(4): Error: tuple index 1 exceeds 1
wiz.d(3): Error: static assert (1LU > 1LU) is false
wiz.d(8): instantiated from here: T!(int)
I think error reporting should stop at the static assert.
Comment #1 by hsteoh — 2014-08-29T15:04:34Z
Workarounds:
1)
-----
template T(Ts...)
if (Ts.length > 1)
{
alias Ts[1] Z;
}
-----
2)
-----
template T(Ts...)
{
static if (Ts.length > 1)
alias Ts[1] Z;
else
static assert(0);
}
-----
Comment #2 by razvan.nitu1305 — 2022-09-08T08:49:13Z
Today, the code yields:
onlineapp.d(2): Error: tuple index 1 exceeds 1
onlineapp.d(7): Error: template instance `onlineapp.T!int` error instantiating
And I am arguing that this is the correct behavior. The static assert is generally used to test that things inside the template instantiation are correct.
Template constraints are used to check that the template arguments are correct.
The static assert cannot be evaluated before the template is instantiated because that will make it useless in 99% of the cases. The general case for static asserts in template declarations is to check that specific template properties are correct, therefore, you first need to have the instantiation before you actually evaluate the static assert.
In conclusion: use template constraints for this scenario:
template T(Ts...)
if (Ts.length > 1)
{
alias Ts[1] Z;
}
Closing as invalid.