mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Implements proposal #7016: `self` moves from the deduced implicit list (`fn F[self: Self]()`) to the front of the explicit list. Its type may be written explicitly (`fn F(self: Self)`) or omitted, in which case it defaults to `Self` (`fn F(self)`, `fn F(ref self)`); `self` in the implicit list is rejected. Throughout checking, `self` is modeled as the first explicit parameter. Because a method is just a function whose first parameter is `self`, it can also be called as an ordinary function with the receiver passed explicitly (`Type.M(obj, ...)`), not only as `obj.M(...)`. A new `SemIR::CallArgParamPatterns` helper chooses the parameters matched against the explicit arguments, excluding a leading `self` only when it is supplied as a method-call receiver; arity checking, conversion, and generic deduction use it. The resulting SemIR and lowering are unchanged: `self` is still `call_param0`, and witnesses, thunks, and vtables are unaffected. An omitted `self` type is parsed as a `SelfBindingPattern` node with no type expression; checking synthesizes the `Self` type so it behaves exactly like `self: Self`. However, the exact spelling used must match between a forward declaration and a definition, following #3763's rules around declaration matching. Generated functions, thunks, and C++ interop import/export build `self` as the first explicit parameter, and the `self`-type override (e.g. Derived->Base for a virtual override) applies to the explicit `self`. Placement is validated by new diagnostics: `SelfInImplicitParamList`, `SelfNotFirstParam`, and `SelfOutsideParamList`. The benchmark source generator and the documentation adopt the `(self)` shorthand; the prelude, the examples, and the test data are migrated in the following commits. Assisted-by: Claude Code with Claude Opus 4.7 --------- Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
This commit is contained in:
co-authored by
josh11b
parent
fb05da761f
commit
7871237c15
@@ -275,7 +275,10 @@ static auto EstimateAvgFunctionDeclLines(SourceGen::FunctionDeclParams params)
|
||||
static auto EstimateAvgMethodDeclLines(SourceGen::MethodDeclParams params)
|
||||
-> double {
|
||||
// Currently model a uniform distribution [0, max] parameters. Assume a line
|
||||
// break before the first parameter for >2 and after every 4th.
|
||||
// break before the first parameter for >2 and after every 4th. A Carbon
|
||||
// method also emits a leading `self`, but `self` only rarely tips a method
|
||||
// onto an additional wrapped line, so the estimate ignores it; this stays
|
||||
// calibrated against the emitter (see `source_gen_test`).
|
||||
int param_lines = 0;
|
||||
for (int num_params : llvm::seq_inclusive(0, params.max_params)) {
|
||||
if (num_params > NumSingleLineMethodParams) {
|
||||
@@ -797,10 +800,6 @@ auto SourceGen::GenerateFunctionDecl(
|
||||
os << indent << "// TODO: make better comment text\n";
|
||||
if (!IsCpp()) {
|
||||
os << indent << (is_private ? "private " : "") << "fn " << name;
|
||||
|
||||
if (is_method) {
|
||||
os << "[self: Self]";
|
||||
}
|
||||
} else {
|
||||
os << indent;
|
||||
if (!is_method) {
|
||||
@@ -815,10 +814,19 @@ auto SourceGen::GenerateFunctionDecl(
|
||||
(is_method ? NumSingleLineMethodParams : NumSingleLineFunctionParams)) {
|
||||
os << "\n" << indent << " ";
|
||||
}
|
||||
// For Carbon methods, `self` is the first explicit parameter. Its type is
|
||||
// omitted, which defaults it to `Self`.
|
||||
bool is_carbon_method = is_method && !IsCpp();
|
||||
if (is_carbon_method) {
|
||||
os << "self";
|
||||
}
|
||||
UniqueIdentifierPopper unique_param_names(*this, param_names);
|
||||
for (int i : llvm::seq(param_count)) {
|
||||
if (i > 0) {
|
||||
if ((i % MaxParamsPerLine) == 0) {
|
||||
// `self` occupies the first slot for Carbon methods, so shift the index
|
||||
// used for separators and line wrapping.
|
||||
int slot = i + (is_carbon_method ? 1 : 0);
|
||||
if (slot > 0) {
|
||||
if ((slot % MaxParamsPerLine) == 0) {
|
||||
os << ",\n" << indent << " ";
|
||||
} else {
|
||||
os << ", ";
|
||||
|
||||
Reference in New Issue
Block a user