mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 13:31:06 +01:00
Design overview update part 5: Names (#1347)
This follows #1274 , #1325 , #1328 , and #1336 . It fills in the "Names" section. Co-authored-by: Richard Smith <richard@metafoo.co.uk> Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This commit is contained in:
co-authored by
Richard Smith
Chandler Carruth
parent
3603db0a08
commit
5535f5ee30
+407
-83
@@ -63,13 +63,16 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
- [Destructors](#destructors)
|
||||
- [Choice types](#choice-types)
|
||||
- [Names](#names)
|
||||
- [Packages, libraries, namespaces](#packages-libraries-namespaces)
|
||||
- [Legal names](#legal-names)
|
||||
- [Files, libraries, packages](#files-libraries-packages)
|
||||
- [Package declaration](#package-declaration)
|
||||
- [Imports](#imports)
|
||||
- [Name visibility](#name-visibility)
|
||||
- [Package scope](#package-scope)
|
||||
- [Namespaces](#namespaces)
|
||||
- [Naming conventions](#naming-conventions)
|
||||
- [Aliases](#aliases)
|
||||
- [Name lookup](#name-lookup)
|
||||
- [Name lookup for common types](#name-lookup-for-common-types)
|
||||
- [Name visibility](#name-visibility)
|
||||
- [Generics](#generics)
|
||||
- [Checked and template parameters](#checked-and-template-parameters)
|
||||
- [Interfaces and implementations](#interfaces-and-implementations)
|
||||
@@ -561,18 +564,40 @@ are applied to convert the expression to the target type.
|
||||
|
||||
_Declarations_ introduce a new [name](#names) and say what that name represents.
|
||||
For some kinds of entities, like [functions](#functions), there are two kinds of
|
||||
declarations: _forward declarations_ and _definitions_. In this case, there
|
||||
should be exactly one definition for the name, but there can be additional
|
||||
forward declarations that introduce the name before it is defined. Forward
|
||||
declarations allow cyclic references, and can be used to declare a name in an
|
||||
[api file](#packages-libraries-namespaces) that is defined in an
|
||||
[impl file](#packages-libraries-namespaces). A name that has been declared but
|
||||
not defined is called _incomplete_, and in some cases there are limitations on
|
||||
what can be done with an incomplete name.
|
||||
declarations: _forward declarations_ and _definitions_. For those entities,
|
||||
there should be exactly one definition for the name, and at most one additional
|
||||
forward declaration that introduces the name before it is defined, plus any
|
||||
number of declarations in a
|
||||
[`match_first` block](generics/details.md#prioritization-rule). Forward
|
||||
declarations can be used to separate interface from implementation, such as to
|
||||
declare a name in an [api file](#files-libraries-packages) that is defined in an
|
||||
[impl file](#files-libraries-packages). Forward declarations also allow entities
|
||||
to be used before they are defined, such as to allow cyclic references. A name
|
||||
that has been declared but not defined is called _incomplete_, and in some cases
|
||||
there are limitations on what can be done with an incomplete name. Within a
|
||||
definition, the defined name is incomplete until the end of the definition is
|
||||
reached, but is complete in the bodies of member functions because they are
|
||||
[parsed as if they appeared after the definition](#class-functions-and-factory-functions).
|
||||
|
||||
A name is valid until the end of the innermost enclosing
|
||||
[_scope_](<https://en.wikipedia.org/wiki/Scope_(computer_science)>). Except for
|
||||
the outermost scope, scopes are enclosed in curly braces (`{`...`}`).
|
||||
[_scope_](<https://en.wikipedia.org/wiki/Scope_(computer_science)>). There are a
|
||||
few kinds of scopes:
|
||||
|
||||
- the outermost scope, which includes the whole file,
|
||||
- scopes that are enclosed in curly braces (`{`...`}`), and
|
||||
- scopes that encompass a single declaration.
|
||||
|
||||
For example, the names of the parameters of a [function](#functions) or
|
||||
[class](#classes) are valid until the end of the declaration. The name of the
|
||||
function or class itself is visible until the end of the enclosing scope.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Principle: Information accumulation](/docs/project/principles/information_accumulation.md)
|
||||
> - Proposal
|
||||
> [#875: Principle: information accumulation](https://github.com/carbon-language/carbon-lang/pull/875)
|
||||
> - Question-for-leads issue
|
||||
> [#472: Open question: Calling functions defined later in the same file](https://github.com/carbon-language/carbon-lang/issues/472)
|
||||
|
||||
## Patterns
|
||||
|
||||
@@ -780,6 +805,9 @@ the `var` keyword is added before the binding, then the arguments will be copied
|
||||
to new storage, and so can be mutated in the function body. The copy ensures
|
||||
that any mutations will not be visible to the caller.
|
||||
|
||||
The parameter names in a forward declaration may be omitted using `_`, but must
|
||||
match the definition if they are specified.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Functions](functions.md)
|
||||
@@ -789,6 +817,8 @@ that any mutations will not be visible to the caller.
|
||||
> [#438: Add statement syntax for function declarations](https://github.com/carbon-language/carbon-lang/pull/438)
|
||||
> - Question-for-leads issue
|
||||
> [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476)
|
||||
> - Question-for-leads issue
|
||||
> [#1132: How do we match forward declarations with their definitions?](https://github.com/carbon-language/carbon-lang/issues/1132)
|
||||
|
||||
### `auto` return type
|
||||
|
||||
@@ -1241,7 +1271,7 @@ class Point {
|
||||
Note that if the definition of a function is provided inside the class scope,
|
||||
the body is treated as if it was defined immediately after the outermost class
|
||||
definition. This means that members such as the fields will be considered
|
||||
defined even if their definitions are later in the source than the class
|
||||
declared even if their declarations are later in the source than the class
|
||||
function.
|
||||
|
||||
The [`returned var` feature](#returned-var) can be used if the address of the
|
||||
@@ -1541,34 +1571,218 @@ choice LikeABoolean { False, True }
|
||||
|
||||
## Names
|
||||
|
||||
### Packages, libraries, namespaces
|
||||
Names are introduced by [declarations](#declarations-definitions-and-scopes) and
|
||||
are valid until the end of the scope in which they appear. Code may not refer to
|
||||
names earlier in the source than they are declared. In executable scopes such as
|
||||
function bodies, names declared later are not found. In declarative scopes such
|
||||
as packages, classes, and interfaces, it is an error to refer to names declared
|
||||
later, except that inline class member function bodies are
|
||||
[parsed as if they appeared after the class](#class-functions-and-factory-functions).
|
||||
|
||||
A name in Carbon is formed from a sequence of letters, numbers, and underscores,
|
||||
and which starts with a letter. We intend to follow
|
||||
[Unicode's Annex 31](https://unicode.org/reports/tr31/) in selecting valid
|
||||
identifier characters, but a concrete set of valid characters has not been
|
||||
selected yet.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Lexical conventions](lexical_conventions)
|
||||
> - [Principle: Information accumulation](/docs/project/principles/information_accumulation.md)
|
||||
> - Proposal
|
||||
> [#142: Unicode source files](https://github.com/carbon-language/carbon-lang/pull/142)
|
||||
> - Question-for-leads issue
|
||||
> [#472: Open question: Calling functions defined later in the same file](https://github.com/carbon-language/carbon-lang/issues/472)
|
||||
> - Proposal
|
||||
> [#875: Principle: information accumulation](https://github.com/carbon-language/carbon-lang/pull/875)
|
||||
|
||||
### Files, libraries, packages
|
||||
|
||||
- **Files** are grouped into libraries, which are in turn grouped into
|
||||
packages.
|
||||
- **Libraries** are the granularity of code reuse through imports.
|
||||
- **Packages** are the unit of distribution.
|
||||
|
||||
Name paths in Carbon always start with the package name. Additional namespaces
|
||||
may be specified as desired.
|
||||
Each library must have exactly one `api` file. This file includes declarations
|
||||
for all public names of the library. Definitions for those declarations must be
|
||||
in some file in the library, either the `api` file or an `impl` file.
|
||||
|
||||
For example, this code declares a class `Geometry.Shapes.Flat.Circle` in a
|
||||
library `Geometry/OneSide`:
|
||||
Every package has its own namespace. This means libraries within a package need
|
||||
to coordinate to avoid name conflicts, but not across packages.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Code and name organization](code_and_name_organization)
|
||||
> - Proposal
|
||||
> [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107)
|
||||
|
||||
### Package declaration
|
||||
|
||||
Files start with an optional package declaration, consisting of:
|
||||
|
||||
- the `package` keyword introducer,
|
||||
- an optional identifier specifying the package name,
|
||||
- optional `library` followed by a string with the library name,
|
||||
- either `api` or `impl`, and
|
||||
- a terminating semicolon (`;`).
|
||||
|
||||
For example:
|
||||
|
||||
```carbon
|
||||
package Geometry library("OneSide") namespace Shapes;
|
||||
|
||||
namespace Flat;
|
||||
class Flat.Circle { ... }
|
||||
// Package name is `Geometry`.
|
||||
// Library name is "Shapes".
|
||||
// This file is an `api` file, not an `impl` file.
|
||||
package Geometry library "Shapes" api;
|
||||
```
|
||||
|
||||
This type can be used from another package:
|
||||
Parts of this declaration may be omitted:
|
||||
|
||||
- If the package name is omitted, as in `package library "Main" api;`, the
|
||||
file contributes to the default package. No other package may import from
|
||||
the default package.
|
||||
- If the library keyword is not specified, as in `package Geometry api;`, this
|
||||
file contributes to the default library.
|
||||
- If a file has no package declaration at all, it is the `api` file belonging
|
||||
to the default package and default library. This is particularly for tests
|
||||
and smaller examples. No other library can import this library even from
|
||||
within the default package. It can be split across multiple `impl` files
|
||||
using a `package impl;` package declaration.
|
||||
|
||||
A program need not use the default package, but if it does, it should contain
|
||||
the entry-point function. By default, the entry-point function is `Run` from the
|
||||
default package.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Code and name organization](code_and_name_organization)
|
||||
> - Proposal
|
||||
> [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107)
|
||||
|
||||
### Imports
|
||||
|
||||
After the package declaration, files may include `import` declarations. These
|
||||
include the package name and optionally `library` followed by the library name.
|
||||
If the library is omitted, the default library for that package is imported.
|
||||
|
||||
```carbon
|
||||
package ExampleUser;
|
||||
// Import the "Vector" library from the
|
||||
// `LinearAlgebra` package.
|
||||
import LinearAlgebra library "Vector";
|
||||
// Import the default library from the
|
||||
// `ArbitraryPrecision` package.
|
||||
import ArbitraryPrecision;
|
||||
```
|
||||
|
||||
import Geometry library "OneSide";
|
||||
The syntax `import PackageName ...` introduces the name `PackageName` as a
|
||||
[`private`](#name-visibility) name naming the given package. It cannot be used
|
||||
to import libraries of the current package. Importing additional libraries from
|
||||
that package makes additional members of `PackageName` visible.
|
||||
|
||||
fn Foo(Geometry.Shapes.Flat.Circle circle) { ... }
|
||||
Libraries from the current package are imported by omitting the package name.
|
||||
|
||||
```carbon
|
||||
// Import the "Vertex" library from the same package.
|
||||
import library "Vertex";
|
||||
// Import the default library from the same package.
|
||||
import library default;
|
||||
```
|
||||
|
||||
The `import library ...` syntax adds all the public top-level names within the
|
||||
given library to the top-level scope of the current file as
|
||||
[`private`](#name-visibility) names, and similarly for names in
|
||||
[namespaces](#namespaces).
|
||||
|
||||
Every `impl` file automatically imports the `api` file for its library.
|
||||
|
||||
All `import` declarations must appear before all other non-`package`
|
||||
declarations in the file.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Code and name organization](code_and_name_organization)
|
||||
> - Proposal
|
||||
> [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107)
|
||||
|
||||
### Name visibility
|
||||
|
||||
The names visible from an imported library are determined by these rules:
|
||||
|
||||
- Declarations in an `api` file are by default _public_, which means visible
|
||||
to any file that imports that library. This matches class members, which are
|
||||
also [default public](#access-control).
|
||||
- A `private` prefix on a declaration in an `api` file makes the name _library
|
||||
private_. This means the name is visible in the file and all `impl` files
|
||||
for the same library.
|
||||
- The visibility of a name is determined by its first declaration, considering
|
||||
`api` files before `impl` files. The `private` prefix is only allowed on the
|
||||
first declaration.
|
||||
- A name declared in an `impl` file and not the corresponding `api` file is
|
||||
_file private_, meaning visible in just that file. Its first declaration
|
||||
must be marked with a `private` prefix. **TODO:** This needs to be finalized
|
||||
in a proposal to resolve inconsistency between
|
||||
[#665](https://github.com/carbon-language/carbon-lang/issues/665#issuecomment-914661914)
|
||||
and [#1136](https://github.com/carbon-language/carbon-lang/issues/1136).
|
||||
- Private names don't conflict with names outside the region they're private
|
||||
to: two different libraries can have different private names `foo` without
|
||||
conflict, but a private name conflicts with a public name in the same scope.
|
||||
|
||||
At most one `api` file in a package transitively used in a program may declare a
|
||||
given name public.
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Exporting entities from an API file](code_and_name_organization/README.md#exporting-entities-from-an-api-file)
|
||||
> - Question-for-leads issue
|
||||
> [#665: `private` vs `public` _syntax_ strategy, as well as other visibility tools like `external`/`api`/etc.](https://github.com/carbon-language/carbon-lang/issues/665)
|
||||
> - Proposal
|
||||
> [#752: api file default public](https://github.com/carbon-language/carbon-lang/pull/752)
|
||||
> - Proposal
|
||||
> [#931: Generic impls access (details 4)](https://github.com/carbon-language/carbon-lang/pull/931)
|
||||
> - Question-for-leads issue
|
||||
> [#1136: what is the top-level scope in a source file, and what names are found there?](https://github.com/carbon-language/carbon-lang/issues/1136)
|
||||
|
||||
### Package scope
|
||||
|
||||
The top-level scope in a package is the scope of the package. This means:
|
||||
|
||||
- Within this scope (and its sub-namespaces), all visible names from the same
|
||||
package appear. This includes names from the same file, names from the `api`
|
||||
file of a library when inside an `impl` file, and names from imported
|
||||
libraries of the same package.
|
||||
- In scopes where package members might have a name conflict with something
|
||||
else, the syntax `package.Foo` can be used to name the `Foo` member of the
|
||||
current package.
|
||||
|
||||
In this example, the names `F` and `P` are used in a scope where they could mean
|
||||
two different things, and
|
||||
[qualifications are needed to disambiguate](#name-lookup):
|
||||
|
||||
```carbon
|
||||
import P;
|
||||
fn F();
|
||||
class C {
|
||||
fn F();
|
||||
class P {
|
||||
fn H();
|
||||
}
|
||||
fn G() {
|
||||
// ❌ Error: ambiguous whether `F` means
|
||||
// `package.F` or `package.C.F`.
|
||||
F();
|
||||
// ✅ Allowed: fully qualified
|
||||
package.F();
|
||||
package.C.F();
|
||||
// ✅ Allowed: unambiguous
|
||||
C.F();
|
||||
// ❌ Error: ambiguous whether `P` means
|
||||
// `package.P` or `package.P.F`.
|
||||
P.H();
|
||||
// ✅ Allowed
|
||||
package.P.H();
|
||||
package.C.P.H();
|
||||
C.P.H();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> References:
|
||||
@@ -1581,18 +1795,69 @@ fn Foo(Geometry.Shapes.Flat.Circle circle) { ... }
|
||||
> - Question-for-leads issue
|
||||
> [#1136: what is the top-level scope in a source file, and what names are found there?](https://github.com/carbon-language/carbon-lang/issues/1136)
|
||||
|
||||
### Legal names
|
||||
### Namespaces
|
||||
|
||||
Various constructs introduce a named entity in Carbon. These can be functions,
|
||||
types, variables, or other kinds of entities. A name in Carbon is formed from a
|
||||
word, which is a sequence of letters, numbers, and underscores, and which starts
|
||||
with a letter. We intend to follow Unicode's Annex 31 in selecting valid
|
||||
identifier characters, but a concrete set of valid characters has not been
|
||||
selected yet.
|
||||
A `namespace` declaration defines a name that may be used as a prefix of names
|
||||
declared afterward. When defining a member of a namespace, other members of that
|
||||
namespace are considered in scope and may be found by
|
||||
[name lookup](#name-lookup) without the namespace prefix. In this example,
|
||||
package `P` defines some of its members inside a namespace `N`:
|
||||
|
||||
> References: [Lexical conventions](lexical_conventions)
|
||||
```carbon
|
||||
package P api;
|
||||
|
||||
// Defines namespace `N` within the current package.
|
||||
namespace N;
|
||||
|
||||
// Defines namespaces `M` and `M.L`.
|
||||
namespace M.L;
|
||||
|
||||
fn F();
|
||||
// ✅ Allowed: Declares function `G` in namespace `N`.
|
||||
private fn N.G();
|
||||
// ❌ Error: `Bad` hasn't been declared.
|
||||
fn Bad.H();
|
||||
|
||||
fn J() {
|
||||
// ❌ Error: No `package.G`
|
||||
G();
|
||||
}
|
||||
|
||||
fn N.K() {
|
||||
// ✅ Allowed: Looks in both `package` and `package.N`.
|
||||
// Finds `package.F` and `package.N.G`.
|
||||
F();
|
||||
G();
|
||||
}
|
||||
|
||||
// ✅ Allowed: Declares function `R` in namespace `M.L`.
|
||||
fn M.L.R();
|
||||
// ✅ Allowed: Declares function `Q` in namespace `M`.
|
||||
fn M.Q();
|
||||
```
|
||||
|
||||
Another package importing `P` can refer to the public members of that namespace
|
||||
by prefixing with the package name `P` followed by the namespace:
|
||||
|
||||
```carbon
|
||||
import P;
|
||||
|
||||
// ✅ Allowed: `F` is public member of `P`.
|
||||
P.F();
|
||||
// ❌ Error: `N.G` is a private member of `P`.
|
||||
P.N.G();
|
||||
// ✅ Allowed: `N.K` is public member of `P`.
|
||||
P.N.K();
|
||||
// ✅ Allowed: `M.L.R` is public member of `P`.
|
||||
P.M.L.R();
|
||||
// ✅ Allowed: `M.Q` is public member of `P`.
|
||||
P.M.Q();
|
||||
```
|
||||
|
||||
> References:
|
||||
>
|
||||
> **TODO:** References need to be evolved.
|
||||
> - ["Namespaces" in "Code and name organization"](code_and_name_organization/README.md#namespaces)
|
||||
> - ["Package and namespace members" in "Qualified names and member access"](expressions/member_access.md#package-and-namespace-members)
|
||||
|
||||
### Naming conventions
|
||||
|
||||
@@ -1601,7 +1866,9 @@ Our naming conventions are:
|
||||
- For idiomatic Carbon code:
|
||||
- `UpperCamelCase` will be used when the named entity cannot have a
|
||||
dynamically varying value. For example, functions, namespaces, or
|
||||
compile-time constant values.
|
||||
compile-time constant values. Note that
|
||||
[`virtual` methods](#inheritance) are named the same way to be
|
||||
consistent with other functions and methods.
|
||||
- `lower_snake_case` will be used when the named entity's value won't be
|
||||
known until runtime, such as for variables.
|
||||
- For Carbon-provided features:
|
||||
@@ -1616,77 +1883,130 @@ Our naming conventions are:
|
||||
|
||||
### Aliases
|
||||
|
||||
Carbon provides a facility to declare a new name as an alias for a value. This
|
||||
is a fully general facility because everything is a value in Carbon, including
|
||||
types.
|
||||
|
||||
For example:
|
||||
`alias` declares a name as equivalent to another name, for example:
|
||||
|
||||
```carbon
|
||||
alias MyInt = i32;
|
||||
alias NewName = SomePackage.OldName;
|
||||
```
|
||||
|
||||
This creates an alias called `MyInt` for whatever `i32` resolves to. Code
|
||||
textually after this can refer to `MyInt`, and it will transparently refer to
|
||||
`i32`.
|
||||
Note that the right-hand side of the equal sign (`=`) is a name not a value, so
|
||||
`alias four = 4;` is not allowed. This allows `alias` to work with entities like
|
||||
namespaces, which aren't values in Carbon.
|
||||
|
||||
This can be used during an incremental migration when changing a name, or to
|
||||
include a name in a public API. For example, `alias` may be used to include a
|
||||
name from an interface implementation as a member of a class or
|
||||
[named constraint](generics/details.md#named-constraints), possibly renamed:
|
||||
|
||||
```carbon
|
||||
class ContactInfo {
|
||||
external impl as Printable;
|
||||
external impl as ToPrinterDevice;
|
||||
alias PrintToScreen = Printable.Print;
|
||||
alias PrintToPrinter = ToPrinterDevice.Print;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Aliases](aliases.md)
|
||||
> - ["Aliasing" in "Code and name organization"](code_and_name_organization/README.md#aliasing)
|
||||
> - [`alias` a name from an external impl](generics/details.md#external-impl)
|
||||
> - [`alias` a name in a named constraint](generics/details.md#named-constraints)
|
||||
> - Proposal
|
||||
> [#553: Generics details part 1](https://github.com/carbon-language/carbon-lang/pull/553)
|
||||
> - Question-for-leads issue
|
||||
> [#749: Alias syntax](https://github.com/carbon-language/carbon-lang/issues/749)
|
||||
|
||||
> **TODO:** References need to be evolved.
|
||||
|
||||
### Name lookup
|
||||
|
||||
Unqualified name lookup will always find a file-local result, including aliases,
|
||||
or names that are defined as part of the prelude. There is no prioritization of
|
||||
scopes. This means that all relevant scopes are searched, and if the name is
|
||||
found multiple times referring to different entities, then it is an error. The
|
||||
error may be resolved by adding qualification to disambiguate the lookup.
|
||||
The general principle of Carbon name lookup is that we look up names in all
|
||||
relevant scopes, and report an error if the name is found to refer to more than
|
||||
one different entity. So Carbon requires disambiguation by adding qualifiers
|
||||
instead of doing any
|
||||
[shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) of names. For an
|
||||
example, see [the "package scope" section](#package-scope).
|
||||
|
||||
When defining a member of a class, like a [method](#methods), then the other
|
||||
members of the class' scope are searched as part of name lookup, even when that
|
||||
member is being defined out-of-line.
|
||||
Unqualified name lookup walks the semantically-enclosing scopes, not only the
|
||||
lexically-enclosing ones. So when a lookup is performed within
|
||||
`fn MyNamespace.MyClass.MyNestedClass.MyFunction()`, we will look in
|
||||
`MyNestedClass`, `MyClass`, `MyNamespace`, and the package scope, even when the
|
||||
lexically-enclosing scope is the package scope. This means that the definition
|
||||
of a method will look for names in the class' scope even if it is written
|
||||
lexically out of line:
|
||||
|
||||
```
|
||||
class C {
|
||||
fn F();
|
||||
fn G();
|
||||
}
|
||||
fn C.G() {
|
||||
// ✅ Allowed: resolves to `package.C.F`.
|
||||
F();
|
||||
}
|
||||
```
|
||||
|
||||
[Member name lookup](expressions/member_access.md) follows a similar philosophy.
|
||||
If a [checked-generic type parameter](#checked-and-template-parameters) is known
|
||||
to implement multiple interfaces due to a constraint using
|
||||
[`&`](#combining-constraints) or
|
||||
[`where` clauses](generics/details.md#where-constraints), member name lookup
|
||||
into that type will look in all of the interfaces. If it is found in multiple,
|
||||
the name must be disambiguated by qualifying using compound member access
|
||||
([1](expressions/member_access.md),
|
||||
[2](generics/details.md#qualified-member-names-and-compound-member-access)). A
|
||||
[template-generic type parameter](#checked-and-template-parameters) performs
|
||||
look up into the caller's type in addition to the constraint.
|
||||
|
||||
Carbon also rejects cases that would be invalid if all declarations in the file,
|
||||
including ones appearing later, were visible everywhere, not only after their
|
||||
point of appearance:
|
||||
|
||||
```carbon
|
||||
class C {
|
||||
fn F();
|
||||
fn G();
|
||||
}
|
||||
fn C.G() {
|
||||
F();
|
||||
}
|
||||
// Error: use of `F` in `C.G` would be ambiguous
|
||||
// if this declaration was earlier.
|
||||
fn F();
|
||||
```
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Name lookup](name_lookup.md)
|
||||
> - ["Qualified names and member access" section of "Expressions"](expressions/README.md#qualified-names-and-member-access)
|
||||
> - [Qualified names and member access](expressions/member_access.md)
|
||||
> - [Principle: Information accumulation](/docs/project/principles/information_accumulation.md)
|
||||
> - Proposal
|
||||
> [#875: Principle: information accumulation](https://github.com/carbon-language/carbon-lang/pull/875)
|
||||
> - Proposal
|
||||
> [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989)
|
||||
>
|
||||
> **TODO:** References need to be evolved.
|
||||
> - Question-for-leads issue
|
||||
> [#1136: what is the top-level scope in a source file, and what names are found there?](https://github.com/carbon-language/carbon-lang/issues/1136)
|
||||
|
||||
#### Name lookup for common types
|
||||
|
||||
Common types that we expect to be used universally will be provided for every
|
||||
file, including `i32` and `bool`. These will likely be defined in a special
|
||||
"prelude" package.
|
||||
file are made available as if there was a special "prelude" package that was
|
||||
imported automatically into every `api` file. Dedicated type literal syntaxes
|
||||
like `i32` and `bool` refer to types defined within this package, based on the
|
||||
["all APIs are library APIs" principle](/docs/project/principles/library_apis_only.md).
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Name lookup](name_lookup.md)
|
||||
> - [Principle: All APIs are library APIs](/docs/project/principles/library_apis_only.md)
|
||||
> - Question-for-leads issue
|
||||
> [#750: Naming conventions for Carbon-provided features](https://github.com/carbon-language/carbon-lang/issues/750)
|
||||
> - Question-for-leads issue
|
||||
> [#1058: How should interfaces for core functionality be named?](https://github.com/carbon-language/carbon-lang/issues/1058)
|
||||
>
|
||||
> **TODO:** References need to be evolved.
|
||||
|
||||
### Name visibility
|
||||
|
||||
> **TODO:**
|
||||
|
||||
> References:
|
||||
>
|
||||
> - [Exporting entities from an API file](code_and_name_organization/README.md#exporting-entities-from-an-api-file)
|
||||
> - Question-for-leads issue
|
||||
> [#665: `private` vs `public` _syntax_ strategy, as well as other visibility tools like `external`/`api`/etc.](https://github.com/carbon-language/carbon-lang/issues/665)
|
||||
> - Proposal
|
||||
> [#752: api file default public](https://github.com/carbon-language/carbon-lang/pull/752)
|
||||
> - Proposal
|
||||
> [#931: Generic impls access (details 4)](https://github.com/carbon-language/carbon-lang/pull/931)
|
||||
> [#1280: Principle: All APIs are library APIs](https://github.com/carbon-language/carbon-lang/pull/1280)
|
||||
|
||||
## Generics
|
||||
|
||||
@@ -1824,9 +2144,10 @@ class Circle {
|
||||
In this case, `Print` is a member of `Circle`. Interfaces may also be
|
||||
implemented [externally](generics/details.md#external-impl), which means the
|
||||
members of the interface are not direct members of the type. Those methods may
|
||||
still be called using
|
||||
[compound member access syntax](generics/details.md#qualified-member-names-and-compound-member-access)
|
||||
to qualify the name of the member, as in `x.(Printable.Print)()`. External
|
||||
still be called using compound member access syntax
|
||||
([1](expressions/member_access.md),
|
||||
[2](generics/details.md#qualified-member-names-and-compound-member-access)) to
|
||||
qualify the name of the member, as in `x.(Printable.Print)()`. External
|
||||
implementations don't have to be in the same library as the type definition,
|
||||
subject to the orphan rule ([1](generics/details.md#impl-lookup),
|
||||
[2](generics/details.md#orphan-rule)) for
|
||||
@@ -1850,6 +2171,8 @@ by replacing the definition scope in curly braces (`{`...`}`) with a semicolon.
|
||||
> [#990: Generics details 8: interface default and final members](https://github.com/carbon-language/carbon-lang/pull/990)
|
||||
> - Proposal
|
||||
> [#1084: Generics details 9: forward declarations](https://github.com/carbon-language/carbon-lang/pull/1084)
|
||||
> - Question-for-leads issue
|
||||
> [#1132: How do we match forward declarations with their definitions?](https://github.com/carbon-language/carbon-lang/issues/1132)
|
||||
|
||||
### Combining constraints
|
||||
|
||||
@@ -1869,9 +2192,10 @@ fn PrintMin[T:! Ordered & Printable](x: T, y: T) {
|
||||
```
|
||||
|
||||
The body of the function may call functions that are in either interface, except
|
||||
for names that are members of both. In that case, use the
|
||||
[compound member access syntax](generics/details.md#qualified-member-names-and-compound-member-access)
|
||||
to qualify the name of the member, as in:
|
||||
for names that are members of both. In that case, use the compound member access
|
||||
syntax ([1](expressions/member_access.md),
|
||||
[2](generics/details.md#qualified-member-names-and-compound-member-access)) to
|
||||
qualify the name of the member, as in:
|
||||
|
||||
```carbon
|
||||
fn DrawTies[T:! Renderable & GameResult](x: T) {
|
||||
@@ -2339,8 +2663,8 @@ include:
|
||||
|
||||
### Importing and `#include`
|
||||
|
||||
A C++ library header file may be [imported](#packages-libraries-namespaces) into
|
||||
Carbon using an `import` declaration of the special `Cpp` package.
|
||||
A C++ library header file may be [imported](#imports) into Carbon using an
|
||||
`import` declaration of the special `Cpp` package.
|
||||
|
||||
```carbon
|
||||
// like `#include "circle.h"` in C++
|
||||
|
||||
@@ -137,7 +137,7 @@ fn Add(a: i64, b: i64) -> i64 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
fn Main() {
|
||||
fn Run() {
|
||||
Add(1, 2);
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user