-
Notifications
You must be signed in to change notification settings - Fork 490
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
Start documenting name resolution. #937
Conversation
I tried hard to make this accurate, but there are almost certainly some mistakes (or things people would present differently). Please be gentle. 😄 I explicitly did not update the rest of the reference to specify how things are introduced into different namespaces. For example, the Other uncertainties:
TerminologyThis introduces a new term "entity" to refer to types/items/values/macros/lifetimes/etc. I'd like to defend that choice, as I think it is useful to have a single term to refer to that soup of things. Also, I find that term is used in several other language specs and programming literature. I waffled a bit on using "name" as an explicit term. There is a bit of a vague overlap between "name", "identifier", "label", and "path". I think "name" is very commonly used in other language specs and literature (and follows more naturally with "namespaces" and "name resolution", and is how rustc internally refers to them as "name bindings"). I'm not sure if how I presented it is entirely clear, though. |
I'll look at this tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, overall, I like what I'm seeing. This is a huge chunk of language that makes describing other parts of the language a lot more precise. Like, I could gleefully work on expressions/path-expr.md
using this terminology.
Except, I don't like saying that the things that introduce names are entities themselves. I rather think that items introduce entities and names separately. The entity stands alone in some abstract entity space where names don't exist while the name is attached to a scope in a specified namespace that points to the element in entity space. I'm probably missing some subtlety in my definition even; this stuff is hard to think about. But by separating it out like this, it lets us:
- separate the lexical element (e.g. an item) from what the lexical element introduces
- say that a single lexical element introduces multiple entities and names
- say the crate root is an entity, and if you think it is not, one can create an alias to it
I have some half-finished thoughts in my head that a name can also be attached to an entity. For example, mod foo { struct Bar; }
would have Bar
attached to Foo
, and that this attachment is what lets foo::Bar
work. Then the preludes can introduce the names into module scope but without attaching them. This also lets us attach associated items to the item they associate to.
I'm also not sure how non-static method names fit in all of this.
src/glossary.md
Outdated
@@ -61,6 +61,11 @@ through a mechanism called ‘trait objects’. | |||
|
|||
A dynamically sized type (DST) is a type without a statically known size or alignment. | |||
|
|||
### Entity | |||
|
|||
An [*entity*] is a [type], [item], [generic parameter], [variable binding], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not gonna sugar coat this, so: this definition is atrocious. Anybody reading it will be "but why combine these things into one group?"
I'd offer a suggestion for a better definition, but I have opinions on the current definition anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, yea, it is difficult to define "entity" since it is a bit of a nebulous concept that is only defined by the list of things it encompasses. Some examples of how others handle it:
C++: "An entity is a value, object, reference, structured binding, function, enumerator, type, class member, bit-field,template, template specialization, namespace, or parameter pack."
Ada: Doesn't directly say what an "entity" is, other than "A declaration is a language construct that associates a name with (a view of) an entity."
Java: Defines entity as the list (similar to how I did): "A declared entity (§6.1) is a package, class type (normal or enum), …". It tends to be use the term "declared entity" more formally.
ECMA 334 (C#): Doesn't seem to ever define it, but uses it all over such as "The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name."
Go: Doesn't define it, but uses it offhand like "While the identifier of the inner declaration is in scope, it denotes the entity declared by the inner declaration."
Haskell 2010: "We use the term entity to refer to a value, type, or class defined in, imported into, or perhaps exported from a module"
Typescript: Uses the term "entity" all over without explicitly defining it.
IEEE 24765: "in computer programming, any item that can be named or denoted in a program." (among several other more vague definitions)
I took another stab at making it more explicit, though I think defining it as a list of things is also valid.
src/names/namespaces.md
Outdated
@@ -0,0 +1,148 @@ | |||
# Namespaces | |||
|
|||
Entity names are segregated into separate *namespaces* based on the kind of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't actually define what a namespace is. How about something like...
A *namespace* is a set of names where each name unambiguously refers to a specific entity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If two glob imports import the same name inside the value namespace, that it is still a namespace despite ambiguity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow the point about glob imports. A conflict with two glob imports like that is an error (that is, an invalid program). Other valid circumstances have rules that disambiguate what name is introduced. I wouldn't consider that to be ambiguous when there are rules on which name is used.
src/names.md
Outdated
|
||
Entities that explicitly introduce a name in the source code are: | ||
|
||
* [Items] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit.
* [Items] | |
* [Items]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I think I had that originally, but removed it due to the risk that markdown would "eat" it. For example, if you have a single word after the colon, like * [Boolean type]: `bool`
, it just disappears since it is interpreted as a link reference. It should be safe otherwise, though.
src/names.md
Outdated
* [External block items] | ||
* [`macro_rules` declarations] and [matcher metavariables] | ||
* [Implementation] associated items | ||
* [Expressions] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit.
* [Expressions] | |
* [Expressions]: |
I believe this is #23, correct? I think method-call-expr doesn't do a horrible job of covering it. |
+1 |
src/glossary.md
Outdated
A [*namespace*] is a set of [names](#name) where each name unambiguously | ||
refers to a specific [entity](#entity). Namespaces are organized in a | ||
hierarchy, where each level of the hierarchy has its own collection of named | ||
entities. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this is what is called "scope" in the compiler (https://github.com/rust-lang/rust/blob/master/compiler/rustc_resolve/src/lib.rs#L102-L115)? ("Scope" in the compiler is also overloaded and used for other things.)
"Namespace" in the compiler is one of "type", "value" and "macro" (+ perhaps "lifetime" and "label", but they are separate).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok, it's not a "scope", but the wording is confusing.
set of names where each name unambiguously
refers to a specific entity
This is plain indecipherable.
Namespaces are organized in a hierarchy
And this should somehow highlight that the hierarchies exist inside the namespaces, and not between them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I'm struggling to define it clearly. Lexicography is not my strong suit. I took another stab at it.
I suspect this will receive updates and clarifications once I start working on the "scopes" chapter.
# Preludes | ||
|
||
A *prelude* is a collection of names that are automatically brought into scope | ||
of every module in a crate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, originally "prelude" meant simply a piece of code inserted by the compiler at the start of the crate, like
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
, not a set of names.
Then I used it as a temporary name / analogy for built-in types ("language prelude") and extern crates ("extern prelude"), because they behaved similarly to the actual prelude import, and then it stuck.
I still have no idea whether the name "prelude" sounds reasonable in the meaning "set of names" to native speakers, or to users of languages from which this term originally came.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm personally comfortable with it. I think the behavior is similar enough ("importing these things into every module"). I think it will help later when talking about behaviors in how names are resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still have no idea whether the name "prelude" sounds reasonable in the meaning "set of names" to native speakers, or to users of languages from which this term originally came.
As a native speaker, I think of "prelude" as a jargon term the same way "macro" or "scope" is. Those words all have meanings outside programming, but the connection to the jargon term is tenuous at best. I think "prelude" is useful as an existing jargon term that's used in other languages, though.
src/names/preludes.md
Outdated
library prelude], [extern prelude], or [tool prelude] into scope for that | ||
module or any of its descendants. | ||
|
||
This attribute does not affect the [language prelude] or [`macro_use` prelude]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It affects macro_use
prelude on >=2018 edition.
The plan was to exclude macro_use
prelude on both editions (rust-lang/rust#55630), but I never got to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, sorry I missed that. For various reasons, I do all my testing in 2015, and I didn't think to try 2018. I even saw that code, and somehow forgot to double-check it. I thought it was weird that it didn't affect macro_use
.
* Fix: no_implicit_prelude behaves differently in 2015. * Try to make it clearer how standard library stuff is injected into the crate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see nothing further I'd like to see changed. This comment is to remove my "needs change" mark on the PR.
@petrochenkov can you approve and merge once you're satisfied yourself?
@Havvy |
Update books ## nomicon 7 commits in a8584998eacdea7106a1dfafcbf6c1c06fcdf925..bbf06ad39d1f45654047e9596b750cc6e6d1b693 2021-01-06 12:49:49 -0500 to 2021-01-22 07:07:31 -0800 - Fix alloc link in exotic-sizes for local docs (rust-lang/nomicon#255) - Remove TODO - Fix small punctuation error - Arc revisions (Clone atomic explanation) (pt2/3(+?)) - Fix Arc Clone - Arc revisions (pt1/2(+?)) - Simple Arc implementation (without Weak refs) ## reference 5 commits in 50af691f838937c300b47812d0507c6d88c14f97..f02b09eb6e8af340ad1256a54adb7aae2ff3163e 2021-01-12 21:19:20 -0800 to 2021-01-22 01:53:02 -0800 - Fix missing space (rust-lang/reference#941) - Start documenting name resolution. (rust-lang/reference#937) - Fix plural and delete spurious words in comparison ops (rust-lang/reference#932) - Document execution order (rust-lang/reference#888) - Compound operator expressions (rust-lang/reference#915) ## book 3 commits in ac57a0ddd23d173b26731ccf939f3ba729753275..e724bd826580ff95df48a8533af7dec1080693d4 2021-01-09 14:18:45 -0500 to 2021-01-20 08:19:49 -0600 - Fixes rust-lang/book#2417. Get the index from user input instead of a const. (rust-lang/book#2566) - Turn off the playground in a bunch more lib.rs inclusions (rust-lang/book#2569) - Merge pull request rust-lang/book#2567 from rust-lang/rust-1.49 ## rust-by-example 1 commits in 03e23af01f0b4f83a3a513da280e1ca92587f2ec..f633769acef68574427a6fae6c06f13bc2199573 2021-01-09 10:20:28 -0300 to 2021-01-13 20:58:25 -0300 - Fixed styling on closure example (rust-lang/rust-by-example#1405)
Update books ## nomicon 7 commits in a8584998eacdea7106a1dfafcbf6c1c06fcdf925..bbf06ad39d1f45654047e9596b750cc6e6d1b693 2021-01-06 12:49:49 -0500 to 2021-01-22 07:07:31 -0800 - Fix alloc link in exotic-sizes for local docs (rust-lang/nomicon#255) - Remove TODO - Fix small punctuation error - Arc revisions (Clone atomic explanation) (pt2/3(+?)) - Fix Arc Clone - Arc revisions (pt1/2(+?)) - Simple Arc implementation (without Weak refs) ## reference 5 commits in 50af691f838937c300b47812d0507c6d88c14f97..f02b09eb6e8af340ad1256a54adb7aae2ff3163e 2021-01-12 21:19:20 -0800 to 2021-01-22 01:53:02 -0800 - Fix missing space (rust-lang/reference#941) - Start documenting name resolution. (rust-lang/reference#937) - Fix plural and delete spurious words in comparison ops (rust-lang/reference#932) - Document execution order (rust-lang/reference#888) - Compound operator expressions (rust-lang/reference#915) ## book 3 commits in ac57a0ddd23d173b26731ccf939f3ba729753275..e724bd826580ff95df48a8533af7dec1080693d4 2021-01-09 14:18:45 -0500 to 2021-01-20 08:19:49 -0600 - Fixes rust-lang/book#2417. Get the index from user input instead of a const. (rust-lang/book#2566) - Turn off the playground in a bunch more lib.rs inclusions (rust-lang/book#2569) - Merge pull request rust-lang/book#2567 from rust-lang/rust-1.49 ## rust-by-example 1 commits in 03e23af01f0b4f83a3a513da280e1ca92587f2ec..f633769acef68574427a6fae6c06f13bc2199573 2021-01-09 10:20:28 -0300 to 2021-01-13 20:58:25 -0300 - Fixed styling on closure example (rust-lang/rust-by-example#1405)
Update link for extern prelude. There was some reorganization in the reference as part of rust-lang/reference#937.
Update link for no_std attribute. There was some reorganization in the reference as part of rust-lang/reference#937.
This is a very small start to making progress on documenting name resolution (#568). This PR focuses on:
Closes #924.