diff --git a/src/subtyping.md b/src/subtyping.md index 79b29be..8c8a180 100644 --- a/src/subtyping.md +++ b/src/subtyping.md @@ -1,5 +1,45 @@ # Subtyping and Variance +Rust uses lifetimes to track the relationships between borrows and ownership. +However, a naive implementation of lifetimes would be either too restrictive, +or permit undefined behaviour. Let's see a few examples: + +```rust,ignore +fn debug<'a>(a: &'a str, b: &'a str) { + println!("a = {:?} b = {:?}", a, b) +} + +fn main() { + let a: &'static str = "hello"; + { + let b = String::from("world"); + let b = &b; // 'b has a shorter lifetime than 'static + debug(a, b); + } +} +``` + +In an overly restrictive implementation of lifetimes, since `a` and `b` have differeing lifetimes, +we might see the following error: + +```text +error[E0308]: mismatched types + --> src/main.rs:6:16 + | +6 | debug(a, b); + | ^ + | | + | expected `&'static str`, found struct `&'b str` +``` + +This is over-restrictive. In this case, what we want is to accept any type that lives "at least as long" as `<'a>`. +This is what subtyping is intended to fix. + +Let's define lifetime `'a` to be a `subtype` of lifetime `'b`, if and only if `'a` lives _at least as long_ as `'b`. +We will denote this as `'a: 'b` + +--- + Subtyping is a relationship between types that allows statically typed languages to be a bit more flexible and permissive.