digitalmars.D.learn - Type Inference in safe unittests
- jmh530 (36/36) Aug 22 2017 I'm not sure if this is a bug or not.
- Jonathan M Davis via Digitalmars-d-learn (17/53) Aug 22 2017 Well, templates aren't the only case where we have attribute inference
- jmh530 (13/33) Aug 22 2017 Yeah, this happens with @safe main also (below), but not for more
- Steven Schveighoffer (4/16) Aug 22 2017 The surprising part to me is that non-@safe main doesn't infer anything....
- jmh530 (8/20) Aug 22 2017 They aren't auto functions or templates, just normal member
- Steven Schveighoffer (11/31) Aug 22 2017 Logically, any internal struct's code is available for examination
I'm not sure if this is a bug or not. I was playing around with printing out some member types with unittests and I was noticing some strange results when they were in safe unittests rather than normal unittests. The first one prints out what I would expect, but the safe unittest puts safe nogc nothrow and pure on them, as if it is re-writing the struct as a template (or maybe just the functions as templates, I don't know). private enum isPrivate(T, string member) = !__traits(compiles, __traits(getMember, T, member)); void printMemberTypes(alias T)() { foreach(memberName; __traits(allMembers, T)) { static if(!isPrivate!(T, memberName)) { writeln(typeid(typeof(__traits(getMember, T, memberName)))); } } } unittest { struct Foo { int foo(int i, string s) safe { return 0; } double foo2(string s) safe { return 0; } } printMemberTypes!(Foo); } safe unittest { struct Foo { int foo(int i, string s) safe { return 0; } double foo2(string s) safe { return 0; } } printMemberTypes!(Foo); }
Aug 22 2017
On Tuesday, August 22, 2017 16:11:11 jmh530 via Digitalmars-d-learn wrote:I'm not sure if this is a bug or not. I was playing around with printing out some member types with unittests and I was noticing some strange results when they were in safe unittests rather than normal unittests. The first one prints out what I would expect, but the safe unittest puts safe nogc nothrow and pure on them, as if it is re-writing the struct as a template (or maybe just the functions as templates, I don't know). private enum isPrivate(T, string member) = !__traits(compiles, __traits(getMember, T, member)); void printMemberTypes(alias T)() { foreach(memberName; __traits(allMembers, T)) { static if(!isPrivate!(T, memberName)) { writeln(typeid(typeof(__traits(getMember, T, memberName)))); } } } unittest { struct Foo { int foo(int i, string s) safe { return 0; } double foo2(string s) safe { return 0; } } printMemberTypes!(Foo); } safe unittest { struct Foo { int foo(int i, string s) safe { return 0; } double foo2(string s) safe { return 0; } } printMemberTypes!(Foo); }Well, templates aren't the only case where we have attribute inference anymore (e.g. auto return functions have it), and I'm pretty sure that there have been several requests for fixing issues regards to local declarations so that they have inference (in particular, I think that there have been complaints about marking a function as pure having issues with internal declarations then not being treated as pure even though they could be). And for better or worse, the trend has been towards adding inference in cases where it's guaranteed that the code will always be available and will be available to any code using that code - and in the case of a declaration inside of a function like that, it's guaranted that anything referencing it is going to have access to the code. So, it doesn't surprise me at all if attribute inference has been added to local declarations like this. If you want to guarantee that no inference is happening, then you'll probably have to declare it directly in the module where it can't be infered due to the fact that a .di file could redeclare it without any function bodies. - Jonathan M Davis
Aug 22 2017
On Tuesday, 22 August 2017 at 16:27:05 UTC, Jonathan M Davis wrote:Well, templates aren't the only case where we have attribute inference anymore (e.g. auto return functions have it), and I'm pretty sure that there have been several requests for fixing issues regards to local declarations so that they have inference (in particular, I think that there have been complaints about marking a function as pure having issues with internal declarations then not being treated as pure even though they could be). And for better or worse, the trend has been towards adding inference in cases where it's guaranteed that the code will always be available and will be available to any code using that code - and in the case of a declaration inside of a function like that, it's guaranted that anything referencing it is going to have access to the code. So, it doesn't surprise me at all if attribute inference has been added to local declarations like this. If you want to guarantee that no inference is happening, then you'll probably have to declare it directly in the module where it can't be infered due to the fact that a .di file could redeclare it without any function bodies. - Jonathan M DavisYeah, this happens with safe main also (below), but not for more regular local blocks. Anyway, I found it very confusing as that's not how I assumed safe applied to unittests or main worked. safe void main() { struct Foo { int foo(int i, string s) safe { return 0; } double foo2(string s) safe { return 0; } } printMemberTypes!(Foo); }
Aug 22 2017
On 8/22/17 2:19 PM, jmh530 wrote:Yeah, this happens with safe main also (below), but not for more regular local blocks. Anyway, I found it very confusing as that's not how I assumed safe applied to unittests or main worked. safe void main() { struct Foo { int foo(int i, string s) safe { return 0; } double foo2(string s) safe { return 0; } } printMemberTypes!(Foo); }The surprising part to me is that non- safe main doesn't infer anything. Is that true? -Steve
Aug 22 2017
On Tuesday, 22 August 2017 at 18:25:31 UTC, Steven Schveighoffer wrote:They aren't auto functions or templates, just normal member functions of a struct in main. I thought inferring function attributes was only for auto functions and templates. I never thought it would for member functions of structs in main. But yeah, I'm pretty those functions are safe and not safe nogc nothrow pure.safe void main() { struct Foo { int foo(int i, string s) safe { return 0; } double foo2(string s) safe { return 0; } } printMemberTypes!(Foo); }The surprising part to me is that non- safe main doesn't infer anything. Is that true? -Steve
Aug 22 2017
On 8/22/17 5:44 PM, jmh530 wrote:On Tuesday, 22 August 2017 at 18:25:31 UTC, Steven Schveighoffer wrote:Logically, any internal struct's code is available for examination wherever it could possibly be used. If it's returned, then the function return must be auto (and the function code available). If it's passed as a template parameter, it is available. Inference could happen on any internal function anywhere, not just inside internal structs. I'm not sure why the marking of the enclosing function should make a difference, either they all infer or they all don't infer. To me, this seems like a bug (the inconsistency). -SteveThey aren't auto functions or templates, just normal member functions of a struct in main. I thought inferring function attributes was only for auto functions and templates. I never thought it would for member functions of structs in main. But yeah, I'm pretty those functions are safe and not safe nogc nothrow pure.safe void main() { struct Foo { int foo(int i, string s) safe { return 0; } double foo2(string s) safe { return 0; } } printMemberTypes!(Foo); }The surprising part to me is that non- safe main doesn't infer anything. Is that true?
Aug 22 2017