Reputation: 9600
The following program correctly fails to compile:
sub f(Int $a) { my Str $b = $a }
say f 42;
say f 'foo';
Specifically, line 3 causes a compilation error (with a ===SORRY!===
error message); this error occurs before line 2 is executed, so the type mismatch within &f is never reached.
But when, specifically, does this error occur? I thought it occurred during the CHECK phase, but was surprised to notice that raku -c
does not generate a compile error; it reports Syntax OK
.
To dig into this a bit more, I added logging code to the snippet above:
BEGIN note 'begin';
CHECK note 'check';
INIT note 'init';
END note 'end';
sub f(Int $a) { my Str $b = $a }
say f 42;
say f 'foo';
Running this revised code with raku -c
prints "begin\n check\n Syntax OK"; running it with raku
prints "begin\n check\n ===SORRY!===" (and the rest of the error message).
If I remove the say f 'foo'
line (and thus the compile error), raku -c
still prints "begin\n check\n Syntax OK" but raku
prints "begin\n check\n init\n Type check failed… \n end" (again omitting the body of the error message).
What's going on here? Does the compile error that generated the ===SORRY!===
occur some time between CHECK and INIT (is there any such time?)? Or does raku -c
not actually "run BEGIN and CHECK blocks" as raku --help
indicates? Or something else?
Relatedly: how, if at all, is any of this connected to the idea of "nested compile times"? Does the execution of this code involve any nested compile times, or does that only occur when using modules? Is there any way to note/log separate compile phases (maybe with correctly placed BEGIN blocks?) or is that something that isn't exposed?
Upvotes: 8
Views: 114
Reputation: 26894
The SORRY message is a side-effect of the static optimizer. Observe the difference in behaviour between:
$ raku -e 'sub foo(Int $a) { }; foo "foo"'
===SORRY!=== Error while compiling -e
Calling foo(Str) will never work with declared signature (Int $a)
and:
$ raku --optimize=off -e 'sub foo(Int $a) { }; foo "foo"'
Type check failed in binding to parameter '$a'; expected Int but got Str ("foo")
in sub foo at -e line 1
which happens somewhere between CHECK
and INIT
time, unless it has been disabled. Note that disabling the static optimizer makes it a runtime error.
Upvotes: 8