-
-
Notifications
You must be signed in to change notification settings - Fork 54
Description
Please describe the bug
This is similar to #718 and came up when looking into that issue:
When we check if the implementation of a method matches the definition in the corresponding trait, we perform the comparison of implementation -> requirement. This however allows changing of ownership in ways that isn't sound, such as when a requirement defines a ref Foo argument but the implementation uses mut Foo. In the below example this allows mutating of A even though the contract of Example.method states that its argument should not be mutable.
type A {
let mut @value: Int
}
type B {}
trait Example {
fn method(argument: ref A)
}
impl Example for B {
fn method(argument: mut A) {
argument.value = 42
}
}
type async Main {
fn async main {
let a = A(0)
let b = B()
b.method(a)
}
}
Similar to closures we probably have to invert the comparison and check if the signature of the requirement is compatible with that of the implementation. In the above example that means we'd end up comparing ref A -> mut A which is invalid and thus the compiler would correctly produce a compile-time error.
Operating system
Fedora
Inko version
main