Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add explanation for counterintuitiveness of lifetime subtyping #1447

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/subtyping.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ fn bar<'a>() {
Since `'static` outlives the lifetime parameter `'a`, `&'static str` is a
subtype of `&'a str`.

Subtyping on lifetimes is in terms of that relationship: if `'a: 'b` ("`'a` outlives `'b`" or "`'a >= 'b`" or `'a` contains `'b`"), then `'a` is a subtype of `'b`. This is a large source of confusion, because it seems intuitively backwards to many: the bigger scope is a subtype of the smaller scope. This does in fact make sense, though. The intuitive reason for this is that if you expect an `&'a u8` (for some concrete 'a that you have already chosen), then it's totally fine for me to hand you an `&'static u8` even if `'static != 'a`, in the same way that if you expect an Animal trait, it's totally fine to hand you a Cat. Cats are just Animals and more, just as `'static` is just `'a` and more.

[Higher-ranked]&#32;[function pointers] and [trait objects] have another
subtype relation. They are subtypes of types that are given by substitutions of
the higher-ranked lifetimes. Some examples:
Expand Down