what are the rules for @nogc and @safe attributes inference?

ikod geller.garry at gmail.com
Fri Nov 30 22:10:11 UTC 2018


On Friday, 30 November 2018 at 21:03:06 UTC, Neia Neutuladh wrote:
> On Fri, 30 Nov 2018 20:41:03 +0000, ikod wrote:
>> I can't find the reason why nogc/nothrow can't be inferred in 
>> this case:
>> 
>> class S(K,V)
>> {
>>      auto get/*()*/(K a) {
>>          return 0;
>>      }
>> }
>> void main() @nogc nothrow {
>>      S!(int, string) sia;
>>      auto v = sia.get(1);
>> }
>
> class Nefarious : S!(int, string)
> {
>   override int get(int a)
>   {
>     // Whoops, I used the GC
>     return new char[a].length;
>   }
> }
>
> The compiler can't prove that a variable of type S!(int, 
> string) will not be of type Nefarious, which uses the GC, so it 
> can't infer @nogc for S.get.
>
> However, if you make the function final, then the compiler can 
> infer it to be pure nothrow @nogc @safe.
>
> Or if you use a struct instead of a class, structs don't do 
> inheritance, so the compiler can infer attributes without 
> worrying about nefarious inheritance.
>
>> But everything is ok if you uncomment parentheses after get.
>
> Templated functions are implicitly final.

Thanks for explanation, got it.

My case is actually

interface I(K,V)
{
     int get()(K);
}
class S(K,V) : I!(K, V)
{
     int v;
     int get()(K a)
     {
         return v;
     }
}
void main() nothrow
{
     S!(int, string) s = new S!(int, string);
     s.get(1);
}

My goal is to allow compiler to infer all properties of s.get 
without adding nothrow/nogc anywhere.  And these templated 
functions is only way it works for me. Is it ok? Or there is 
better solution?

Thanks!


More information about the Digitalmars-d-learn mailing list