Implement checking observe declarations (#6709)

This adds SemIR structs and implements building `observe` lists, as well
as naming, formatting, and importing `observe` declarations.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
This commit is contained in:
Özgür T. Önsoy
2026-07-08 17:07:10 +00:00
committed by GitHub
co-authored by Dana Jansens
parent 918bb9364f
commit 08385adeb5
713 changed files with 13013 additions and 13 deletions
@@ -121,5 +121,7 @@ var f: () = F();
// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref()
// CHECK:STDOUT: assign file.%f.var, %F.call
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -143,6 +143,8 @@ extern library "basic" fn F();
// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref()
// CHECK:STDOUT: assign file.%x.var, %F.call
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_redecl.carbon
@@ -357,5 +357,7 @@ extern library "extern_library_owner" fn F() {}
// CHECK:STDOUT: extern fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -201,6 +201,8 @@ fn CallFAndGIncomplete() {
// CHECK:STDOUT: %ReturnDUsed.ref: %ReturnDUsed.type = name_ref ReturnDUsed, file.%ReturnDUsed.decl [concrete = constants.%ReturnDUsed]
// CHECK:STDOUT: %ReturnDUsed.call: init <error> = call %ReturnDUsed.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_use_imported.carbon
@@ -288,6 +290,8 @@ fn CallFAndGIncomplete() {
// CHECK:STDOUT: %Destroy.Op.bound.loc33: <bound method> = bound_method %.loc33_17.2, constants.%Destroy.Op.1a2547.2
// CHECK:STDOUT: %Destroy.Op.call.loc33: init %empty_tuple.type = call %Destroy.Op.bound.loc33(%.loc33_17.2)
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @ReturnCUnused [from "fail_incomplete_return.carbon"];
@@ -303,5 +307,7 @@ fn CallFAndGIncomplete() {
// CHECK:STDOUT: fn @Destroy.Op.loc34_15.2(%self.param: ref %D) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -138,6 +138,8 @@ extern private fn ExternOrderAndConflict() {}
// CHECK:STDOUT: fn @DuplicateVirtual() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @TwoAccess();
@@ -145,6 +147,8 @@ extern private fn ExternOrderAndConflict() {}
// CHECK:STDOUT: fn @ModifiersConflict() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @InvalidModifier();
@@ -152,10 +156,14 @@ extern private fn ExternOrderAndConflict() {}
// CHECK:STDOUT: fn @ModifiersConflict2() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: extern fn @ExternOrderAndConflict() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -147,15 +147,21 @@ fn E() {}
// CHECK:STDOUT: fn @D() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @E.loc55() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @E.loc63() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -114,6 +114,8 @@ fn A {
// CHECK:STDOUT: fn @A {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_return_type.carbon
@@ -103,6 +103,8 @@ extern fn A();
// CHECK:STDOUT: fn @A() [from "basic.carbon"] {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- extern_api.carbon
@@ -663,6 +663,8 @@ import library "extern_api";
// CHECK:STDOUT: %E.call: init %empty_tuple.type = call %E.ref()
// CHECK:STDOUT: assign file.%e.var, %E.call
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_redecl_api.carbon
@@ -881,6 +883,8 @@ import library "extern_api";
// CHECK:STDOUT: %E.call: init %empty_tuple.type = call %E.ref()
// CHECK:STDOUT: assign file.%e.var, %E.call
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- redecl_extern_api.carbon
@@ -1099,6 +1103,8 @@ import library "extern_api";
// CHECK:STDOUT: %E.call: init %empty_tuple.type = call %E.ref()
// CHECK:STDOUT: assign file.%e.var, %E.call
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_merge.carbon
@@ -1292,6 +1298,8 @@ import library "extern_api";
// CHECK:STDOUT: %E.call: init %empty_tuple.type = call %E.ref()
// CHECK:STDOUT: assign file.%e.var, %E.call
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_merge_reverse.carbon
@@ -1485,6 +1493,8 @@ import library "extern_api";
// CHECK:STDOUT: %E.call: init %empty_tuple.type = call %E.ref()
// CHECK:STDOUT: assign file.%e.var, %E.call
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- unloaded.carbon
@@ -112,6 +112,8 @@ fn D();
// CHECK:STDOUT: fn @A() [from "decl_in_api_definition_in_impl.carbon"] {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- use_decl_in_api.carbon
@@ -103,6 +103,8 @@ fn CallF(ab: ({}, {}), c: {}) {
// CHECK:STDOUT: fn @F(%a.param: %empty_struct_type, %b.param: %empty_struct_type, %c.param: %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @CallF(%ab.param: %tuple.type.b6b, %c.param: %empty_struct_type) {
@@ -114,5 +116,7 @@ fn CallF(ab: ({}, {}), c: {}) {
// CHECK:STDOUT: %tuple.elem1: %empty_struct_type = tuple_access %ab.ref, element1
// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%tuple.elem0, %tuple.elem1, %c.ref)
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -80,5 +80,7 @@ fn G() {
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = ref_binding_pattern x [concrete = constants.%x.patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -42,5 +42,7 @@ fn G() { F(); }
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !observes:
// CHECK:STDOUT: }
// CHECK:STDOUT: