digitalmars.D - My late christmas present for you: context-aware assertion error
- Seb (65/67) Jan 12 2019 tl;dr: I was annoyed for years that D's assert are so non
- Andre Pany (6/13) Jan 12 2019 Thanks for this great features. 2019 will be again a very great
- H. S. Teoh (11/37) Jan 12 2019 Awesome!
- Seb (7/10) Jan 12 2019 Yes, I hope so!
- H. S. Teoh (8/22) Jan 12 2019 [...]
- Seb (8/13) Jan 12 2019 It probably would be -verrors=json (or sth. like this), but the
- WebFreak001 (5/21) Jan 14 2019 I would be happy to change code-d and tools to any other format
- viniarck (4/11) Jan 12 2019 Epic! That's massively useful. I Such a great start for D in 2019
- viniarck (3/15) Jan 12 2019 My bad for the typo. I meant to type "It's such a great start for
- Dennis (6/7) Jan 12 2019 Amazing. I saw the PR a while back and was afraid it would be
- Meta (13/81) Jan 12 2019 Thank you so much for working on this. There's nothing more
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (5/11) Jan 13 2019 Wonderful!
- Seb (6/8) Jan 13 2019 Yes of course ;-) (and it was one of the main inspirations for
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (4/6) Jan 13 2019 Is there a way to download a dmd nightly and try this out?
- Seb (14/20) Jan 13 2019 e.g. https://run.dlang.io/is/GMfe9S for playing online with it.
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (2/12) Jan 13 2019 Thanks!
- Vladimir Panteleev (2/6) Jan 13 2019 Awesome, thank you! This should be great for debug builds.
- Atila Neves (9/16) Jan 14 2019 Awesome.
- Seb (14/31) Jan 14 2019 Should be easy enough:
- Andrei Alexandrescu (2/21) Jan 14 2019 Wonderful. Thanks!
- Steven Schveighoffer (4/13) Jan 14 2019 Just want to add in my +1. Thanks!
- Kagamin (4/9) Jan 15 2019 But 1!=2 is true :)
- Seb (5/14) Jan 15 2019 Hmm you have a point there. How do other people feel about this?
- Kagamin (5/8) Jan 15 2019 I remember Adam wanted the asserted expression to be printed as
- rjframe (12/29) Jan 15 2019 I think I'd agree with Kagamin - after the first time you'd know it, but...
- Jacob Carlborg (5/6) Jan 15 2019 I think the message should look as similar as the expression in the code...
- Kagamin (4/4) Jan 15 2019 And what happens to other expressions?
- Seb (13/17) Jan 15 2019 https://run.dlang.io/is/mRQM02
tl;dr: I was annoyed for years that D's assert are so non informative AssertError, so here's my late Christmas present for the D community. With 2.085 DMD will gain an experimental flag for more informative assertion errors. Feedback on this experimental feature is welcome, s.t. we eventually can enable it by default. Example: --- void main() { int a = 1, b = 2; assert(a == b); // ERROR: 1 != 2 } --- ```dmd -run onlineapp.dcore.exception.AssertError onlineapp.d(4): 1 != 2 ---------------- ??:? _d_assert_msg [0xb150e350] ??:? _Dmain [0xb150d627] ``` Play online: https://run.dlang.io/is/GMfe9S Full changelog: https://dlang.org/changelog/pending.html#assert Where to start hacking: - https://github.com/dlang/dmd/blob/00299e3b6ca9dcd5a5dc8bd50280b63d0bdc51f9/src/dmd/expressionsem.d#L5559 - https://github.com/dlang/druntime/blob/master/src/core/internal/dassert.d - https://github.com/dlang/dmd/pull/8517 Q: Why not just introduce an `assertEqual` user function? A: - there's a lot of already written D code out there that uses `assert` [1] - `assertEqual` wouldn't cut, it because then we would need to have an `assertLessThan` etc. too Q: Why put this in the compiler and not in fluent-assert or similar library? A: - there's a lot of already written D code out there that uses `assert` [1] - not everyone wants to use a library just to have somewhat decent assert messages - libraries can only do sth. like `testedValue.should.equal(42)`, but the compiler can deal with `testedValue == 42` [1] https://github.com/search?l=D&q=assert&type=Code Error context ------------- Also note that with 2.085 DMD will get -verrors=context --- void foo() { a = 1; } --- ```dmd -verrors=context onlineapp.donlineapp.d(3): Error: undefined identifier a a = 1; ^ ``` Full changelog: https://dlang.org/changelog/pending.html#error-context Play online: https://run.dlang.io/is/8gsye1 Thanks to all the people (Jacob Carlborg, Petar Kirov, Nicolas Wilson, Rainer Schuetze, etc.) who helped me to get this feature into DMD! Merry Christmas!
Jan 12 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote: ...Full changelog: https://dlang.org/changelog/pending.html#error-context Play online: https://run.dlang.io/is/8gsye1 Thanks to all the people (Jacob Carlborg, Petar Kirov, Nicolas Wilson, Rainer Schuetze, etc.) who helped me to get this feature into DMD! Merry Christmas!Thanks for this great features. 2019 will be again a very great year for D! Kind regards Andre
Jan 12 2019
On Sat, Jan 12, 2019 at 03:34:02PM +0000, Seb via Digitalmars-d wrote: [...]--- void main() { int a = 1, b = 2; assert(a == b); // ERROR: 1 != 2 } --- ```Awesome! [...]dmd -run onlineapp.dcore.exception.AssertError onlineapp.d(4): 1 != 2Also note that with 2.085 DMD will get -verrors=context[...]--- void foo() { a = 1; } --- ```Awesome! It's about time dmd error messages got a facelift. Will -verrors=context eventually become the default? T -- The irony is that Bill Gates claims to be making a stable operating system and Linus Torvalds claims to be trying to take over the world. -- Anonymousdmd -verrors=context onlineapp.donlineapp.d(3): Error: undefined identifier a a = 1; ^ ```
Jan 12 2019
On Saturday, 12 January 2019 at 16:17:07 UTC, H. S. Teoh wrote:Awesome! It's about time dmd error messages got a facelift. Will -verrors=context eventually become the default?Yes, I hope so! Once it has gotten a fair bit of real-world feedback and testing (which is the one of the reasons why I opened this thread) we can enable it by default if a TTY is detected. TTY detection is probably necessary as there are still a lot of programs (especially editor plugins) which parse the DMD output.
Jan 12 2019
On Sat, Jan 12, 2019 at 04:23:53PM +0000, Seb via Digitalmars-d wrote:On Saturday, 12 January 2019 at 16:17:07 UTC, H. S. Teoh wrote:[...] Seriously, for editor/IDE plugins, there should be a --porcelain option that outputs error messages in a machine-friendly format, like with a fixed format that's easy for scripts / code / whatever to parse. T -- Life is too short to run proprietary software. -- Bdale GarbeeAwesome! It's about time dmd error messages got a facelift. Will -verrors=context eventually become the default?Yes, I hope so! Once it has gotten a fair bit of real-world feedback and testing (which is the one of the reasons why I opened this thread) we can enable it by default if a TTY is detected. TTY detection is probably necessary as there are still a lot of programs (especially editor plugins) which parse the DMD output.
Jan 12 2019
On Saturday, 12 January 2019 at 16:32:43 UTC, H. S. Teoh wrote:Seriously, for editor/IDE plugins, there should be a --porcelain option that outputs error messages in a machine-friendly format, like with a fixed format that's easy for scripts / code / whatever to parse. TIt probably would be -verrors=json (or sth. like this), but the problem is that tools which parse DMD output are already out there, so we need to be a bit careful not to break them. Anyhow, I think using TTY detection to enable -verrors=context by default should work fine. DMD did/does the same when color-coded messages (`-color` ) where introduced.
Jan 12 2019
On Saturday, 12 January 2019 at 16:52:28 UTC, Seb wrote:On Saturday, 12 January 2019 at 16:32:43 UTC, H. S. Teoh wrote:I would be happy to change code-d and tools to any other format than currently parsing regexes, it's also missing consecutive errors like "instantiated from here" right now which I would like to fix :)Seriously, for editor/IDE plugins, there should be a --porcelain option that outputs error messages in a machine-friendly format, like with a fixed format that's easy for scripts / code / whatever to parse. TIt probably would be -verrors=json (or sth. like this), but the problem is that tools which parse DMD output are already out there, so we need to be a bit careful not to break them. Anyhow, I think using TTY detection to enable -verrors=context by default should work fine. DMD did/does the same when color-coded messages (`-color` ) where introduced.
Jan 14 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:tl;dr: I was annoyed for years that D's assert are so non informative AssertError, so here's my late Christmas present for the D community. With 2.085 DMD will gain an experimental flag for more informative assertion errors. Feedback on this experimental feature is welcome, s.t. we eventually can enable it by default. [...]Epic! That's massively useful. I Such a great start for D in 2019 :) Thanks a lot, Seb! I'll use this new version soon.
Jan 12 2019
On Saturday, 12 January 2019 at 16:28:57 UTC, viniarck wrote:On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:My bad for the typo. I meant to type "It's such a great start for D in 2019".tl;dr: I was annoyed for years that D's assert are so non informative AssertError, so here's my late Christmas present for the D community. With 2.085 DMD will gain an experimental flag for more informative assertion errors. Feedback on this experimental feature is welcome, s.t. we eventually can enable it by default. [...]Epic! That's massively useful. I Such a great start for D in 2019 :) Thanks a lot, Seb! I'll use this new version soon.
Jan 12 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:Merry Christmas!Amazing. I saw the PR a while back and was afraid it would be pushed aside in favor of library solutions, but whenever I quickly write unittests for my modules I never feel like dragging in a fluent assert library and end up manually putting writeln's everywhere, so I'm super glad it's actually coming to dmd.
Jan 12 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:tl;dr: I was annoyed for years that D's assert are so non informative AssertError, so here's my late Christmas present for the D community. With 2.085 DMD will gain an experimental flag for more informative assertion errors. Feedback on this experimental feature is welcome, s.t. we eventually can enable it by default. Example: --- void main() { int a = 1, b = 2; assert(a == b); // ERROR: 1 != 2 } --- ```Thank you so much for working on this. There's nothing more infuriating than my program crashing due to a failed assert, then having to edit and recompile it just to put in some debug printing. It's not a big problem when I take the time to do things properly and put the relevant information into the assert message, but when I'm quickly hacking on some code it's annoying to do it for every single assert (I generally use asserts and DBC religiously to ensure preconditions and assumptions actually hold). This is one of those little things that is so small but is also extremely annoying, so thank you again for taking the time to fix it.dmd -run onlineapp.dcore.exception.AssertError onlineapp.d(4): 1 != 2 ---------------- ??:? _d_assert_msg [0xb150e350] ??:? _Dmain [0xb150d627] ``` Play online: https://run.dlang.io/is/GMfe9S Full changelog: https://dlang.org/changelog/pending.html#assert Where to start hacking: - https://github.com/dlang/dmd/blob/00299e3b6ca9dcd5a5dc8bd50280b63d0bdc51f9/src/dmd/expressionsem.d#L5559 - https://github.com/dlang/druntime/blob/master/src/core/internal/dassert.d - https://github.com/dlang/dmd/pull/8517 Q: Why not just introduce an `assertEqual` user function? A: - there's a lot of already written D code out there that uses `assert` [1] - `assertEqual` wouldn't cut, it because then we would need to have an `assertLessThan` etc. too Q: Why put this in the compiler and not in fluent-assert or similar library? A: - there's a lot of already written D code out there that uses `assert` [1] - not everyone wants to use a library just to have somewhat decent assert messages - libraries can only do sth. like `testedValue.should.equal(42)`, but the compiler can deal with `testedValue == 42` [1] https://github.com/search?l=D&q=assert&type=Code Error context ------------- Also note that with 2.085 DMD will get -verrors=context --- void foo() { a = 1; } --- ```dmd -verrors=context onlineapp.donlineapp.d(3): Error: undefined identifier a a = 1; ^ ``` Full changelog: https://dlang.org/changelog/pending.html#error-context Play online: https://run.dlang.io/is/8gsye1 Thanks to all the people (Jacob Carlborg, Petar Kirov, Nicolas Wilson, Rainer Schuetze, etc.) who helped me to get this feature into DMD! Merry Christmas!
Jan 12 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:Full changelog: https://dlang.org/changelog/pending.html#error-context Play online: https://run.dlang.io/is/8gsye1 Thanks to all the people (Jacob Carlborg, Petar Kirov, Nicolas Wilson, Rainer Schuetze, etc.) who helped me to get this feature into DMD!Wonderful! Have you looked at my previous proposal at https://wiki.dlang.org/DIP83? Thanks a lot!
Jan 13 2019
On Sunday, 13 January 2019 at 09:48:53 UTC, Per Nordlöw wrote:Have you looked at my previous proposal at https://wiki.dlang.org/DIP83?Yes of course ;-) (and it was one of the main inspirations for this work). Please see the DMD PR for the full history of this feature, discussion and the implementation in DMD: https://github.com/dlang/dmd/pull/8517
Jan 13 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:https://dlang.org/changelog/pending.html#error-context Play online: https://run.dlang.io/is/8gsye1Is there a way to download a dmd nightly and try this out? The nightly at https://dlang.org/download.html is currently broken.
Jan 13 2019
On Sunday, 13 January 2019 at 11:11:05 UTC, Per Nordlöw wrote:On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:e.g. https://run.dlang.io/is/GMfe9S for playing online with it. or: curl https://dlang.org/install.sh | bash -s dmd-nightlyhttps://dlang.org/changelog/pending.html#error-context Play online: https://run.dlang.io/is/8gsye1Is there a way to download a dmd nightly and try this out?The nightly at https://dlang.org/download.html is currently broken.The link just uses HTTPS which isn't supported by the S3 bucket. HTTP works: HTTP works: http://downloads.dlang.org/nightlies/ See also: https://github.com/dlang/dlang.org/pull/2554 Alternatively, you could always use digger: --- dub fetch digger dub run digger -- build --- (this will build the current master of DMD/Druntime/Phobos/Tools/Dub automatically for you)
Jan 13 2019
On Sunday, 13 January 2019 at 12:01:49 UTC, Seb wrote:The link just uses HTTPS which isn't supported by the S3 bucket. HTTP works: HTTP works: http://downloads.dlang.org/nightlies/ See also: https://github.com/dlang/dlang.org/pull/2554 Alternatively, you could always use digger: --- dub fetch digger dub run digger -- build --- (this will build the current master of DMD/Druntime/Phobos/Tools/Dub automatically for you)Thanks!
Jan 13 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:Thanks to all the people (Jacob Carlborg, Petar Kirov, Nicolas Wilson, Rainer Schuetze, etc.) who helped me to get this feature into DMD! Merry Christmas!Awesome, thank you! This should be great for debug builds.
Jan 13 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:tl;dr: I was annoyed for years that D's assert are so non informative AssertError, so here's my late Christmas present for the D community. With 2.085 DMD will gain an experimental flag for more informative assertion errors. Feedback on this experimental feature is welcome, s.t. we eventually can enable it by default. [...]Awesome. It's obvious that assertions for equality are the most common, I wonder how easy it would be to get other changes merged like `assert(foo in bar)`. There are also all the assertions that make use of `equal` because of ranges. In unit-threaded `foo.should == bar` works if foo is a range and bar is a dynamic array. What I'd really like is access to the AST in the assert but alas I don't think that will ever be possible.
Jan 14 2019
On Monday, 14 January 2019 at 14:15:45 UTC, Atila Neves wrote:On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:Should be easy enough: https://github.com/dlang/dmd/pull/9264 https://github.com/dlang/druntime/pull/2463 Also note that other trivial stuff like `a < b` is already supported. See e.g.: https://github.com/dlang/druntime/blob/master/test/exceptions/src/assert_fail.dtl;dr: I was annoyed for years that D's assert are so non informative AssertError, so here's my late Christmas present for the D community. With 2.085 DMD will gain an experimental flag for more informative assertion errors. Feedback on this experimental feature is welcome, s.t. we eventually can enable it by default. [...]Awesome. It's obvious that assertions for equality are the most common, I wonder how easy it would be to get other changes merged like `assert(foo in bar)`.There are also all the assertions that make use of `equal` because of ranges.In theory we could hard-code a check for the symbol in DMD and see whether its std.algorithm.comparison.equal, but ranges are tricky as both might have been consumed by `equal` and you would then end up printing e.g. sth. like: [] != []I'd really like is access to the AST in the assert but alas I don't think that will ever be possible.Yeah :/
Jan 14 2019
On 1/12/19 10:34 AM, Seb wrote:tl;dr: I was annoyed for years that D's assert are so non informative AssertError, so here's my late Christmas present for the D community. With 2.085 DMD will gain an experimental flag for more informative assertion errors. Feedback on this experimental feature is welcome, s.t. we eventually can enable it by default. Example: --- void main() { int a = 1, b = 2; assert(a == b); // ERROR: 1 != 2 } --- ```Wonderful. Thanks!dmd -run onlineapp.dcore.exception.AssertError onlineapp.d(4): 1 != 2
Jan 14 2019
On 1/12/19 10:34 AM, Seb wrote:tl;dr: I was annoyed for years that D's assert are so non informative AssertError, so here's my late Christmas present for the D community. With 2.085 DMD will gain an experimental flag for more informative assertion errors. Feedback on this experimental feature is welcome, s.t. we eventually can enable it by default.[...]Thanks to all the people (Jacob Carlborg, Petar Kirov, Nicolas Wilson, Rainer Schuetze, etc.) who helped me to get this feature into DMD! Merry Christmas!Just want to add in my +1. Thanks! -Steve
Jan 14 2019
On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:void main() { int a = 1, b = 2; assert(a == b); // ERROR: 1 != 2 }But 1!=2 is true :) Maybe do it the C way "assertion 1 == 2 failed"? Also there's in operator.
Jan 15 2019
On Tuesday, 15 January 2019 at 08:43:06 UTC, Kagamin wrote:On Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:Hmm you have a point there. How do other people feel about this? My main motivation was to be able to see the actual values (instead of just an AssertError), so I would be more than happy to change the format of the message.void main() { int a = 1, b = 2; assert(a == b); // ERROR: 1 != 2 }But 1!=2 is true :) Maybe do it the C way "assertion 1 == 2 failed"? Also there's in operator.
Jan 15 2019
On Tuesday, 15 January 2019 at 10:23:32 UTC, Seb wrote:My main motivation was to be able to see the actual values (instead of just an AssertError), so I would be more than happy to change the format of the message.I remember Adam wanted the asserted expression to be printed as is to more reliably locate the failed assert as it can move when the code changes. Did you consider it? So the message can be "assertion a == b failed: a=1,b=2".
Jan 15 2019
On Tue, 15 Jan 2019 10:23:32 +0000, Seb wrote:On Tuesday, 15 January 2019 at 08:43:06 UTC, Kagamin wrote:I think I'd agree with Kagamin - after the first time you'd know it, but D already has a big list of "after the first time" features; If we see D-learners posting, confused about it, then it should probably be adjusted; otherwise, maybe it's not a major concern. I just skimmed some of my tests and the current message works, but may take some getting used to because of the reversal of the conditional. Ex: assert(opts.imports[0] == "std.stdio"); // becomes "ERROR: std.file != std.stdio"... well, yeah. // "ERROR: assertion std.file == std.stdio failed" is an easier read // (at least for me) --RyanOn Saturday, 12 January 2019 at 15:34:02 UTC, Seb wrote:Hmm you have a point there. How do other people feel about this? My main motivation was to be able to see the actual values (instead of just an AssertError), so I would be more than happy to change the format of the message.void main() { int a = 1, b = 2; assert(a == b); // ERROR: 1 != 2 }But 1!=2 is true :) Maybe do it the C way "assertion 1 == 2 failed"? Also there's in operator.
Jan 15 2019
On 2019-01-15 11:23, Seb wrote:Hmm you have a point there. How do other people feel about this?I think the message should look as similar as the expression in the code as possible. -- /Jacob Carlborg
Jan 15 2019
And what happens to other expressions? assert(a == b); // ERROR: 1 != 2 assert(c.has(d)); // ERROR: c.has(d) The message will have an opposite meaning?
Jan 15 2019
On Tuesday, 15 January 2019 at 08:47:24 UTC, Kagamin wrote:And what happens to other expressions? .. assert(c.has(d)); // ERROR: c.has(d) The message will have an opposite meaning?https://run.dlang.io/is/mRQM02 --- core.exception.AssertError onlineapp.d(5): assert(a.has(b)) failed ---------------- ??:? _d_assert_msg [0x2bf174b4] ??:? _Dmain [0x2bf173ed] --- It falls back to printing the stringified raw expression as the changelog states [1]. (this is still an improvement compared to the current "AssertError" without any information) [1] https://dlang.org/changelog/pending.html#assert
Jan 15 2019