D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 8577 - static assert is triggered after tuple bounds check
Summary: static assert is triggered after tuple bounds check
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-08-21 13:17 UTC by Ellery Newcomer
Modified: 2022-09-08 08:49 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Ellery Newcomer 2012-08-21 13:17:04 UTC
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 hsteoh 2014-08-29 15:04:34 UTC
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 RazvanN 2022-09-08 08:49:13 UTC
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.