digitalmars.D.learn - Why is my pure function system when placed in a struct?
- Q. Schroll (37/37) Feb 27 2019 I have a template function `fImpl` I whish to instantiate
- Stefan Koch (3/8) Feb 27 2019 the struct gets drawn into your delegate-context.
- Dukc (4/6) Feb 27 2019 Even if it did, it should not make the delegate @system. And it
- Dukc (12/14) Feb 27 2019 I tested a bit, and it appears that attribute inference is not
- ag0aep6g (16/30) Feb 27 2019 It's not quite as simple as that. When you put the pragma in a function,...
I have a template function `fImpl` I whish to instantiate manually using the new name `f`. Reason is simple: `f` should not be a template, but overloading it makes it easier that way. Nothing's more simple in D: int fImpl(T)(T value) { return cast(int) value; } alias f = fImpl!int; alias f = fImpl!long; It works perfectly used like that. In my case, `T` isn't just a simple type, it's a delegate type. So it's rather like this: alias BaseDG = int delegate(ref int); int fImpl(DG : BaseDG)(scope DG callback) { // NB: this is safe iff callback is safe int x = 0; return callback(x); } alias myDG = int delegate(ref int) safe; alias f = fImpl!myDG; When I ask the compiler, if `f` is safe, it tells me: Hurray, it is! pragma(msg, __traits(getFunctionAttributes, f)); // tells me: `f` is safe For whatever reason, when I put the code in a struct, the safe testing line tells me, it's system now. struct S { // static: // static or not does not matter alias BaseDG = int delegate(ref int); int fImpl(DG : BaseDG)(scope DG callback) { return 0; } alias myDG = int delegate(ref int) system; alias f = fImpl!myDG; pragma(msg, __traits(getFunctionAttributes, f)); // tells me: `f` is system } I have no idea why. It is irrelevant if the function template is `static` or even does not call the callback.
Feb 27 2019
On Wednesday, 27 February 2019 at 17:23:21 UTC, Q. Schroll wrote:I have a template function `fImpl` I whish to instantiate manually using the new name `f`. Reason is simple: `f` should not be a template, but overloading it makes it easier that way. Nothing's more simple in D: [...]the struct gets drawn into your delegate-context. and I guess that taints the function.
Feb 27 2019
On Wednesday, 27 February 2019 at 18:06:49 UTC, Stefan Koch wrote:the struct gets drawn into your delegate-context. and I guess that taints the function.Even if it did, it should not make the delegate system. And it does not, since this manifest with static functions and function pointers too.
Feb 27 2019
On Wednesday, 27 February 2019 at 17:23:21 UTC, Q. Schroll wrote:For whatever reason, when I put the code in a struct, the safe testing line tells me, it's system now.I tested a bit, and it appears that attribute inference is not done at all for templates inside structs -the attribute need not be a delegate: struct S { static int fImpl(Ret)() { return Ret.init; } pragma(msg, __traits(getFunctionAttributes, fImpl!int)); // still tells us: `f` is system } void main(){} A bug, unless I'm overlooking something.
Feb 27 2019
On 27.02.19 19:10, Dukc wrote:I tested a bit, and it appears that attribute inference is not done at all for templates inside structs -the attribute need not be a delegate: struct S { static int fImpl(Ret)() { return Ret.init; } pragma(msg, __traits(getFunctionAttributes, fImpl!int)); // still tells us: `f` is system } void main(){} A bug, unless I'm overlooking something.It's not quite as simple as that. When you put the pragma in a function, the inferred attributes show up: ---- struct S { void f()() {} } pragma(msg, __traits(getFunctionAttributes, S.f!())); /* system */ void g() { pragma(msg, __traits(getFunctionAttributes, S.f!())); /* Same line now says safe. */ } ---- But I agree that this can't be right.
Feb 27 2019