December 05, 2014
https://issues.dlang.org/show_bug.cgi?id=13775

--- Comment #11 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to Steven Schveighoffer from comment #10)
> OK, I understand. Is there a reason not to make this assert though?

To do it, we need to handle all invalid casts in front end layer.

> The impression it gives is confusing to many people, including myself and Denis.

A possible quick hack is removing "e2ir" from the glue-layer errors.

--
December 05, 2014
https://issues.dlang.org/show_bug.cgi?id=13775

--- Comment #12 from Steven Schveighoffer <schveiguy@yahoo.com> ---
(In reply to Kenji Hara from comment #11)
> (In reply to Steven Schveighoffer from comment #10)
> > OK, I understand. Is there a reason not to make this assert though?
> 
> To do it, we need to handle all invalid casts in front end layer.

I get that, and I get that the fact that it is seen in the glue layer is an internal error.

But on the surface, it just seems that the compiler is just rejecting (in some cases correctly) a cast. The confusing part is that the error message is telling you mainly that the cast is not correct, whether wrong or right -- the 'e2ir' message looks out of place.

In previous bug reports, things like cast(int)"" printed this message. The bug report was not to say that one expected this cast to work, but that "it looks like a stray 'e2ir' message is in there." But now, we know that the 'e2ir' is a clue that the internal error exists. The end result of "fixing" it is that it's now handled in the front end, but to the user, it just looks like 'e2ir' is removed (the error message is identical otherwise).

> > The impression it gives is confusing to many people, including myself and Denis.
> 
> A possible quick hack is removing "e2ir" from the glue-layer errors.

I don't want this, because then it doesn't get reported and fixed for cast rejections that *should* be rejected, but aren't handled in the right layer. It just looks like a normal error and goes unreported.

What I wanted is for the error to say "ICE, please fix me," instead of giving the impression it's simply a normal error.

In other words the 'e2ir' looks more like a typo than a real error message. Just make it a proper ICE, and you will get proper reports.

--
December 06, 2014
https://issues.dlang.org/show_bug.cgi?id=13775

--- Comment #13 from github-bugzilla@puremagic.com ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/0b77f0d79c2c7f5949804483221c3f47d2bbf101
fix Issue 13775 - Broken explicit casting of dynamic array slices of known size
to static array of different type

Support reinterpret-cast from a CT-known boundaries slice expression that can be implicitly typed as `T[n]` to another static array type `U[m]`, iff their sizes are same (`T[n].sizeof == U[m].sizeof`).

https://github.com/D-Programming-Language/dmd/commit/0a92f21363f8fd24ef3bd293673219597d17338b Merge pull request #4193 from 9rnsr/fix13775

[REG2.067a] Issue 13775 - Broken explicit casting of dynamic array slices of known size to static array of different type

--
February 12, 2015
https://issues.dlang.org/show_bug.cgi?id=13775

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
                 CC|                            |pro.mathias.lang@gmail.com
         Resolution|FIXED                       |---

--- Comment #14 from Mathias LANG <pro.mathias.lang@gmail.com> ---
Vibe.d is suffering from it as well:
----
case AF_INET6:
    ubyte[16] ip = addr_ip6.sin6_addr.s6_addr;
    auto ret = appender!string();
    ret.reserve(40);
    foreach (i; 0 .. 8) {
    if (i > 0) ret.put(':');
        ret.formattedWrite("%x", bigEndianToNative!ushort(cast(ubyte[2])ip[i*2
.. i*2+2]));
    }
    return ret.data;
----

However this code still fails with a recent compiler:

source/vibe/core/net.d(181): Error: cannot cast expression ip[cast(ulong)(i *
2)..cast(ulong)(i * 2 + 2)] of type ubyte[] to ubyte[2]

Tested with "v2.067-devel-932e0a5" (From today, Feb 12).

--
February 12, 2015
https://issues.dlang.org/show_bug.cgi?id=13775

sinkuupump@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |sinkuupump@gmail.com

--- Comment #15 from sinkuupump@gmail.com ---
(In reply to Mathias LANG from comment #14)
> Vibe.d is suffering from it as well:
> ----
> case AF_INET6:
>     ubyte[16] ip = addr_ip6.sin6_addr.s6_addr;
>     auto ret = appender!string();
>     ret.reserve(40);
>     foreach (i; 0 .. 8) {
> 	if (i > 0) ret.put(':');
> 		ret.formattedWrite("%x", bigEndianToNative!ushort(cast(ubyte[2])ip[i*2 ..
> i*2+2]));
>     }
>     return ret.data;
> ----
> 
> However this code still fails with a recent compiler:
> 
> source/vibe/core/net.d(181): Error: cannot cast expression ip[cast(ulong)(i
> * 2)..cast(ulong)(i * 2 + 2)] of type ubyte[] to ubyte[2]
> 
> Tested with "v2.067-devel-932e0a5" (From today, Feb 12).

See also Issue 13700, which covers the case.

--
February 12, 2015
https://issues.dlang.org/show_bug.cgi?id=13775

Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #16 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to sinkuupump from comment #15)
> (In reply to Mathias LANG from comment #14)
> > However this code still fails with a recent compiler:
> > 
> > source/vibe/core/net.d(181): Error: cannot cast expression ip[cast(ulong)(i
> > * 2)..cast(ulong)(i * 2 + 2)] of type ubyte[] to ubyte[2]
> > 
> > Tested with "v2.067-devel-932e0a5" (From today, Feb 12).
> 
> See also Issue 13700, which covers the case.

Yes, it's an enhancement case.

--
February 12, 2015
https://issues.dlang.org/show_bug.cgi?id=13775

Martin Nowak <code@dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code@dawg.eu

--- Comment #17 from Martin Nowak <code@dawg.eu> ---
(In reply to Kenji Hara from comment #16)
> > See also Issue 13700, which covers the case.
> 
> Yes, it's an enhancement case.

No, it's an explicit cast and it used to compile in 2.066.1.

cast(ubyte[2])ip[i*2 .. i*2+2])

--
February 12, 2015
https://issues.dlang.org/show_bug.cgi?id=13775

--- Comment #18 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to Martin Nowak from comment #17)
> (In reply to Kenji Hara from comment #16)
> > > See also Issue 13700, which covers the case.
> > 
> > Yes, it's an enhancement case.
> 
> No, it's an explicit cast and it used to compile in 2.066.1.
> 
> cast(ubyte[2])ip[i*2 .. i*2+2])

Read my comment #9. It was *accidentally* accepted in 2.066.1. In git head, casting T[] to T[n] is generally disallowed (glue layer does not support such cast operation), and it will be accepted only when the slice bounds are known at CT. Enhancement 1700 will extend the CT bounds detection, but it's not yet accepted.

--
February 15, 2015
https://issues.dlang.org/show_bug.cgi?id=13775

Martin Nowak <code@dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |---

--- Comment #19 from Martin Nowak <code@dawg.eu> ---
(In reply to Kenji Hara from comment #18)
> Read my comment #9. It was *accidentally* accepted in 2.066.1.

This code used to work even with 2.065.
Maybe the difference here is that it's a slice of a static array?

void bar(ubyte[2] v)
{
}

void foo(ubyte[16] ip)
{
    foreach (i; 0 .. 8)
        bar(cast(ubyte[2])ip[i*2 .. i*2+2]);
}

--
February 16, 2015
https://issues.dlang.org/show_bug.cgi?id=13775

Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #20 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to Martin Nowak from comment #19)
> (In reply to Kenji Hara from comment #18)
> > Read my comment #9. It was *accidentally* accepted in 2.066.1.
> 
> This code used to work even with 2.065.
> Maybe the difference here is that it's a slice of a static array?
> 
> void bar(ubyte[2] v)
> {
> }
> 
> void foo(ubyte[16] ip)
> {
>     foreach (i; 0 .. 8)
>         bar(cast(ubyte[2])ip[i*2 .. i*2+2]);
> }

No, it's same. Issue 3652 has been implemented since 2.063, so the accepts-invalid bug was also introduced from 2.063.

With 2.062, the code reports e2ir error.

test.d(8): Error: e2ir: cannot cast ip[cast(uint)(i * 2)..cast(uint)(i * 2 +
2)] of type ubyte[] to type ubyte[2u]
Internal error: e2ir.c 85

In 2.067a, it has been fixed back to an invalid cast.
As a note, currently most of check code for the invalid casts has been moved
into front-end layer. So the reported error message is a little different.

test.d(8): Error: cannot cast expression ip[cast(uint)(i * 2)..cast(uint)(i * 2
+ 2)] of type ubyte[] to ubyte[2]

--