Skip to content

Commit

Permalink
Update name lookup with regards to carbon-language#875.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonmeow committed Oct 13, 2022
1 parent 6cf2272 commit 6af5930
Showing 1 changed file with 34 additions and 39 deletions.
73 changes: 34 additions & 39 deletions docs/design/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -915,69 +915,63 @@ after any names needed to describe its type.

#### Name lookup in member function definitions

When defining a member function lexically inline, we delay type checking of the
function body until the definition of the current type is complete. This means
that name lookup _for members of objects_ is also delayed. That means that you
can reference `me.F()` in a lexically inline method definition even before the
declaration of `F` in that class definition. However, other names still need to
be declared before they are used. This includes unqualified names, names within
namespaces, and names _for members of types_.
When defining a member function lexically inline, the body is deferred and
processed as if it appeared immediately after the end of the outermost enclosing
class, like in C++.

```
For example, given a class with all inline function definitions:

```carbon
class Point {
fn Distance[me: Self]() -> f32 {
// ✅ Allowed: `x` and `y` are names for members of an object,
// and so lookup is delayed until `type_of(me) == Self` is complete.
return Math.Sqrt(me.x * me.x + me.y * me.y);
}
fn CreatePolarInvalid(r: f32, theta: f32) -> Point {
// ❌ Forbidden: unqualified name used before declaration.
return Create(r * Math.Cos(theta), r * Math.Sin(theta));
}
fn CreatePolarValid1(r: f32, theta: f32) -> Point {
// ❌ Forbidden: `Create` is not yet declared.
fn CreatePolar(r: f32, theta: f32) -> Point {
return Point.Create(r * Math.Cos(theta), r * Math.Sin(theta));
}
fn CreatePolarValid2(r: f32, theta: f32) -> Point {
// ❌ Forbidden: `Create` is not yet declared.
return Self.Create(r * Math.Cos(theta), r * Math.Sin(theta));
}
fn Create(x: f32, y: f32) -> Point {
// ✅ Allowed: checking that conversion of `{.x: f32, .y: f32}`
// to `Point` is delayed until `Point` is complete.
return {.x = x, .y = y};
}
fn CreateXEqualsY(xy: f32) -> Point {
// ✅ Allowed: `Create` is declared earlier.
return Create(xy, xy);
}
var x: f32;
var y: f32;
}
```

fn CreateXAxis(x: f32) -> Point;
These are all parsed as if they were defined outside the class scope:

fn Angle[me: Self]() -> f32;
```carbon
class Point {
fn Distance[me: Self]() -> f32;
fn CreatePolar(r: f32, theta: f32) -> Point;
fn Create(x: f32, y: f32) -> Point;
var x: f32;
var y: f32;
}
fn Point.CreateXAxis(x: f32) -> Point {
// ✅ Allowed: `Point` type is complete.
// Members of `Point` like `Create` are in scope.
return Create(x, 0);
fn Point.Distance[me: Self]() -> f32 {
return Math.Sqrt(me.x * me.x + me.y * me.y);
}
fn Point.CreatePolar(r: f32, theta: f32) -> Point {
return Point.Create(r * Math.Cos(theta), r * Math.Sin(theta));
}
fn Point.Angle[me: Self]() -> f32 {
// ✅ Allowed: `Point` type is complete.
// Function is checked immediately.
return Math.ATan2(me.y, me.x);
fn Point.Create(x: f32, y: f32) -> Point {
return {.x = x, .y = y};
}
```

**Note:** The details of name lookup are still being decided in issue
[#472: Open question: Calling functions defined later in the same file](https://github.com/carbon-language/carbon-lang/issues/472).
Additional details for name lookup are being asked as part of
[#2286: Clarifications for name lookup in classes](https://github.com/carbon-language/carbon-lang/issues/2286):

- Should unqualified name lookup be supported? For example, `Create()` instead
of `Point.Create()`.
- Should instances be usable to access type members? For example,
`Point.Create(0, 0).Create(0,0)`.

### Nominal data classes

Expand Down Expand Up @@ -2103,9 +2097,10 @@ the type of `U.x`."
## References
- [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257)
- [#561: Basic classes: use cases, struct literals, struct types, and future wor](https://github.com/carbon-language/carbon-lang/pull/561)
- [#561: Basic classes: use cases, struct literals, struct types, and future work](https://github.com/carbon-language/carbon-lang/pull/561)
- [#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722)
- [#777: Inheritance](https://github.com/carbon-language/carbon-lang/pull/777)
- [#875: Principle: Information accumulation](https://github.com/carbon-language/carbon-lang/pull/875)
- [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981)
- [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154)
- [#2107: Clarify rules around `Self` and `.Self`](https://github.com/carbon-language/carbon-lang/pull/2107)

0 comments on commit 6af5930

Please sign in to comment.