It is, but there are limits to what it can do.
D's contracts potentially offer a lot of information that the optimiser wouldn't naturally have (any function receiving blind arguments can't make any assumptions without a contract present), but more from a usability/safety point of view, I really hate casting when the compiler should know the assignment is safe.

It's not only an inconvenience, it's also a safety thing.
Consider:
I have an int that I assign to a byte, I know the value fits in a byte, but I'm forced to type the manual cast anyway.
Once that cast is written, if the valid range of my int happens to change in outer code, I will not receive an error informing me that the new range doesn't fit within a byte anymore, it'll just truncate it anyway, since a blind cast is already there in the code.
It would be much better for the compiler to start complaining that it can no longer assure that the int fits into the byte. With the cast present, my bug has been hidden until I eventually crash.


On 13 May 2013 10:18, John Colvin <john.loughran.colvin@gmail.com> wrote:
On Monday, 13 May 2013 at 00:00:54 UTC, Manu wrote:
So, here's an issue that constantly drives me nuts, and an elegant solution
seems so do-able.

void func(int x)
{
  x &= 0xFFFF;
  short s = x; // Error! (but we know x is 0 .. 65535)

  if(x < 256)
  {
    byte b = x; // Error! (we also know x is 0 .. 255)
  }
}

It would be really nice if the compiler would carry around the known
possible range of values, and refer to that information when performing
down-casting assignments.
It would also be very useful information for the back end, it can choose
more efficient types if it knows the range, or produce jump tables rather
than branch sequences.

I think the compiler would need a min, max, and mask for any integers, and
update them as it works.

There are many sources of this information.
Comparisons effectively limit the range:
if(x > 0)
{
  // x = 0 .. int.max
}
else
{
  // x = int.min .. -1
}

Masks, obviously:
x &= 15;

Also contracts are a really great source of seeding this information on
function entry.

Has this been discussed? It seems simple, and it's invisible to the
language. It would just reduce some boilerplate (tedious casts), and also
offer some great optimisation opportunities.

I've been thinking about this for a while from an optimisation point of view. Is this not a common practice for an optimising compiler?