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!

Reply via email to