On Tuesday, 30 January 2018 at 10:49:54 UTC, Simen Kjærås wrote:
Is there a way to get a compile error when returning a temporary from a function and then not assigning it to a variable or passing it to a different function? E.g:

struct S {
    int[] a;
    void morph() {}
}

@warnOnDiscard
S foo() {
    return S([1,2,3]);
}

unittest {
    auto a = foo(); // Fine, assigned to variable.
    bar(foo());     // Fine, passed to other function.
    foo();          // Error: return value is discarded.
    foo().morph();  // Error: return value is discarded.
}

I know that pure functions give errors when their results are discarded, but in this case foo() might not be pure.
--
  Simen

On top of what's said.

It would be very complex to implement properly.

For example the following should fail, but will be very hard for the compiler to actually track.

struct S {
    int[] a;
    void morph() {}
}

@warnOnDiscard
S foo() {
    return S([1,2,3]);
}

void d(S s) {

}

unittest {
auto a = foo(); // This should fail, because a is never used.

// This should also fail, because b is never used actually used afterwards.
    auto b = foo()
    b.morph();

   // This should fail, because d does not use c.
// A simply analysis of d will not work, you'll have to track all passed values to d and whether they themselves should be tracked with the attribute.
   auto c = foo();

   d(c);

// Same as above, should fail too since d doesn't use the return value
  d(foo());
}

The above is going to be very complex to implement in the compiler.

Sure a simple check if it has just been assigned to a variable would work fine, but in the reality people would most likely just do something like this then:

auto unused = foo();

And there ... we "hacked" our way around the attribute.

So for it to work it has to track every single return value from a function that implements the attribute and that is borderline impossible to get correct.

Reply via email to