Skip to content

Add a bit about various type system concepts #697

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

Merged
merged 14 commits into from
Jun 5, 2020

Conversation

mark-i-m
Copy link
Member

@mark-i-m mark-i-m commented May 7, 2020

@spastorino
Copy link
Member

This looks good!

@nikomatsakis nikomatsakis self-assigned this May 14, 2020
@mark-i-m
Copy link
Member Author

@nikomatsakis I think I addressed your comments. Could you take a look at the beginning of the early/late bounds chapter again? (basically the last commit)...

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, the text doesn't seem quite right ..

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good, should land it :)

@@ -0,0 +1,90 @@
# Early and Late Bound Variables

In Rust, generic types are generally [_universally_ quantified][quant].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, I think I would phrase this like so

In Rust, item definitions (like fn) can often have generic parameters, which are always [universally quantified][quant]. That is, if you have a function like

fn foo<T>(x: T) { }

this function is defined "for all T" (not "for some specific T", which would be existentially quantified).

While Rust items can be quantified over types, lifetimes, and constants, the types of values in Rust are only ever quantified over lifetimes. So you can have a type like for<'a> fn(&'a u32), which represents a function pointer that takes a reference with any lifetime, or for<'a> dyn Trait<'a>, which is a dyn trait for a trait implemented for any lifetime; but we have no type like for<T> fn(T), which would be a function that takes a value of any type as a parameter. This is a consequence of monomorphization -- to support a value of type for<T> fn(T), we would need a single function pointer that can be used for a parameter of any type, but in Rust we generate customized code for each parameter type.

One consequence of this asymmetry is a weird split in how we represesent some generic types: early- and late- bound parameters.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced the intro with this (let me know if I didn't replace enough). Sorry, I'm only slowly starting to understand this distinction; you're intro helps a lot.

mark-i-m and others added 2 commits June 5, 2020 10:22
Co-authored-by: Niko Matsakis <niko@alum.mit.edu>
@mark-i-m mark-i-m force-pushed the early-late-bounds branch from ea3bfbb to 933d559 Compare June 5, 2020 15:23
@spastorino spastorino merged commit caac584 into rust-lang:master Jun 5, 2020
@mark-i-m mark-i-m deleted the early-late-bounds branch June 5, 2020 16:39
@mark-i-m
Copy link
Member Author

mark-i-m commented Jun 5, 2020

Oh, huh? I thought I had already merged it! Sorry!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

region name resolution, early vs late bound lifetimes
4 participants