September 01, 2016
On Thursday, 1 September 2016 at 13:18:18 UTC, Rory McGuire wrote:
> the _checkCTFE() function is just a function that does something we're not
> allowed to do at CTFE, but current implementation does not respect
> __traits(compiles, ....);
>
>
>
> As far as I can tell that is a bug. Thoughts?

It is not a bug, because there is no way to mark something as CTFE-only.
static ifs are not visible at the time where ctfe sees the function, they have already been resolved.

getting a static if (__ctfe) to work would require significant changes to the semantic-analysis path for functions.
September 01, 2016
On Thu, Sep 1, 2016 at 6:29 PM, Stefan Koch via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote:

> On Thursday, 1 September 2016 at 13:18:18 UTC, Rory McGuire wrote:
>
>> the _checkCTFE() function is just a function that does something we're not
>> allowed to do at CTFE, but current implementation does not respect
>> __traits(compiles, ....);
>>
>>
>>
>> As far as I can tell that is a bug. Thoughts?
>>
>
> It is not a bug, because there is no way to mark something as CTFE-only. static ifs are not visible at the time where ctfe sees the function, they have already been resolved.
>
> getting a static if (__ctfe) to work would require significant changes to the semantic-analysis path for functions.
>


Ah, right, understood.


is that in one of the "semantic" passes the compiler has?


September 01, 2016
On Thursday, 1 September 2016 at 13:18:18 UTC, Rory McGuire wrote:
> void main() {
> ctfefunc();
> }
>
>
> string ctfefunc() {
> static if (assertCTFE!true) {
> throw new Exception("asdf");
> }
> return `import std.stdio; writeln("ctfe generated this");`;
> }
>
> template assertCTFE(bool b) {
> enum assertCTFE = __traits(compiles, _checkCTFE());
> }
> void _checkCTFE() {
> import std.uuid;
> enum id = new UUID("8AB3060E-2cba-4f23-b74c-b52db3bdfb46");
> }
>
> […] current implementation does not respect __traits(compiles, ....);
>
> As far as I can tell that is a bug. Thoughts?

This doesn't do what you think it does in more than one way. If you laid out how you think it should work, I'd be happy to walk you through where it goes wrong in particular. However, as it is, the whole program would certainly fail to compile if __traits(compiles, …) were false (which it indeed is) because the module-level function _checkCTFE() couldn't then be compiled either. It's just a top-level function. There is no __traits(compiles, ....) involved in that.

 — David
September 01, 2016
On Thursday, 1 September 2016 at 16:43:53 UTC, Rory McGuire wrote:
> is that in one of the "semantic" passes the compiler has?

For reference, I've laid out the reasons why this proposal couldn't work to Stefan here: https://github.com/dlang/dmd/pull/6098#issuecomment-243375543

The real reason is not so much in the pass structure of the compiler as in the fact that CTFE by definition executes the same function body that is also emitted to the runtime binary.

 — David
September 01, 2016
On Thu, Sep 1, 2016 at 9:09 PM, David Nadlinger via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote:

> On Thursday, 1 September 2016 at 16:43:53 UTC, Rory McGuire wrote:
>
>> is that in one of the "semantic" passes the compiler has?
>>
>
> For reference, I've laid out the reasons why this proposal couldn't work to Stefan here: https://github.com/dlang/dmd/p ull/6098#issuecomment-243375543
>
> The real reason is not so much in the pass structure of the compiler as in the fact that CTFE by definition executes the same function body that is also emitted to the runtime binary.
>
>  — David
>

okay thanks, I'll take a look at the link.

Question: if the function runs the same, why can't I catch the exception?
>From what Stefan said even if I could catch the exception static if still
wouldn't compile different code.

bool _checkCTFE() {
try {
import std.uuid;
enum id = new UUID("8AB3060E-2cba-4f23-b74c-b52db3bdfb46");
return false;
} catch (Throwable t) {
return true;
}
}

The above still fails during CTFE, compiler just exists with: enforceCTFE.d(20): Error: variable enforceCTFE._checkCTFE.id : Unable to initialize enum with class or pointer to struct. Use static const variable instead.


So why can't we even catch the Error during CTFE, that would at least help somewhat.

At the moment I just have a verbose logging mode with pragma(msg) for my
CTFE stuff.


September 01, 2016
On Thursday, 1 September 2016 at 19:27:17 UTC, Rory McGuire wrote:
> So why can't we even catch the Error during CTFE, that would at least help somewhat.

You are mixing up runtime exceptions ("throw …") with compiler errors (missing a semicolon). dm.D.learn should be able to help clear that up.

 — David
September 01, 2016
On Thursday, 1 September 2016 at 19:27:17 UTC, Rory McGuire wrote:

>
> At the moment I just have a verbose logging mode with pragma(msg) for my
> CTFE stuff.

I have something that will help with that a little bit.
https://github.com/UplinkCoder/dmd/tree/__ctfeWriteln
when you apply this patch __ctfeWriteln() will output every compiletime avilable string to the console.
It's a little bit nicer then using pragma(msg);
September 01, 2016
On Thursday, 1 September 2016 at 19:38:13 UTC, Stefan Koch wrote:
> I have something that will help with that a little bit.
> https://github.com/UplinkCoder/dmd/tree/__ctfeWriteln
> when you apply this patch __ctfeWriteln() will output every compiletime avilable string to the console.

More crucially, it also allows you to print runtime values during CTFE. pragma(msg, …) suffices to print compile-time constants. Very few people seem to have the correct mental model for the the interaction between compile-time features and CTFE, hence I think using precise terminology is an important first step.

See also: https://github.com/dlang/dmd/pull/692 – it's about time we finally got __ctfeWrite() merged.

 — David
September 01, 2016
On 01 Sep 2016 21:36, "David Nadlinger via Digitalmars-d-announce" < digitalmars-d-announce@puremagic.com> wrote:
>
> On Thursday, 1 September 2016 at 19:27:17 UTC, Rory McGuire wrote:
>>
>> So why can't we even catch the Error during CTFE, that would at least
help somewhat.
>
>
> You are mixing up runtime exceptions ("throw …") with compiler errors
(missing a semicolon). dm.D.learn should be able to help clear that up.
>
>  — David

I'm actually asking why we can't catch the ctfe error. It's quite obvious that it is a temporary limitation of ctfe, there have been many limitations removed over the years.

Surely the ctfe engine could be changed to catch unsupported code errors. (Not invalid, just unsupported at CT).

The ctfe engine would have to "go past" the try anyway, right? This is the part I don't understand. Is it because ctfe actually hasn't started yet and some other analysis is freaking out?


September 01, 2016
On Thursday, 1 September 2016 at 21:01:46 UTC, Rory McGuire wrote:
> I'm actually asking why we can't catch the ctfe error.

You can, by using __traits(compiles, …).

> Surely the ctfe engine could be changed to catch unsupported code errors. (Not invalid, just unsupported at CT).

It already does, see above. How is this related to try/catch?

 — David