mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:10:14 +01:00
Name lookup design doc update (#7317)
Assisted-by: Gemini via Antigravity --------- Co-authored-by: Josh L <josh11b@users.noreply.github.com> Co-authored-by: Dana Jansens <danakj@orodu.net>
This commit is contained in:
co-authored by
Josh L
Dana Jansens
parent
233a58fcb1
commit
d173121dc6
@@ -101,6 +101,10 @@ fn Widgets.GrowSomeCogs() {
|
||||
}
|
||||
```
|
||||
|
||||
Note that `.` is used consistently for member access, whether it is applied to
|
||||
an object, type, or namespace. This is in contrast to C++, which uses `::` for
|
||||
types and namespaces.
|
||||
|
||||
Pointer member access expressions are those using a `->` instead of a `.` and
|
||||
their semantics are exactly what would result from first dereferencing the
|
||||
expression preceding the `->` and then forming a member access expression using
|
||||
|
||||
+51
-47
@@ -10,67 +10,53 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [TODO](#todo)
|
||||
- [Overview](#overview)
|
||||
- [Unqualified name lookup](#unqualified-name-lookup)
|
||||
- [Alternatives](#alternatives)
|
||||
- [Name lookup for common, standard types](#name-lookup-for-common-standard-types)
|
||||
- [Open questions](#open-questions)
|
||||
- [Shadowing](#shadowing)
|
||||
- [References](#references)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## TODO
|
||||
|
||||
This is a skeletal design, added to support [the overview](README.md). It should
|
||||
not be treated as accepted by the core team; rather, it is a placeholder until
|
||||
we have more time to examine this detail. Please feel welcome to rewrite and
|
||||
update as appropriate.
|
||||
|
||||
## Overview
|
||||
|
||||
Names are always introduced into some scope which defines where they can be
|
||||
referenced. Many of these scopes are themselves named. Carbon has a special
|
||||
facility for introducing a dedicated named scope just like C++, but we traverse
|
||||
nested names in a uniform way with `.`-separated names:
|
||||
|
||||
```
|
||||
namespace Foo {
|
||||
namespace Bar {
|
||||
alias ??? MyInt = Int;
|
||||
}
|
||||
}
|
||||
|
||||
fn F(x: Foo.Bar.MyInt);
|
||||
```
|
||||
|
||||
Carbon packages are also namespaces so to get to an imported name from the
|
||||
`Abseil` package you would write `Abseil.Foo`. The "top-level" file scope is
|
||||
that of the Carbon package containing the file, meaning that there is no
|
||||
"global" scope. Dedicated namespaces can be reopened within a package, but there
|
||||
is no way to reopen a package without being a library and file _within_ that
|
||||
package.
|
||||
|
||||
Note that libraries (unlike packages) do **not** introduce a scope, they share
|
||||
the scope of their package. This is based on the observation that in practice, a
|
||||
fairly coarse scoping tends to work best, with some degree of global registry to
|
||||
establish a unique package name.
|
||||
referenced. Many of these scopes are themselves named. For example, types are
|
||||
named, and name scopes can be defined directly with `namespace`, see
|
||||
["Code and name organization"](code_and_name_organization/README.md#namespaces).
|
||||
|
||||
### Unqualified name lookup
|
||||
|
||||
Unqualified name lookup in Carbon will always find a file-local result, other
|
||||
than the implicit "prelude" of importing and aliasing the fundamentals of the
|
||||
standard library. There will be an explicit mention of the name in the file that
|
||||
declares the name in the current or enclosing scope, which must also precede the
|
||||
reference.
|
||||
Unqualified name lookup in Carbon searches the current and enclosing scopes up
|
||||
to the top-level file scope. Names found include:
|
||||
|
||||
#### Alternatives
|
||||
- Locally declared names in the current scope or any enclosing scope, where
|
||||
the declaration must precede the reference.
|
||||
- When an out-of-line declaration or definition is qualified by a scope or
|
||||
nested scopes (such as `fn Foo.Bar(...)`), the scopes nominated by the
|
||||
qualifier (`Foo` and `Foo.Bar`) act as enclosing scopes for unqualified
|
||||
name lookup within that declaration's signature and body. This applies
|
||||
to namespaces, classes, and interfaces.
|
||||
- Names from the current package that are visible by being imported (such as
|
||||
with `import library "..."`), including the implicit import of the API file
|
||||
from an `impl` file.
|
||||
- The implicit "prelude" of importing and aliasing the fundamentals of the
|
||||
standard library.
|
||||
|
||||
This implies that other names within your own package but not declared within
|
||||
the file must be found by way of the package name. It isn't clear if this is the
|
||||
desirable end state. We need to consider alternatives where names from the same
|
||||
library or any library in the same package are made immediately visible within
|
||||
the package scope for unqualified name lookup.
|
||||
Note that a package's name is not injected into the scope of its files, and
|
||||
imports within a single package do not specify the package name. Symbols from
|
||||
other packages must be imported and accessed through their package namespace.
|
||||
|
||||
In declarative scopes (such as namespaces, classes, and interfaces), if
|
||||
unqualified name lookup is performed for a name and fails to find it, that name
|
||||
is said to be _poisoned_ in that scope. It is an error if a poisoned name is
|
||||
later introduced in that scope, as that would alter the meaning of earlier
|
||||
lookups. Within a library, poisoned names persist from the API file to
|
||||
implementation files.
|
||||
|
||||
In sequential scopes (such as function bodies), redeclaring an entity is
|
||||
disallowed.
|
||||
|
||||
### Name lookup for common, standard types
|
||||
|
||||
@@ -86,5 +72,23 @@ operators and `for` loops, is defined in terms of interfaces in the prelude.
|
||||
|
||||
### Shadowing
|
||||
|
||||
We can probably disallow the use of shadowed unqualified names, but the actual
|
||||
design for such needs to be thought through.
|
||||
Name shadowing has been discussed in proposals
|
||||
[#3763: Matching redeclarations](/proposals/p003763-matching-redeclarations.md#use-package-wide-name-poisoning).
|
||||
One rule under consideration is:
|
||||
|
||||
> Always look in all enclosing scopes, and diagnose an ambiguity if an
|
||||
> unqualified name is found in more than one enclosing scope.
|
||||
|
||||
This is aligned with the
|
||||
[name shadowing discussion in the "low context-sensitivity" principle](/docs/project/principles/low_context_sensitivity.md#name-shadowing).
|
||||
|
||||
## References
|
||||
|
||||
- Proposal
|
||||
[#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107)
|
||||
- Proposal
|
||||
[#2287: Allow unqualified name lookup](https://github.com/carbon-language/carbon-lang/pull/2287)
|
||||
- Proposal
|
||||
[#2550: Simplified package declaration for the `Main` package](https://github.com/carbon-language/carbon-lang/pull/2550)
|
||||
- Proposal
|
||||
[#3763: Matching redeclarations](https://github.com/carbon-language/carbon-lang/pull/3763)
|
||||
|
||||
Reference in New Issue
Block a user