`@safe`, `pure`, and `nothrow` depend entirely on the types being used to instantiate the function. Putting them on a templated function the makes it so that only types which can work with them will compile with the function. We don't want that. It's precisely so that templated functions don't force any particular attribute (or forbid any particular attribute) that we added attribute inference. Whether a function is `pure`, `@safe`, or `nothrow` depends on its arguments, and if you want to test that it's `@safe`, `pure`, or `nothrow` with any particular set of arguments, then test that that particular instantiation of it is. That can be done in a number of ways, including use std.traits to test particular function calls or creating `unittest` blocks marked with those attributes and which make those calls.