Don't duplicate match checks for inherited trait bodies
Due to how we were doing match checks, some usages of match in default method bodies of traits and interfaces could end up failing checking once they were "inherited" by the implementing class.
For example, the following failed to compile:
primitive Prim
fun ignore() => None
trait A
fun union(): (Prim | None)
fun match_it(): Bool =>
match union()
| let p: Prim =>
p.ignore()
true
| None =>
false
end
class B is A
fun union(): Prim =>
Prim
We've updated to only do the match checks checking the trait's default method bodies.
Don't duplicate visibility tests for inherited trait bodies
Due to how we were implementing name lookups, some usages of calling private methods on a trait from within the body of a default method on the same trait would fail if a class from outside the package tried to implement the trait.
For example, if you defined the following trait:
trait T
fun _override(): (T | None)
fun _with_default() =>
"""
Will compile if #4613 remains fixed. Otherwise, this will fail to
compiled IFF a class from outside this package implements this trait
and inherits this default method
"""
match _override()
| let t: T =>
t._with_default()
| None =>
None
end
And then in another package tried to create a class that implemented the trait and inherited the method body for _with_default
, you would get a compilation error stating that you can't lookup the private method _with_default
from outside the package. This error happened because the call to t._with_default()
in the trait was "losing the context of the call". This simple class was all that was needed to trigger the bug:
class C is T
fun _override(): (T | None) =>
None
We've updated the compiler to only check name visibility at the time the trait is not type checked, not each time a class that has inherited a default method body from a trait is checked.