TMI: Fun with default methods
Jan. 7th, 2013 07:58 pmI finished one pull request, which fixes 3563 and got most of the way along to finishing another, that one for issue 3979.
Both issues involve default methods, which are a new feature that's not quite baked yet (so much so that for 0.5, we turned it off by default). #3563 had a couple of test cases attached; in the simplest one, calling a non-existent method on self inside a default method would cause an internal compiler error during typechecking. This turns out to be because the typechecker assumes that anything with the type self is the value self (a special name that refers to the self object inside either an implementation of a trait, or a default method in a trait). The simplest fix for this I could see was to treat self as if it has dynamic scope, just for typechecking purposes. That is, instead of throwing away the self ID from the enclosing scope when typechecking a nested closure, keep the same one, so closures inside default methods can refer to self. This seems a little bit dirty (as if it might enable out-of-scope uses of self), but I *think* it's okay because in the Rust compiler, name resolution is a separate pass from typechecking, and happens first. So if you tried to do something fishy with self, resolve would catch it before typechecking ever happened.
Issue 3979 showed that you couldn't call a supertrait method inside a default method. After quite a bit of fumbling, I fixed the test case shown in the issue report, but while working on it I noted to myself that I should check at least two more cases (supertraits with type parameters, and the case where you define the traits in a separate crate from the impls of them). Once I wrote those two test cases and ran them, it turned out neither of them works. So I can't submit this one quite yet (in good conscience).
Both issues involve default methods, which are a new feature that's not quite baked yet (so much so that for 0.5, we turned it off by default). #3563 had a couple of test cases attached; in the simplest one, calling a non-existent method on self inside a default method would cause an internal compiler error during typechecking. This turns out to be because the typechecker assumes that anything with the type self is the value self (a special name that refers to the self object inside either an implementation of a trait, or a default method in a trait). The simplest fix for this I could see was to treat self as if it has dynamic scope, just for typechecking purposes. That is, instead of throwing away the self ID from the enclosing scope when typechecking a nested closure, keep the same one, so closures inside default methods can refer to self. This seems a little bit dirty (as if it might enable out-of-scope uses of self), but I *think* it's okay because in the Rust compiler, name resolution is a separate pass from typechecking, and happens first. So if you tried to do something fishy with self, resolve would catch it before typechecking ever happened.
Issue 3979 showed that you couldn't call a supertrait method inside a default method. After quite a bit of fumbling, I fixed the test case shown in the issue report, but while working on it I noted to myself that I should check at least two more cases (supertraits with type parameters, and the case where you define the traits in a separate crate from the impls of them). Once I wrote those two test cases and ran them, it turned out neither of them works. So I can't submit this one quite yet (in good conscience).