September 02, 2016
On Friday, 2 September 2016 at 21:16:02 UTC, Walter Bright wrote:
> assert()s are there to check that impossible situations in the compiler don't actually happen. They are not for diagnosing errors in user code.

There are three things that will ideally happen when someone sees an assert:

* They'll submit a bug report to bugzilla.
* They'll come up with a reasonably simple test case to add to the bug report.
* They'll find an immediate workaround for their code so they can get on with their life and not have to wait until the next compiler release.

The second and third would be greatly benefitted by the compiler attempting to tell us where the problem was encountered. For instance, if the assert was triggered while trying to generate code for function dmud.eventqueue.EventQueue!(Fiber).scheduleNear, I would know to look first and foremost at that function.

Yes, if I'm rebuilding my code often, I'll be able to narrow things down automatically, but I'm not as virtuous as I would like. And with templates, things get harder.
September 02, 2016
On 9/2/2016 2:54 PM, Chris Wright wrote:
> The second and third would be greatly benefitted by the compiler attempting to
> tell us where the problem was encountered. For instance, if the assert was
> triggered while trying to generate code for function
> dmud.eventqueue.EventQueue!(Fiber).scheduleNear, I would know to look first and
> foremost at that function.

Compiling with -v will usually show how far the compiler got.

September 02, 2016
On Fri, Sep 02, 2016 at 02:52:57PM -0700, Walter Bright via Digitalmars-d wrote: [...]
> I understand your concern, and that's why we put a priority on fixing asserts that are submitted to bugzilla. But without a bug report, we are completely dead in the water in fixing it. It is supposed to never happen, that is why we cannot fix them in advance.

What *would* help greatly is if, upon encountering an unexpected problem, the compiler told the user something to the effect of "hey there, I'm really sorry but apparently I've run into a problem I don't know how to solve; could you please file a bug report at $URL so that the compiler authors look into the problem?"  Instead of blurting out something in encrypted Klingon that nobody understands, like "backend/gjqzx.c 12345 phlebotinum overload".

OK, I exaggerate, but seriously, to anyone unfamiliar with compiler internals, dmd asserts might as well be talking about phlebotinum overloads and they couldn't tell the difference.  If the error message isn't being helpful, the chances of a bug report being filed are pretty low, which means the chances of the problem getting fixed is even lower.

I think this PR would go a long way at making dmd friendlier to new D users, if we can figure out how to make it work for all asserts including from C code:

	https://github.com/dlang/dmd/pull/6103


> Using dustmite is a practical way to reduce the source code to a manageable size.

A user wouldn't even know what dustmite is, let alone that it exists and is applicable to this situation, or where to find it and how to use it, unless they were told. Preferably by the compiler before it terminates with an assert error. ;-)


> Having a compiler stack trace or it dumping its internal variables is unlikely to help anyone but the compiler devs.
[...]

Stack traces or internal variable dumps are equally unhelpful as the current phlebotinum overload abort messages.  What we need is for the compiler to tell the user (1) this is a compiler bug, not some fault in their own code; (2) where to report this bug so that there's actually a chance the problem will get fixed; (3) what is dustmite, where to find it, and how it would help in formulating a bug report. And optionally, (4) where to go to ask for help if you really need to find some way to work around a compiler bug and get your code working again (e.g., forum.dlang.org).

If I were to run some random program downloaded off the 'net and it came back to me with:

	phlebo/tinum.c 12345 zyxqwqyb error

with no information about (1), (2), or (3), chances are pretty high that I would just delete the program and move on to something else. I wouldn't bother spending the effort to find out where to file bug reports, and the problem will likely go unfixed and it will continue to turn off yet more would-be users.

We need to get PR 6103 off the ground.


T

-- 
Let's eat some disquits while we format the biskettes.
September 02, 2016
On Friday, 2 September 2016 at 22:12:20 UTC, Walter Bright wrote:
> Compiling with -v will usually show how far the compiler got.

It's curious that this topic should come up now – just a couple of days ago, I thought about adding better user reporting for LDC ICEs.

What I was planning to do is to keep a global stack of locations (and symbols where applicable, to be able to print the name) that is updated as the AST is traversed during semantic and glue layer. This should be very cheap to do, especially since the information does not need to be perfect.

You can then install a custom assert/segfault handler to print that information to aid users in reducing a test case or working around the problem, even for hard crashes or ICEs. The location information needs to be just close enough that the user knows where to start looking if the error appears after a compiler upgrade or when writing template-heavy code.

 — David
September 03, 2016
On Friday, 2 September 2016 at 21:52:57 UTC, Walter Bright wrote:
> I understand your concern, and that's why we put a priority on fixing asserts that are submitted to bugzilla. But without a bug report, we are completely dead in the water in fixing it. It is supposed to never happen, that is why we cannot fix them in advance.

We have a rule in our codebase, and it's been the same in every codebase I've worked in professionally. If you throw an assert, you have to give a reason and useful information in the assert.

Thus, an error in code that looks like:

assert(0);

Makes no sense to me when in this case it could have been:

fatal_error("Invalid type (from %d to %s)", tx->ty, tx->toChars());

The quality of error reporting has immediately increased. And it would require the creation of a fatal_error macro that does an assert. But now I'm not scratching my head wondering what went wrong in the compiler.

Browsing through that function, I can also see another assert that doesn't let you use vector types unless you're running a 64-bit build or are on OSX. It doesn't tell me that through an error message. I had to look at the source code to work it out. fatal_error("Vector types unavailable on the target platform"); and someone's day was made better. And then a couple of lines above that, another assert(0). fatal_error("Invalid vector type %s", tx->toChars()); and someone can deal with the unexpected.

If I have to open up the compiler's source to get an idea of what I'm doing wrong, that's a bad user experience. And why I want a discussion about this. Not to whinge, not to get a bug fix. But to highlight that assert(0) is a bad pattern and there should be a discussion about changing the usage of asserts inside DMD.
September 03, 2016
On 9/3/2016 3:57 AM, Ethan Watson wrote:
> Browsing through that function, I can also see another assert that doesn't let
> you use vector types unless you're running a 64-bit build or are on OSX. It
> doesn't tell me that through an error message. I had to look at the source code
> to work it out. fatal_error("Vector types unavailable on the target platform");
> and someone's day was made better. And then a couple of lines above that,
> another assert(0). fatal_error("Invalid vector type %s", tx->toChars()); and
> someone can deal with the unexpected.

This appears to conflate diagnosing errors in the user's source code with detecting bugs in the compiler. A user source code error should have been diagnosed long before those asserts are hit (and if not, it's a compiler bug, by definition, not a user source code problem).


> If I have to open up the compiler's source to get an idea of what I'm doing
> wrong, that's a bad user experience. And why I want a discussion about this. Not
> to whinge, not to get a bug fix. But to highlight that assert(0) is a bad
> pattern and there should be a discussion about changing the usage of asserts
> inside DMD.

Except that asserts are checking for compiler bugs, not diagnostics on user code. I don't expect users to debug the compiler - if they get an assert they should file a bug report to bugzilla and let us debug the compiler and fix it.

----

Aside: we regularly have threads here where the difference between detecting programming bugs and detecting input errors is discussed. I fear another one is gathering steam, and if so, I'll likely not participate in it.
September 03, 2016
On 2016-09-03 14:12, Walter Bright wrote:

> Except that asserts are checking for compiler bugs, not diagnostics on
> user code. I don't expect users to debug the compiler - if they get an
> assert they should file a bug report to bugzilla and let us debug the
> compiler and fix it.

What kind of issue due you see with trying to print some form of information when an assertion fails? I would have certainty help me the times I've hacked on the compiler and triggered an assertion. Why shouldn't the developers working on the compiler getting as much help as possible?

-- 
/Jacob Carlborg
September 03, 2016
On Saturday, 3 September 2016 at 12:12:34 UTC, Walter Bright wrote:
> Except that asserts are checking for compiler bugs, not diagnostics on user code.

Except that in the real world, it is an irrelevant distinction because you have stuff to do and can't afford to wait on the compiler team to actually fix the bug.

If nothing else, you'd like to know where it is so you can hack around the bug by changing your implementation. I'm sure every long time D programmer (and likely C++ if you've been in a long time, I have hit many bugs in g++ too) has hit a compiler bug and "fixed" it by using some different approach in their user code.


I understand if you want to say producing better error messages in the compiler is a pain and you have other priorities, but surely you accept that they are valuable for this reason if nothing else.
September 03, 2016
On Saturday, 3 September 2016 at 13:20:37 UTC, Adam D. Ruppe wrote:
> Except that in the real world, it is an irrelevant distinction because you have stuff to do and can't afford to wait on the compiler team to actually fix the bug.
>
> If nothing else, you'd like to know where it is so you can hack around the bug by changing your implementation. I'm sure every long time D programmer (and likely C++ if you've been in a long time, I have hit many bugs in g++ too) has hit a compiler bug and "fixed" it by using some different approach in their user code.

Exactly this. If a compiler bug stops someone from working in a production environment because there's no information about why the bug occured, the semantic difference between a compiler bug and a user code bug means precisely nothing to the end user. It does mean that they're losing hours of work while the problem is clumsily attempted to be diagnosed.

In the cases I've been bringing up here, it's all been user code that's been the problem *anyway*. Regardless of if the compiler author was expecting code to get to that point or not, erroring out with zero information is a bad user experience.

This also gets compounded in environments where you can't just grab the hottest DMD with a compiler bug fix. Before too long, our level builders will be using D as their scripting language. They need a stable base. We can't do something like upgrade a compiler during a milestone week, so upgrades will be scheduled (I'm planning on going with even-numbered releases). A fix for the compiler bug is no good if I can't ship it out for months. The only way to go there is to implement workarounds until such time an upgrade is feasible.

(Side note: There's zero chance of me upgrading to the next DMD if it retains the altered allMembers functionality)

These kinds of problems are likely to be compounded when D reaches critical mass. It's all well and good to tell people in the enthusiast community "Run <x> to get a repro case and make a bug". If a problem can't be easily googlable or understandable from the error reporting, then that's a turn off for a wider audience.
September 03, 2016
On 9/3/2016 6:14 AM, Jacob Carlborg wrote:
> What kind of issue due you see with trying to print some form of information
> when an assertion fails?

Because it's useless to anyone but the compiler devs, and it adds cruft to the compiler. And even worse than useless, it confuses the user into thinking it is a meaningful message.

It is not. It is a compiler bug. It has meaning only to the compiler developer, and hence does not belong in the *user* interface. Let's not pretend the user can debug the compiler.


> I would have certainty help me the times I've hacked on
> the compiler and triggered an assertion. Why shouldn't the developers working on
> the compiler getting as much help as possible?

The compiler code is littered with helpful debugging printf's that are commented out. I use them all the time. There is no purpose to them if one is not actively working on the compiler.