mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 20:51:16 +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
+2
-2
@@ -15,11 +15,11 @@ class A {
|
||||
|
||||
fn Init() -> A { return {.v = (1, 2)}; }
|
||||
|
||||
fn Access[self: Self]() -> i32 {
|
||||
fn Access(self) -> i32 {
|
||||
return self.v[0];
|
||||
}
|
||||
|
||||
fn Use[ref self: Self]() -> i32 {
|
||||
fn Use(ref self) -> i32 {
|
||||
self.v[0] = 1;
|
||||
return self.v[1];
|
||||
}
|
||||
|
||||
+8
-8
@@ -32,7 +32,7 @@ fn F() {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc16_43.3.temp = alloca [6 x i32], align 4, !dbg !7
|
||||
// CHECK:STDOUT: %var = alloca i32, align 4, !dbg !8
|
||||
// CHECK:STDOUT: %.loc17_19.1.temp = alloca <{ i32, i1 }>, align 4, !dbg !8
|
||||
// CHECK:STDOUT: %.loc17_19.3.temp = alloca <{ i32, i1 }>, align 4, !dbg !8
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc16_43.3.temp), !dbg !7
|
||||
// CHECK:STDOUT: %.loc16_43.4.array.index = getelementptr inbounds [6 x i32], ptr %.loc16_43.3.temp, i32 0, i64 0, !dbg !7
|
||||
// CHECK:STDOUT: %.loc16_43.7.array.index = getelementptr inbounds [6 x i32], ptr %.loc16_43.3.temp, i32 0, i64 1, !dbg !7
|
||||
@@ -46,18 +46,18 @@ fn F() {
|
||||
// CHECK:STDOUT: br label %for.next, !dbg !8
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: for.next: ; preds = %for.body, %entry
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc17_19.1.temp), !dbg !8
|
||||
// CHECK:STDOUT: call void @"_CNext.e163a239f9fa927c:Iterate.Core.620427d555024fe2"(ptr %.loc17_19.1.temp, ptr @array.loc16_43.24, ptr %var), !dbg !8
|
||||
// CHECK:STDOUT: %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.18012f5191ea64dc(ptr %.loc17_19.1.temp), !dbg !8
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc17_19.3.temp), !dbg !8
|
||||
// CHECK:STDOUT: call void @"_CNext.e163a239f9fa927c:Iterate.Core.620427d555024fe2"(ptr %.loc17_19.3.temp, ptr @array.loc16_43.24, ptr %var), !dbg !8
|
||||
// CHECK:STDOUT: %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.18012f5191ea64dc(ptr %.loc17_19.3.temp), !dbg !8
|
||||
// CHECK:STDOUT: br i1 %Optional.HasValue.call, label %for.body, label %for.done, !dbg !8
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: for.body: ; preds = %for.next
|
||||
// CHECK:STDOUT: %Optional.Get.call = call i32 @_CGet.Optional.Core.18012f5191ea64dc(ptr %.loc17_19.1.temp), !dbg !8
|
||||
// CHECK:STDOUT: %Optional.Get.call = call i32 @_CGet.Optional.Core.18012f5191ea64dc(ptr %.loc17_19.3.temp), !dbg !8
|
||||
// CHECK:STDOUT: call void @_CG.Main(i32 %Optional.Get.call), !dbg !9
|
||||
// CHECK:STDOUT: br label %for.next, !dbg !10
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: for.done: ; preds = %for.next
|
||||
// CHECK:STDOUT: call void @"_COp.ab782c7eec490fc7:core.Destroy.Core"(ptr %.loc17_19.1.temp), !dbg !8
|
||||
// CHECK:STDOUT: call void @"_COp.ab782c7eec490fc7:core.Destroy.Core"(ptr %.loc17_19.3.temp), !dbg !8
|
||||
// CHECK:STDOUT: call void @"_COp.5e27612b9dd31a14:core.Destroy.Core"(ptr %var), !dbg !8
|
||||
// CHECK:STDOUT: call void @"_COp.3a5df7cec745952b:core.Destroy.Core"(ptr @array), !dbg !7
|
||||
// CHECK:STDOUT: ret void, !dbg !11
|
||||
@@ -276,7 +276,7 @@ fn F() {
|
||||
// CHECK:STDOUT: !49 = !{!15, !22}
|
||||
// CHECK:STDOUT: !50 = !{!51}
|
||||
// CHECK:STDOUT: !51 = !DILocalVariable(arg: 1, scope: !46, type: !22)
|
||||
// CHECK:STDOUT: !52 = !DILocation(line: 23, column: 46, scope: !46)
|
||||
// CHECK:STDOUT: !52 = !DILocation(line: 23, column: 38, scope: !46)
|
||||
// CHECK:STDOUT: !53 = distinct !DISubprogram(name: "Next", linkageName: "_CNext.e163a239f9fa927c:Iterate.Core.620427d555024fe2", scope: null, file: !47, line: 24, type: !54, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !56)
|
||||
// CHECK:STDOUT: !54 = !DISubroutineType(types: !55)
|
||||
// CHECK:STDOUT: !55 = !{!22, !22, !22}
|
||||
@@ -360,4 +360,4 @@ fn F() {
|
||||
// CHECK:STDOUT: !133 = distinct !DISubprogram(name: "AsInt", linkageName: "_CAsInt.Int.9452f4c51951679b.Core:AnyInt.Core.be1e879c1ad406d8", scope: null, file: !82, line: 58, type: !127, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !134)
|
||||
// CHECK:STDOUT: !134 = !{!135}
|
||||
// CHECK:STDOUT: !135 = !DILocalVariable(arg: 1, scope: !133, type: !15)
|
||||
// CHECK:STDOUT: !136 = !DILocation(line: 58, column: 36, scope: !133)
|
||||
// CHECK:STDOUT: !136 = !DILocation(line: 58, column: 28, scope: !133)
|
||||
|
||||
Reference in New Issue
Block a user