On 11/15/2012 10:26 AM, Joseph Rushton Wakeling wrote:
On 11/15/2012 06:40 PM, Ali Çehreli wrote:
b) The user wants to play safe:

auto makeFoo()
{
Foo foo;
foreach (i; 0..10)
foo.add( /* new data point */ );
return foo;
}

void main()
{
immutable foo = makeFoo();
}

Both of those compile with dmd 2.060.

Really? I'm using from-GitHub dmd, and with the above example I get a
"cannot implicitly convert expression to immutable" error, e.g.:

Error: cannot implicitly convert expression (testSets(nfRaw,0.1L)) of
type TestData!(ulong,ulong) to immutable(TestData!(ulong,ulong))


The following program compiles without any errors with dmd 2.060:

struct Foo(T0, T1)
{
    T0 t0;
    T1 t1;
}

auto testSets(T0, T1)(T0 t0, T1 t1)
{
    auto foo = Foo!(T0, T1)(t0, t1);
    return foo;
}

void main()
{
    ulong nfRaw;
    immutable foo = testSets(nfRaw,0.1L);
}

So far it makes sense to me: There shouldn't be any problem with making a copy of a value type and marking that copy as immutable.

Unless there exists a member that would make this unsafe. Let's add an int[] member to Foo:

struct Foo(T0, T1)
{
    T0 t0;
    T1 t1;
    int[] a;
}

auto testSets(T0, T1)(T0 t0, T1 t1, int[] a)
{
    auto foo = Foo!(T0, T1)(t0, t1, a);
    return foo;
}

void main()
{
    ulong nfRaw;
    int[] a = [ 42 ];
    immutable foo = testSets(nfRaw, 0.1L, a); // <-- compilation error
    assert(foo.a[0] == 42);
    a[0] = 43;
    assert(foo.a[1] == 43);  // <-- if compiled, this would be a bug
}

Do you have a reference type in your struct?

Ali

Reply via email to