www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - __traits(compileError, {})

reply bitwise <bitwise.pvt gmail.com> writes:
Lately, I've been hit by several compilation errors when phobos 
fails to construct an instance of a class or struct I've pass it. 
Regardless of what the exact failure is, phobos usually gives you 
some generic error that isn't helpful.

Example:

class Test {
      disable this();
}

int main(string[] argv) {
     auto sz = __traits(classInstanceSize, Test);
     auto mem = malloc(sz)[0..sz];
     emplace!Test(mem);
     return 0;
}

The above code fails with this error:

'Error: static assert  "Don't know how to initialize an object of 
type Test with arguments ()"'

 disable'd constructors are only one of the reasons I've hit this 
snag.
Once though, I was having an extremely hard time figuring out 
what was wrong, and the fix was simply to modify emplace(). I 
removed the line below from emplace(), and forced the constructor 
call, which led to a much more helpful error.

`// static if (is(typeof(result.__ctor(args1))))`

If you simply did that though, it may not be obvious to everyone 
what happened, but if you had __traits(compilerError, {}) then 
you could dress the error up as appropriate:

"Emplace failed with error:\n\t'" ~ __traits(compileError, { 
result.__ctor(args1) }) ~ "."

The alternative would be to manually code redundant error checks 
that the compiler already does into everything in phobos that 
needs to construct objects, which seems much worse than 
implementing something like __traits(compileError, {}).

Thoughts?
Sep 07 2017
next sibling parent reply bitwise <bitwise.pvt gmail.com> writes:
On Friday, 8 September 2017 at 01:18:46 UTC, bitwise wrote:
 Lately, I've been hit by several compilation errors when phobos 
 fails to construct an instance of a class or struct I've pass 
 it. Regardless of what the exact failure is, phobos usually 
 gives you some generic error that isn't helpful.

 [...]
Does anyone even follow procedures of any kind for additions this trivial, or do they just do pull requests and debate it there?
Sep 10 2017
parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sunday, September 10, 2017 23:25:59 bitwise via Digitalmars-d wrote:
 On Friday, 8 September 2017 at 01:18:46 UTC, bitwise wrote:
 Lately, I've been hit by several compilation errors when phobos
 fails to construct an instance of a class or struct I've pass
 it. Regardless of what the exact failure is, phobos usually
 gives you some generic error that isn't helpful.

 [...]
Does anyone even follow procedures of any kind for additions this trivial, or do they just do pull requests and debate it there?
Additions to the standard library on the size of new modules or redesigned modules require a formal review in the main newsgroup, but making changes to individual functions don't. If you're looking to add something to the compiler, it could simply be a PR, or it could require a DIP, depending on its scope and what Walter and the other compiler devs think. In the case of your suggestion, I'd argue that it would simply be better to improve the compiler-generated error messages if they're not good enough rather than trying to add some mechanism to inject messages from the programmer into the compiler's error messages. And remember that you do already have static assert, pragma(msg, ...), and __traits(compiles, ...) to work with if you want to be adding additional compile-time checks and/or printing out additional messages at compile time. But if you have an idea that you want to implement and try and get in, then implement it and create a PR. Worst case, they tell you that it's not a desirable change or that a more formal review is necessary. And in the latter case, that just means that you then know what you need to do to go to the next step. - Jonathan M Davis
Sep 10 2017
parent reply bitwise <bitwise.pvt gmail.com> writes:
On Monday, 11 September 2017 at 00:15:08 UTC, Jonathan M Davis 
wrote:
 On Sunday, September 10, 2017 23:25:59 bitwise via 
 Digitalmars-d wrote:
 On Friday, 8 September 2017 at 01:18:46 UTC, bitwise wrote:
 [...]
Does anyone even follow procedures of any kind for additions this trivial, or do they just do pull requests and debate it there?
Additions to the standard library on the size of new modules or redesigned modules require a formal review in the main newsgroup, but making changes to individual functions don't. If you're looking to add something to the compiler, it could simply be a PR, or it could require a DIP, depending on its scope and what Walter and the other compiler devs think.
Ok, makes sense - Thanks. My own learning curve aside though, it doesn't seem prohibitively time consuming to just try this myself at some point.
 In the case of your suggestion, I'd argue that it would simply 
 be better to improve the compiler-generated error messages if 
 they're not good enough.
I'm suggesting the opposite. I'm saying that the compiler messages _are_ good enough, but that some functions in phobos (emplace, for example) suppress them by using code like this: ` static if(__traits(compiles, { ... })) doIt(); else static assert("custom error message"); ` So instead of a custom error message, you could simply run the offending code through the compiler and output what it says. The compiler's error message would most likely be much better and more detailed than the custom one inserted by hand. So essentially, the above would be refactored like this: ` static if(__traits(compiles, { doIt(); })) doIt(); else static assert("Failed to invoke 'doIt': \n\t" ~ __traits(compilerError, { doIt(); })); ` For the case of emplace() though, I'm wondering if that static if even needs to be there at all - maybe not.
Sep 10 2017
parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Monday, September 11, 2017 00:41:12 bitwise via Digitalmars-d wrote:
 On Monday, 11 September 2017 at 00:15:08 UTC, Jonathan M Davis
 In the case of your suggestion, I'd argue that it would simply
 be better to improve the compiler-generated error messages if
 they're not good enough.
I'm suggesting the opposite. I'm saying that the compiler messages _are_ good enough, but that some functions in phobos (emplace, for example) suppress them by using code like this: ` static if(__traits(compiles, { ... })) doIt(); else static assert("custom error message"); ` So instead of a custom error message, you could simply run the offending code through the compiler and output what it says. The compiler's error message would most likely be much better and more detailed than the custom one inserted by hand. So essentially, the above would be refactored like this: ` static if(__traits(compiles, { doIt(); })) doIt(); else static assert("Failed to invoke 'doIt': \n\t" ~ __traits(compilerError, { doIt(); })); ` For the case of emplace() though, I'm wondering if that static if even needs to be there at all - maybe not.
Well, if you find anything in a Phobos function that you think is suboptimal, feel free to create a PR to fix it. - Jonathan M Davis
Sep 10 2017
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08.09.2017 03:18, bitwise wrote:
 Lately, I've been hit by several compilation errors when phobos fails to 
 construct an instance of a class or struct I've pass it. Regardless of 
 what the exact failure is, phobos usually gives you some generic error 
 that isn't helpful.
 
 Example:
 
 class Test {
       disable this();
 }
 
 int main(string[] argv) {
      auto sz = __traits(classInstanceSize, Test);
      auto mem = malloc(sz)[0..sz];
      emplace!Test(mem);
      return 0;
 }
 
 The above code fails with this error:
 
 'Error: static assert  "Don't know how to initialize an object of type 
 Test with arguments ()"'
 
  disable'd constructors are only one of the reasons I've hit this snag.
 Once though, I was having an extremely hard time figuring out what was 
 wrong, and the fix was simply to modify emplace(). I removed the line 
 below from emplace(), and forced the constructor call, which led to a 
 much more helpful error.
 
 `// static if (is(typeof(result.__ctor(args1))))`
 
 If you simply did that though, it may not be obvious to everyone what 
 happened, but if you had __traits(compilerError, {}) then you could 
 dress the error up as appropriate:
 
 "Emplace failed with error:\n\t'" ~ __traits(compileError, { 
 result.__ctor(args1) }) ~ "."
 
 The alternative would be to manually code redundant error checks that 
 the compiler already does into everything in phobos that needs to 
 construct objects, which seems much worse than implementing something 
 like __traits(compileError, {}).
 
 Thoughts?
The dangerous thing about this suggestion is that it makes the compilation errors DMD implements de facto part of the semantics of the D language. I.e. improving compiler diagnostics becomes a breaking language change.
Sep 11 2017
parent bitwise <bitwise.pvt gmail.com> writes:
On Monday, 11 September 2017 at 11:07:46 UTC, Timon Gehr wrote:
 The dangerous thing about this suggestion is that it makes the 
 compilation errors DMD implements de facto part of the 
 semantics of the D language. I.e. improving compiler 
 diagnostics becomes a breaking language change.
I guess this is true if people start trying to parse the error messages to extract details, but shouldn't there be some level of standardization for tools anyways? Thinking about this a little further though, I think the behavior I had in mind could be implemented without changes. My example from above could become this: ` static if(!__traits(compiles, { doIt(); })) { // now, we know it's about to fail pragma(msg, "doIt() failed because...."); } // do it anyways and let the compiler output it's regular error message doIt(); `
Sep 11 2017