I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is @nogc. Here's a semi-reduced test-case:

---
import std.range;
import std.traits    : EnumMembers;
import std.typecons  : tuple, staticIota;
import std.algorithm : map;

struct Enumap(K, V)
  if(EnumMembers!K == staticIota!(0, EnumMembers!K.length))
{
  enum length = EnumMembers!K.length;
  private V[length] _store;

  ref auto opIndex(K key) inout {
    return _store[key];
  }

  @nogc auto byKeyValue() const {
    return only(EnumMembers!K).map!(key => tuple(key, this[key]));
  }
}

@nogc void main() {
    import std.typecons  : tuple;
    import std.algorithm : map;

    enum E { a, b, c, d };
    immutable elements = Enumap!(E, int)([1,2,3,4]);

auto pairs = elements.byKeyValue.map!(pair => tuple(pair[0], pair[1] + 1));
}
---

GDC claims that byKeyValue() allocates a closure, but DMD is just fine with me calling it @nogc. I'm inclined to agree with GDC here, unless DMD is doing some magic so that actually doesn't allocate a closure.

Reply via email to