Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
November 07, 2018 [Issue 19371] Taking address of ref return in @safe code: compile-time checks fail | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19371 Stanislav Blinov <stanislav.blinov@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |safe -- |
November 10, 2018 [Issue 19371] Taking address of ref return in @safe code: compile-time checks fail | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19371 Nick Treleaven <nick@geany.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |nick@geany.org --- Comment #1 from Nick Treleaven <nick@geany.org> --- Using __traits(compiles) works for the first two asserts: static assert(!__traits(compiles, &get())); static assert(!__traits(compiles, () @safe { return &get(); })); is(typeof()) is not as strict, it is looking for a type rather than compiling. > static assert(!__traits(compiles, { auto p = &get(); })); Here, the function literal is inferred as @system, and can even be assigned to a variable in @safe code (but not called): auto f = { auto p = &get(); }; //ok f(); // Error: `@safe` function cannot call `@system` function pointer `f` You can fix it by forcing @safe for the literal, or calling the literal: static assert(!__traits(compiles, () @safe { auto p = &get(); })); static assert(!__traits(compiles, { auto p = &get(); }())); -- |
November 10, 2018 [Issue 19371] Taking address of ref return in @safe code: compile-time checks fail | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19371 --- Comment #2 from Stanislav Blinov <stanislav.blinov@gmail.com> --- Thanks for the pointers about __traits(compiles), I somehow lost the distinction of braces. However, the point about is(typeof()) still stands though: pragma(msg, typeof(() @safe { return &get(); })); will print _error_. In other words: ``` void main() @safe { int x; ref int get() { return x; } // since this doesn't compile: int* getExplicit() @safe { return &get(); } // ...then it has no type, therefore this should pass: static assert(!is(typeof(() @safe { return &get(); }))); } ``` -- |
November 13, 2018 [Issue 19371] Taking address of ref return in @safe code: compile-time checks fail | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19371 --- Comment #3 from Nick Treleaven <nick@geany.org> --- (In reply to Stanislav Blinov from comment #2) > pragma(msg, typeof(() @safe { return &get(); })); > > will print _error_. What compiler are you using? With run.dlang.io the above (currently) prints: int* delegate() pure nothrow @nogc @safe It's the same even if I remove the @safe attribute, safety inference (or safe consistency checking) is not happening inside typeof alone. BTW if I do this: auto f = { return &get(); }; pragma(msg, typeof(f)); I get `int* delegate() pure nothrow @nogc @system`. The compiler does safety inference for `f` before typeof(f) is analysed. The same happens if I replace the literal with `{ return cast(int*)7; }`, it's reported as @safe inside pragma(msg, typeof(...)), but @system when assigning it to a variable `f` and doing pragma(msg, typeof(f)). > // since this doesn't compile: > int* getExplicit() @safe { return &get(); } > // ...then it has no type, therefore this should pass: > static assert(!is(typeof(() @safe { return &get(); }))); It depends if `typeof` is supposed to do @safe checking, or if it is just a tool to extract a type from an expression (that appears to have a valid type), even if that expression might not actually compile with full compiler checks. I think it's the latter, which is why __traits(compiles) was invented. -- |
November 13, 2018 [Issue 19371] Taking address of ref return in @safe code: compile-time checks fail | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19371 --- Comment #4 from Nick Treleaven <nick@geany.org> --- See: https://forum.dlang.org/post/k6o04g$259s$1@digitalmars.com -- |
November 14, 2018 [Issue 19371] Taking address of ref return in @safe code: compile-time checks fail | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19371 --- Comment #5 from Stanislav Blinov <stanislav.blinov@gmail.com> --- Add -dip1000 to the command line. With it, I don't understand how these two lines are not contradicting: pragma(msg, typeof(() @safe { return &get(); })); // _error_ static assert(!is(typeof(() @safe { return &get(); }))); // fails -- |
November 28, 2018 [Issue 19371] Taking address of ref return in @safe code: compile-time checks fail | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19371 --- Comment #6 from Nick Treleaven <nick@geany.org> --- (In reply to Stanislav Blinov from comment #5) Adding -dip1000, the pragma line does error, but the static assert passes. -- |
November 28, 2018 [Issue 19371] Taking address of ref return in @safe code: compile-time checks fail | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19371 Stanislav Blinov <stanislav.blinov@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution|--- |INVALID --- Comment #7 from Stanislav Blinov <stanislav.blinov@gmail.com> --- Hmm, I must've done something wrong initially. -- |
Copyright © 1999-2021 by the D Language Foundation