www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strage class' with invariant() {} function behaviour

reply mumba <qniol o2.pl> writes:
Hello people.

Check this out, and explain please.

class Foo {
    invariant(Object) bar() {
        return new invariant(Object); //return sth caller cannot change
    }
}

So far, so good. Now:

class Foo {
    invariant() {} //some design by contract stuff, nothing related to type's
storage classes
    Object bar() { //less restrictive version of the previous func
        return new Object; 
    }
}

So far so good. Now let's make a fusion:

class Foo {
    invariant() {}
    invariant(Object) bar() {
        return new invariant(Object);
    }
}

BANG! (dmd v2.014)
variable test.Foo.bar.__result cannot modify invariant

...

Of course, I have some theories, but I wouldn't come here if they were good, so
I'll keep them for myself. Tell me yours.

cheers.
Oct 08 2008
parent reply "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Wed, Oct 8, 2008 at 2:34 PM, mumba <qniol o2.pl> wrote:
 Hello people.

 Check this out, and explain please.

 class Foo {
    invariant(Object) bar() {
        return new invariant(Object); //return sth caller cannot change
    }
 }

 So far, so good. Now:

 class Foo {
    invariant() {} //some design by contract stuff, nothing related to type's
storage classes
    Object bar() { //less restrictive version of the previous func
        return new Object;
    }
 }

 So far so good. Now let's make a fusion:

 class Foo {
    invariant() {}
    invariant(Object) bar() {
        return new invariant(Object);
    }
 }

 BANG! (dmd v2.014)
 variable test.Foo.bar.__result cannot modify invariant

 ...

 Of course, I have some theories, but I wouldn't come here if they were good,
so I'll keep them for myself. Tell me yours.

 cheers.
D's contracts allow you to put an out contract on a function to see what the result of the function was: void foo() out(result) { /* check that result is reasonable */ } body { /* function body */ } When you declare a class invariant, it calls the invariant after each public method is called. My guess is that D is inserting an implicit "out(result) { assert(this); }" on each public method, but the out contract probably hasn't yet been updated and thinks typeof(result) is just Object, not invariant(Object). Hence, error. It's most likely a bug.
Oct 08 2008
parent reply mumba <qniol o2.pl> writes:
Jarrett Billingsley Wrote:

  My guess is that D is inserting an implicit
 "out(result) { assert(this); }" on each public method, but the out
 contract probably hasn't yet been updated and thinks typeof(result) is
 just Object, not invariant(Object).  Hence, error.
Sorry, but I don't understand this sentence :). What do you mean by "updated"? "assert(this) added"? I guess not, since this is what D is actually doing (beginning of the sentence) so how we can even expect having sth done before we did it? Is there some kind of "update" D performs in order to turn types to invariant(types)?
Oct 08 2008
parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Wed, Oct 8, 2008 at 3:31 PM, mumba <qniol o2.pl> wrote:
 Jarrett Billingsley Wrote:

  My guess is that D is inserting an implicit
 "out(result) { assert(this); }" on each public method, but the out
 contract probably hasn't yet been updated and thinks typeof(result) is
 just Object, not invariant(Object).  Hence, error.
Sorry, but I don't understand this sentence :). What do you mean by "updated"? "assert(this) added"? I guess not, since this is what D is actually doing (beginning of the sentence) so how we can even expect having sth done before we did it? Is there some kind of "update" D performs in order to turn types to invariant(types)?
By updated I mean that there seem to be some areas in the D2 compiler that still don't know about const and invariant. assert(this) calls the invariant of 'this'.
Oct 08 2008