fn main() { // Note: here we do not have any type annotations // but we do express conflicting requirements: let v = [mut [0]]; let w = [mut [mut 0]]; let x = [mut [mut 0]]; fn f(&&v: [mut [int]]) { v[0] = [3] } fn g(&&v: [const [const int]]) { } fn h(&&v: [mut [mut int]]) { v[0] = [mut 3] } fn i(&&v: [mut [const int]]) { v[0] = [mut 3] } fn j(&&v: [[const int]]) { } f(v); g(v); h(v); //! ERROR (values differ in mutability) i(v); //! ERROR (values differ in mutability) j(v); //! ERROR (values differ in mutability) f(w); //! ERROR (values differ in mutability) g(w); h(w); i(w); //! ERROR (values differ in mutability) j(w); //! ERROR (values differ in mutability) // Note that without adding f() or h() to the mix, it is valid for // x to have the type [mut [const int]], and thus we can safely // call g() and i() but not j(): g(x); i(x); j(x); //! ERROR (values differ in mutability) }