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