On 9/12/22 12:14 PM, Ali Çehreli wrote:
>What are best practices here?
attributes such as pure
, @nogc
, nothrow
, @safe
should all be left to inference. Either the function can do those attributes, or it cannot.
attributes such as const
or inout
are different -- these are not inferred, and you need to use introspection to determine these. Which is really unfortunate, because there's no easy way to say "const if this is allowed" -- you have to repeat the implementation.
Is this accurate: Because Foo is a template, it should not put any attribute on member functions? Or only member functions that use a member that depends on a template parameter? And non-members that are templates?
It is scary because Foo works just fine until it is used with impure code.
It's not that scary, because I'm not sure what one would expect passing in an impure function to the template.
>Is putting function attributes on unittest blocks for catching such issues?
@nogc nothrow pure @safe
unittest
{
// ...
}
No, it isn't because unless my unittest code is impure, I can't catch my incorrect 'pure' etc. on my member functions.
Yes, this is exactly what you should do. You don't need to unittest compiler inference -- just expect this to work. What you want to test is if there's any code you wrote for Foo can make impure something that should be pure. Things that Foo calls on its parameter should not count towards your test, that's on the caller.
So for instance, create a dummy range that is pure, nogc, nothrow, safe, and test Foo as a wrapper on that range, attributing the unittest with that. And if that works, you should be good. You shouldn't have to test that if you pass in an impure function, the thing becomes impure.
Caveat: if you have code that is compiled differently based on those attributes, you should test those cases too to ensure coverage of the code in question.
-Steve