Skip to content

Instantly share code, notes, and snippets.

@VigneshChennai
Last active July 26, 2022 15:40
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save VigneshChennai/5a56c8ad4ed563c820f37e5cea8ecb88 to your computer and use it in GitHub Desktop.
Save VigneshChennai/5a56c8ad4ed563c820f37e5cea8ecb88 to your computer and use it in GitHub Desktop.
Covariant and Invariant - Rust Example
struct CovariantExample<'a, T> {
a: &'a T
}
struct InvariantExample<'a, T> {
a: &'a mut T
}
fn covarient() {
let a = 1;
let v2: &i32 = &a;
let c1 = CovariantExample::<&'static i32> {a: &&1};
let c2 = CovariantExample::<&i32> {a: &v2};
let mut c3 = &c2;
c3 = &c1; // ==> This will works as CovariantExample<T> is covariant to T
}
fn invarient() {
let a = 1;
let mut v2: &i32 = &a;
let c1 = InvariantExample::<&'static i32> {a: &mut &1 };
let c2 = InvariantExample::<&i32> {a: &mut v2};
let mut c3 = &c2;
// the below will fail to compile
c3 = &c1; // ==> This will fail to compile as InvariantExample<T> is invariant to T
}
fn main() {
covarient();
invarient();
}
@VigneshChennai
Copy link
Author

The compilation fails with the compiler complaining about "variable a 'not live long enough'"


error[E0597]: `a` does not live long enough
  --> src/main.rs:27:24
   |
27 |     let mut v2: &i32 = &a;
   |                        ^^
   |                        |
   |                        borrowed value does not live long enough
   |                        assignment requires that `a` is borrowed for `'static`
...
35 | }
   | - `a` dropped here while still borrowed

It is due to the reason that, due to the line 34, the compile tries to make c2 type as InvariantExample<&'static i32>. It does it because InvariantExample<T> is invariant over T. So, it can't pass InvariantExample::<&'static i32> where InvariantExample::<&i32> is needed.

PS:

  1. Theoretical Explanation https://doc.rust-lang.org/nomicon/subtyping.html
  2. Compiler version used: rustc 1.48.0 (7eac88abb 2020-11-16)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment