gracelang / minigrace

Self-hosting compiler for the Grace programming language
39 stars 22 forks source link

Stale object treated as fresh #313

Open apblack opened 4 years ago

apblack commented 4 years ago

The following code (from patterns+typesBundle) does not always create a fresh object:

method TypeIntersection (t1, t2) {
    if (t2.isType.not) then { return t2 & t1 }   // double-dispatch to Pattern t2
    if (t1.isNone) then {return t1}
    if (t2.isNone) then {return t2}
    object {
        use AndPattern (t1, t2)
            alias matchHook(_) = matches(_)
            exclude &(_)
            exclude |(_)
            exclude matches(_)
            exclude isType
        use BaseType
        var name is readable := "‹anon›"
        method methodNames {
            merge(t1.methodNames, t2.methodNames)
        }
        method asString {
            if (self.name == "‹anon›") then {
                "({t1} & {t2})"
            } else {
                "type {self.name}"
            }
        }
    }
}

This is because the early returns at the start of the method can return a "stale" (i.e., not fresh) object. Nevertheless, it is treated as if it always created a fresh method. The wrapper that calls the init function on the newly-created object then fails because there isn't an init function.