From e78a57bb82692b752f2d1d10cdcbb503b9bf0a33 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 16 May 2025 15:50:28 -0700 Subject: [PATCH] Adjust formatting of blocks and scopes (#5474) This is making two inter-related changes: - Change `file` to reuse the formatter logic of `constants` and `imports`, meaning empty `file` scopes will be omitted - Mark `` sections in blocks (not in non-block scopes, because they're not as sequential) --- .../testdata/alias/fail_control_flow.carbon | 4 -- .../no_prelude/dump_sem_ir_ranges.carbon | 39 +++++++++- .../no_prelude/dump_sem_ir_ranges_only.carbon | 5 ++ .../testdata/basics/type_literals.carbon | 8 --- .../class/fail_base_as_declared_name.carbon | 2 - .../class/fail_self_type_member.carbon | 2 - .../class/no_prelude/comp_time_field.carbon | 2 - .../testdata/facet/min_prelude/access.carbon | 2 - .../facet/min_prelude/runtime_value.carbon | 23 +++++- .../no_prelude/extern_library.carbon | 2 - .../no_prelude/fail_todo_no_params.carbon | 4 -- .../if_expr/fail_not_in_function.carbon | 10 --- .../fail_assoc_const_not_binding.carbon | 4 -- .../fail_and_or_not_in_function.carbon | 8 --- .../packages/no_prelude/export_import.carbon | 2 - .../no_prelude/missing_prelude.carbon | 4 -- .../patterns/min_prelude/underscore.carbon | 4 -- .../testdata/struct/fail_keyword_name.carbon | 2 - .../tuple/min_prelude/tuple_pattern.carbon | 2 - .../var/fail_todo_control_flow_init.carbon | 8 --- .../var/min_prelude/var_pattern.carbon | 4 -- .../var/no_prelude/fail_generic.carbon | 2 - toolchain/sem_ir/formatter.cpp | 72 ++++++++++--------- toolchain/sem_ir/formatter.h | 5 +- 24 files changed, 107 insertions(+), 113 deletions(-) diff --git a/toolchain/check/testdata/alias/fail_control_flow.carbon b/toolchain/check/testdata/alias/fail_control_flow.carbon index d4eb52ad1210..2608bdc651ac 100644 --- a/toolchain/check/testdata/alias/fail_control_flow.carbon +++ b/toolchain/check/testdata/alias/fail_control_flow.carbon @@ -43,8 +43,6 @@ fn F() { // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_nested.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -59,8 +57,6 @@ fn F() { // CHECK:STDOUT: %false: bool = bool_literal false [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(.inst28.loc4_14: bool) { // CHECK:STDOUT: %B: bool = bind_symbolic_name B, 0 [symbolic = %B (constants.%B.7dd)] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/basics/no_prelude/dump_sem_ir_ranges.carbon b/toolchain/check/testdata/basics/no_prelude/dump_sem_ir_ranges.carbon index 8ebbe0eb26ef..6c3321681c17 100644 --- a/toolchain/check/testdata/basics/no_prelude/dump_sem_ir_ranges.carbon +++ b/toolchain/check/testdata/basics/no_prelude/dump_sem_ir_ranges.carbon @@ -88,6 +88,18 @@ fn F(); // CHECK:STDOUT: --- function.carbon // CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %A.type: type = fn_type @A [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %A: %A.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete] +// CHECK:STDOUT: %B.type: type = fn_type @B [concrete] +// CHECK:STDOUT: %B: %B.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: %C.type: type = fn_type @C [concrete] +// CHECK:STDOUT: %C: %C.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %C.decl: %C.type = fn_decl @C [concrete = constants.%C] { // CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] @@ -102,10 +114,12 @@ fn F(); // CHECK:STDOUT: // CHECK:STDOUT: fn @B() -> %empty_tuple.type { // CHECK:STDOUT: !entry: +// CHECK:STDOUT: // CHECK:STDOUT: %b.ref.loc11: ref %empty_tuple.type = name_ref b, %b // CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [concrete = constants.%A] // CHECK:STDOUT: %A.call: init %empty_tuple.type = call %A.ref() // CHECK:STDOUT: assign %b.ref.loc11, %A.call +// CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @C() -> %empty_tuple.type { @@ -132,12 +146,23 @@ fn F(); // CHECK:STDOUT: // CHECK:STDOUT: --- class.carbon // CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %G.type: type = fn_type @G [concrete] +// CHECK:STDOUT: %G: %G.type = struct_value () [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %I.type: type = fn_type @I [concrete] +// CHECK:STDOUT: %I: %I.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} +// CHECK:STDOUT: // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -148,6 +173,7 @@ fn F(); // CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %I.decl: %I.type = fn_decl @I [concrete = constants.%I] {} {} +// CHECK:STDOUT: // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -162,22 +188,33 @@ fn F(); // CHECK:STDOUT: // CHECK:STDOUT: --- call_params.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %A.type: type = fn_type @A [concrete] +// CHECK:STDOUT: %A: %A.type = struct_value () [concrete] +// CHECK:STDOUT: %C.type: type = fn_type @C [concrete] +// CHECK:STDOUT: %C: %C.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @G() { // CHECK:STDOUT: !entry: +// CHECK:STDOUT: // CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [concrete = constants.%A] // CHECK:STDOUT: %A.call: init %empty_tuple.type = call %A.ref() +// CHECK:STDOUT: // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %C.call: init %empty_tuple.type = call %C.ref() // CHECK:STDOUT: %.loc13_7.1: ref %empty_tuple.type = temporary_storage // CHECK:STDOUT: %.loc13_7.2: ref %empty_tuple.type = temporary %.loc13_7.1, %A.call // CHECK:STDOUT: %tuple.loc13: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple] // CHECK:STDOUT: %.loc13_7.3: %empty_tuple.type = converted %A.call, %tuple.loc13 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: // CHECK:STDOUT: %.loc17_7.1: ref %empty_tuple.type = temporary_storage // CHECK:STDOUT: %.loc17_7.2: ref %empty_tuple.type = temporary %.loc17_7.1, %C.call // CHECK:STDOUT: %tuple.loc17: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple] // CHECK:STDOUT: %.loc17_7.3: %empty_tuple.type = converted %C.call, %tuple.loc17 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- file_without_ranges.carbon diff --git a/toolchain/check/testdata/basics/no_prelude/dump_sem_ir_ranges_only.carbon b/toolchain/check/testdata/basics/no_prelude/dump_sem_ir_ranges_only.carbon index 0c185755584e..6f789da16b8f 100644 --- a/toolchain/check/testdata/basics/no_prelude/dump_sem_ir_ranges_only.carbon +++ b/toolchain/check/testdata/basics/no_prelude/dump_sem_ir_ranges_only.carbon @@ -26,6 +26,11 @@ fn F(); // CHECK:STDOUT: --- with-range.carbon // CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/basics/type_literals.carbon b/toolchain/check/testdata/basics/type_literals.carbon index 9bbe33cc2b10..ec786213a765 100644 --- a/toolchain/check/testdata/basics/type_literals.carbon +++ b/toolchain/check/testdata/basics/type_literals.carbon @@ -196,8 +196,6 @@ var test_f128: f128; // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- uN.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -268,13 +266,7 @@ var test_f128: f128; // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_fN_bad_width.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_fN_todo_unsupported.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_base_as_declared_name.carbon b/toolchain/check/testdata/class/fail_base_as_declared_name.carbon index defd44bc36f4..910054c794a2 100644 --- a/toolchain/check/testdata/class/fail_base_as_declared_name.carbon +++ b/toolchain/check/testdata/class/fail_base_as_declared_name.carbon @@ -22,5 +22,3 @@ fn N.base() {} // CHECK:STDOUT: --- fail_base_as_declared_name.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_self_type_member.carbon b/toolchain/check/testdata/class/fail_self_type_member.carbon index 746b2d895804..3f1a0026ab3f 100644 --- a/toolchain/check/testdata/class/fail_self_type_member.carbon +++ b/toolchain/check/testdata/class/fail_self_type_member.carbon @@ -37,8 +37,6 @@ fn F() -> bool { // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.b [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %bool.make_type: init type = call constants.%Bool() [concrete = bool] // CHECK:STDOUT: %.loc12_10.1: type = value_of_initializer %bool.make_type [concrete = bool] diff --git a/toolchain/check/testdata/class/no_prelude/comp_time_field.carbon b/toolchain/check/testdata/class/no_prelude/comp_time_field.carbon index 9130671f1e1c..84fc1dd920ee 100644 --- a/toolchain/check/testdata/class/no_prelude/comp_time_field.carbon +++ b/toolchain/check/testdata/class/no_prelude/comp_time_field.carbon @@ -94,8 +94,6 @@ var x: Class = {}; // CHECK:STDOUT: %Class: type = class_type @Class [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: complete_type_witness = invalid // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/min_prelude/access.carbon b/toolchain/check/testdata/facet/min_prelude/access.carbon index 87cff7eca60a..27e07c60eda7 100644 --- a/toolchain/check/testdata/facet/min_prelude/access.carbon +++ b/toolchain/check/testdata/facet/min_prelude/access.carbon @@ -1049,8 +1049,6 @@ interface J { // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: interface @I { // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] // CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] { diff --git a/toolchain/check/testdata/facet/min_prelude/runtime_value.carbon b/toolchain/check/testdata/facet/min_prelude/runtime_value.carbon index 036dddc48b0e..1306fcbcc885 100644 --- a/toolchain/check/testdata/facet/min_prelude/runtime_value.carbon +++ b/toolchain/check/testdata/facet/min_prelude/runtime_value.carbon @@ -113,7 +113,15 @@ fn F(T: Z where .X = (), v: T.X); // CHECK:STDOUT: --- facet_value_copy_from_reference.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %I.type [concrete] +// CHECK:STDOUT: %pattern_type.2b5: type = pattern_type %I.type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: @@ -126,11 +134,21 @@ fn F(T: Z where .X = (), v: T.X); // CHECK:STDOUT: %.loc13_15.2: %I.type = bind_value %.loc13_15.1 // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %a: %I.type = bind_name a, %.loc13_15.2 +// CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_facet_copy_narrowing_from_reference.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %facet_type: type = facet_type <@I & @J> [concrete] +// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %facet_type [concrete] +// CHECK:STDOUT: %pattern_type.2b5: type = pattern_type %I.type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: @@ -143,5 +161,6 @@ fn F(T: Z where .X = (), v: T.X); // CHECK:STDOUT: %.loc21_15.2: %facet_type = bind_value %.loc21_15.1 // CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %a: %I.type = bind_name a, +// CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/declaration/no_prelude/extern_library.carbon b/toolchain/check/testdata/function/declaration/no_prelude/extern_library.carbon index ccd2b3ea6ed0..3d86616406fc 100644 --- a/toolchain/check/testdata/function/declaration/no_prelude/extern_library.carbon +++ b/toolchain/check/testdata/function/declaration/no_prelude/extern_library.carbon @@ -299,8 +299,6 @@ extern library "extern_library_owner" fn F() {} // CHECK:STDOUT: // CHECK:STDOUT: --- fail_extern_library_mismatch_owner.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_extern_self_library.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/function/declaration/no_prelude/fail_todo_no_params.carbon b/toolchain/check/testdata/function/declaration/no_prelude/fail_todo_no_params.carbon index 64b5ae8824be..2c2d2634e0a2 100644 --- a/toolchain/check/testdata/function/declaration/no_prelude/fail_todo_no_params.carbon +++ b/toolchain/check/testdata/function/declaration/no_prelude/fail_todo_no_params.carbon @@ -166,12 +166,8 @@ fn A { // CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_arrow_body.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_invalid_file_generic_regression_test.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/if_expr/fail_not_in_function.carbon b/toolchain/check/testdata/if_expr/fail_not_in_function.carbon index 5f7149042fab..23bde3243230 100644 --- a/toolchain/check/testdata/if_expr/fail_not_in_function.carbon +++ b/toolchain/check/testdata/if_expr/fail_not_in_function.carbon @@ -87,22 +87,16 @@ fn F() { // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_types.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_in_param.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_class.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -110,8 +104,6 @@ fn F() { // CHECK:STDOUT: %true: bool = bool_literal true [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %true: bool = bool_literal true [concrete = constants.%true] // CHECK:STDOUT: if %true br !if.expr.then else br !if.expr.else @@ -134,8 +126,6 @@ fn F() { // CHECK:STDOUT: %true: bool = bool_literal true [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(.inst17.loc4_14: type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_binding.carbon b/toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_binding.carbon index 99ede372a2aa..241181bccc41 100644 --- a/toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_binding.carbon +++ b/toolchain/check/testdata/interface/no_prelude/fail_assoc_const_not_binding.carbon @@ -123,8 +123,6 @@ interface I { // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: interface @I { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = .inst17 @@ -136,8 +134,6 @@ interface I { // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: interface @I { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = .inst17 diff --git a/toolchain/check/testdata/operators/builtin/fail_and_or_not_in_function.carbon b/toolchain/check/testdata/operators/builtin/fail_and_or_not_in_function.carbon index b048f6cd3ed8..596f5c5f9c70 100644 --- a/toolchain/check/testdata/operators/builtin/fail_and_or_not_in_function.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_and_or_not_in_function.carbon @@ -77,8 +77,6 @@ var or_val: bool = true or true; // CHECK:STDOUT: %Float: %Float.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%b.param: bool) -> type { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %b.ref: bool = name_ref b, .inst28.loc5_6 @@ -106,8 +104,6 @@ var or_val: bool = true or true; // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_or.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -118,8 +114,6 @@ var or_val: bool = true or true; // CHECK:STDOUT: %Float: %Float.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%b.param: bool) -> type { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %b.ref: bool = name_ref b, .inst28.loc5_6 @@ -147,5 +141,3 @@ var or_val: bool = true or true; // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/packages/no_prelude/export_import.carbon b/toolchain/check/testdata/packages/no_prelude/export_import.carbon index b3867aba2326..235daa5d8c0b 100644 --- a/toolchain/check/testdata/packages/no_prelude/export_import.carbon +++ b/toolchain/check/testdata/packages/no_prelude/export_import.carbon @@ -344,8 +344,6 @@ export Poison; // CHECK:STDOUT: // CHECK:STDOUT: --- fail_export_in_impl.impl.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- export_export.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/packages/no_prelude/missing_prelude.carbon b/toolchain/check/testdata/packages/no_prelude/missing_prelude.carbon index cce4530ded5a..a52aba864639 100644 --- a/toolchain/check/testdata/packages/no_prelude/missing_prelude.carbon +++ b/toolchain/check/testdata/packages/no_prelude/missing_prelude.carbon @@ -374,9 +374,5 @@ var n: {} = i32; // CHECK:STDOUT: // CHECK:STDOUT: --- fail_prelude_as_namespace.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_prelude_as_class.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/patterns/min_prelude/underscore.carbon b/toolchain/check/testdata/patterns/min_prelude/underscore.carbon index 16101080e559..a34cae065071 100644 --- a/toolchain/check/testdata/patterns/min_prelude/underscore.carbon +++ b/toolchain/check/testdata/patterns/min_prelude/underscore.carbon @@ -467,8 +467,6 @@ fn F() -> {} { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: complete_type_witness = invalid // CHECK:STDOUT: @@ -525,7 +523,5 @@ fn F() -> {} { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %empty_struct_type; // CHECK:STDOUT: diff --git a/toolchain/check/testdata/struct/fail_keyword_name.carbon b/toolchain/check/testdata/struct/fail_keyword_name.carbon index c2f155a60e97..8ab7835ebd88 100644 --- a/toolchain/check/testdata/struct/fail_keyword_name.carbon +++ b/toolchain/check/testdata/struct/fail_keyword_name.carbon @@ -26,5 +26,3 @@ fn G() { return {.return = 5}; }; // CHECK:STDOUT: --- fail_keyword_name.carbon // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/tuple/min_prelude/tuple_pattern.carbon b/toolchain/check/testdata/tuple/min_prelude/tuple_pattern.carbon index 952ca81e4c27..f0c867370eb1 100644 --- a/toolchain/check/testdata/tuple/min_prelude/tuple_pattern.carbon +++ b/toolchain/check/testdata/tuple/min_prelude/tuple_pattern.carbon @@ -569,8 +569,6 @@ let (a: {}, b: {}) = ({}, {}, {}); // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: complete_type_witness = invalid // CHECK:STDOUT: diff --git a/toolchain/check/testdata/var/fail_todo_control_flow_init.carbon b/toolchain/check/testdata/var/fail_todo_control_flow_init.carbon index a64adac9cd6d..7de49457199e 100644 --- a/toolchain/check/testdata/var/fail_todo_control_flow_init.carbon +++ b/toolchain/check/testdata/var/fail_todo_control_flow_init.carbon @@ -77,26 +77,18 @@ var y2: bool = false or true; // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_if_false.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_true_or_false.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_false_or_true.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/var/min_prelude/var_pattern.carbon b/toolchain/check/testdata/var/min_prelude/var_pattern.carbon index fa0dfb75179e..f301ea330ecb 100644 --- a/toolchain/check/testdata/var/min_prelude/var_pattern.carbon +++ b/toolchain/check/testdata/var/min_prelude/var_pattern.carbon @@ -361,8 +361,6 @@ class C { // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: fn @f(); // CHECK:STDOUT: // CHECK:STDOUT: --- fail_implicit.carbon @@ -370,8 +368,6 @@ class C { // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%.param: ); // CHECK:STDOUT: // CHECK:STDOUT: --- var_self.carbon diff --git a/toolchain/check/testdata/var/no_prelude/fail_generic.carbon b/toolchain/check/testdata/var/no_prelude/fail_generic.carbon index 123f03f12893..389f6e407f2e 100644 --- a/toolchain/check/testdata/var/no_prelude/fail_generic.carbon +++ b/toolchain/check/testdata/var/no_prelude/fail_generic.carbon @@ -25,7 +25,5 @@ fn Main() { // CHECK:STDOUT: constants { // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: file {} -// CHECK:STDOUT: // CHECK:STDOUT: fn @Main(); // CHECK:STDOUT: diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index d299be0fc59b..8fd44c4eb4fc 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -64,26 +64,18 @@ Formatter::Formatter(const File* sem_ir, } auto Formatter::Format() -> void { - out_ << "--- " << sem_ir_->filename() << "\n\n"; + out_ << "--- " << sem_ir_->filename() << "\n"; - FormatScopeIfUsed(InstNamer::ScopeId::Constants, - sem_ir_->constants().array_ref()); - FormatScopeIfUsed(InstNamer::ScopeId::ImportRefs, - sem_ir_->inst_blocks().Get(InstBlockId::ImportRefs)); - - out_ << inst_namer_.GetScopeName(InstNamer::ScopeId::File) << " "; - OpenBrace(); - - // TODO: Handle the case where there are multiple top-level instruction - // blocks. For example, there may be branching in the initializer of a - // global or a type expression. - if (auto block_id = sem_ir_->top_inst_block_id(); block_id.has_value()) { - llvm::SaveAndRestore file_scope(scope_, InstNamer::ScopeId::File); - FormatCodeBlock(block_id); - } - - CloseBrace(); - out_ << '\n'; + FormatTopLevelScopeIfUsed(InstNamer::ScopeId::Constants, + sem_ir_->constants().array_ref(), + /*use_tentative_output_scopes=*/true); + FormatTopLevelScopeIfUsed(InstNamer::ScopeId::ImportRefs, + sem_ir_->inst_blocks().Get(InstBlockId::ImportRefs), + /*use_tentative_output_scopes=*/true); + FormatTopLevelScopeIfUsed( + InstNamer::ScopeId::File, + sem_ir_->inst_blocks().GetOrEmpty(sem_ir_->top_inst_block_id()), + /*use_tentative_output_scopes=*/false); for (auto [id, _] : sem_ir_->interfaces().enumerate()) { FormatInterface(id); @@ -109,7 +101,6 @@ auto Formatter::Format() -> void { FormatSpecific(id); } - // End-of-file newline. out_ << "\n"; } @@ -284,9 +275,11 @@ auto Formatter::IndentLabel() -> void { Indent(-2); } -auto Formatter::FormatScopeIfUsed(InstNamer::ScopeId scope_id, - llvm::ArrayRef block) -> void { - if (use_dump_sem_ir_ranges_) { +auto Formatter::FormatTopLevelScopeIfUsed(InstNamer::ScopeId scope_id, + llvm::ArrayRef block, + bool use_tentative_output_scopes) + -> void { + if (!use_tentative_output_scopes && use_dump_sem_ir_ranges_) { // Don't format the scope if no instructions are in a dump range. block = block.drop_while( [&](InstId inst_id) { return !ShouldFormatInst(inst_id); }); @@ -299,13 +292,23 @@ auto Formatter::FormatScopeIfUsed(InstNamer::ScopeId scope_id, llvm::SaveAndRestore scope(scope_, scope_id); // Note, we don't use OpenBrace() / CloseBrace() here because we always want // a newline to avoid misformatting if the first instruction is omitted. - out_ << inst_namer_.GetScopeName(scope_id) << " {\n"; + out_ << "\n" << inst_namer_.GetScopeName(scope_id) << " {\n"; indent_ += 2; for (const InstId inst_id : block) { - TentativeOutputScope scope(*this, tentative_inst_chunks_[inst_id.index]); - FormatInst(inst_id); + // Format instructions when needed, but do nothing for elided entries; + // unlike normal code blocks, scopes are non-sequential so skipped + // instructions are assumed to be uninteresting. + if (use_tentative_output_scopes) { + // This is for constants and imports. These use tentative logic to + // determine whether an instruction is printed. + TentativeOutputScope scope(*this, tentative_inst_chunks_[inst_id.index]); + FormatInst(inst_id); + } else if (ShouldFormatInst(inst_id)) { + // This is for the file scope. It uses only the range-based filtering. + FormatInst(inst_id); + } } - out_ << "}\n\n"; + out_ << "}\n"; indent_ -= 2; } @@ -645,8 +648,17 @@ auto Formatter::FormatParamList(InstBlockId params_id, bool has_return_slot) } auto Formatter::FormatCodeBlock(InstBlockId block_id) -> void { + bool elided = false; for (const InstId inst_id : sem_ir_->inst_blocks().GetOrEmpty(block_id)) { - FormatInst(inst_id); + if (ShouldFormatInst(inst_id)) { + FormatInst(inst_id); + elided = false; + } else if (!elided) { + // When formatting a block, leave a hint that instructions were elided. + Indent(); + out_ << "\n"; + elided = true; + } } } @@ -753,10 +765,6 @@ auto Formatter::FormatInst(InstId inst_id, ImportRefUnloaded inst) -> void { } auto Formatter::FormatInst(InstId inst_id) -> void { - if (!ShouldFormatInst(inst_id)) { - return; - } - if (!inst_id.has_value()) { Indent(); out_ << "none\n"; diff --git a/toolchain/sem_ir/formatter.h b/toolchain/sem_ir/formatter.h index 962a18774f18..538a82bfc748 100644 --- a/toolchain/sem_ir/formatter.h +++ b/toolchain/sem_ir/formatter.h @@ -142,8 +142,9 @@ class Formatter { // Formats a top-level scope, and any of the instructions in that scope that // are used. - auto FormatScopeIfUsed(InstNamer::ScopeId scope_id, - llvm::ArrayRef block) -> void; + auto FormatTopLevelScopeIfUsed(InstNamer::ScopeId scope_id, + llvm::ArrayRef block, + bool use_tentative_output_scopes) -> void; // Formats a full class. auto FormatClass(ClassId id) -> void;