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:
josh11b
2026-06-09 16:50:18 +00:00
committed by GitHub
co-authored by Josh L Dana Jansens
parent 233a58fcb1
commit d173121dc6
2 changed files with 55 additions and 47 deletions
+4
View File
@@ -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
View File
@@ -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)