Skip to content

Commit 7c1798d

Browse files
authored
Format impl witness instructions as part of the impl (#6485)
The impl's body block has to end before we make its ImplDecl instruction, and the witness instructions come later, so they don't end up in the body block. Currently they just end up in the enclosing (file, typically, or class) scope block. Add a new InstBlockId to Impl for holding witness instructions, and explicitly insert them into that block. Then include those instructions into the scope of the Impl for naming, and format them into the Impl right after the body block. This is based on #6484
1 parent 992d435 commit 7c1798d

File tree

121 files changed

+1386
-1302
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+1386
-1302
lines changed

toolchain/check/handle_impl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id)
281281
// impl unusable for impl lookup.
282282
impl.witness_id = SemIR::ErrorInst::InstId;
283283
} else {
284+
context.inst_block_stack().Push();
284285
// This makes either a placeholder witness table or a full witness
285286
// table. The full witness table is deferred to the impl definition
286287
// unless the declaration uses rewrite constraints to set values of
@@ -293,6 +294,7 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id)
293294
impl.witness_id = AddImplWitnessForDeclaration(
294295
context, node_id, impl,
295296
context.generics().GetSelfSpecific(impl.generic_id));
297+
impl.witness_block_id = context.inst_block_stack().Pop();
296298
}
297299

298300
FinishGenericDecl(context, node_id, impl.generic_id);

toolchain/check/testdata/as/basics.carbon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
381381
// CHECK:STDOUT: %struct.948: %struct_type.x = struct_value (%empty_tuple) [concrete]
382382
// CHECK:STDOUT: %X.val: %X = struct_value (%empty_tuple) [concrete]
383383
// CHECK:STDOUT: %As.type.cd7: type = facet_type <@As, @As(%Y)> [concrete]
384-
// CHECK:STDOUT: %As.impl_witness.362: <witness> = impl_witness file.%As.impl_witness_table.loc14 [concrete]
384+
// CHECK:STDOUT: %As.impl_witness.362: <witness> = impl_witness @X.as.As.impl.%As.impl_witness_table [concrete]
385385
// CHECK:STDOUT: %As.Convert.type.5a7: type = fn_type @As.Convert, @As(%Y) [concrete]
386386
// CHECK:STDOUT: %X.as.As.impl.Convert.type: type = fn_type @X.as.As.impl.Convert [concrete]
387387
// CHECK:STDOUT: %X.as.As.impl.Convert: %X.as.As.impl.Convert.type = struct_value () [concrete]

toolchain/check/testdata/as/var_init.carbon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fn Convert(t: ()) {
3434
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
3535
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
3636
// CHECK:STDOUT: %ImplicitAs.type.37a: type = facet_type <@ImplicitAs, @ImplicitAs(%X)> [concrete]
37-
// CHECK:STDOUT: %ImplicitAs.impl_witness: <witness> = impl_witness @X.%ImplicitAs.impl_witness_table [concrete]
37+
// CHECK:STDOUT: %ImplicitAs.impl_witness: <witness> = impl_witness @empty_tuple.type.as.ImplicitAs.impl.%ImplicitAs.impl_witness_table [concrete]
3838
// CHECK:STDOUT: %ImplicitAs.Convert.type.9f8: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%X) [concrete]
3939
// CHECK:STDOUT: %pattern_type.05f: type = pattern_type %X [concrete]
4040
// CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert.type: type = fn_type @empty_tuple.type.as.ImplicitAs.impl.Convert [concrete]

toolchain/check/testdata/basics/include_in_dumps.carbon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn F(c: C) { c.(I.Op)(); }
124124
// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete]
125125
// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%I.Op.decl [concrete]
126126
// CHECK:STDOUT: %C: type = class_type @C [concrete]
127-
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness @C.%I.impl_witness_table [concrete]
127+
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete]
128128
// CHECK:STDOUT: %pattern_type.7c7: type = pattern_type %C [concrete]
129129
// CHECK:STDOUT: %I.facet: %I.type = facet_value %C, (%I.impl_witness) [concrete]
130130
// CHECK:STDOUT: }

toolchain/check/testdata/builtins/type/destroy.carbon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ fn F() {
4141
// CHECK:STDOUT: %assoc0: %DestroyLike.assoc_type = assoc_entity element0, @DestroyLike.%DestroyLike.Op.decl [concrete]
4242
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
4343
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
44-
// CHECK:STDOUT: %DestroyLike.impl_witness.52f: <witness> = impl_witness file.%DestroyLike.impl_witness_table, @T.as.DestroyLike.impl(%empty_tuple.type) [concrete]
44+
// CHECK:STDOUT: %DestroyLike.impl_witness.52f: <witness> = impl_witness @T.as.DestroyLike.impl.%DestroyLike.impl_witness_table, @T.as.DestroyLike.impl(%empty_tuple.type) [concrete]
4545
// CHECK:STDOUT: %T.as.DestroyLike.impl.Op.type.6ca: type = fn_type @T.as.DestroyLike.impl.Op, @T.as.DestroyLike.impl(%empty_tuple.type) [concrete]
4646
// CHECK:STDOUT: %T.as.DestroyLike.impl.Op.3ae: %T.as.DestroyLike.impl.Op.type.6ca = struct_value () [concrete]
4747
// CHECK:STDOUT: %DestroyLike.facet.430: %DestroyLike.type = facet_value %empty_tuple.type, (%DestroyLike.impl_witness.52f) [concrete]
4848
// CHECK:STDOUT: %.bcf: type = fn_type_with_self_type %DestroyLike.Op.type, %DestroyLike.facet.430 [concrete]
4949
// CHECK:STDOUT: %T.as.DestroyLike.impl.Op.bound.f9f: <bound method> = bound_method file.%a.var, %T.as.DestroyLike.impl.Op.3ae [concrete]
5050
// CHECK:STDOUT: %T.as.DestroyLike.impl.Op.specific_fn.38d: <specific function> = specific_function %T.as.DestroyLike.impl.Op.3ae, @T.as.DestroyLike.impl.Op(%empty_tuple.type) [concrete]
5151
// CHECK:STDOUT: %bound_method.717: <bound method> = bound_method file.%a.var, %T.as.DestroyLike.impl.Op.specific_fn.38d [concrete]
52-
// CHECK:STDOUT: %DestroyLike.impl_witness.409: <witness> = impl_witness file.%DestroyLike.impl_witness_table, @T.as.DestroyLike.impl(%empty_struct_type) [concrete]
52+
// CHECK:STDOUT: %DestroyLike.impl_witness.409: <witness> = impl_witness @T.as.DestroyLike.impl.%DestroyLike.impl_witness_table, @T.as.DestroyLike.impl(%empty_struct_type) [concrete]
5353
// CHECK:STDOUT: %T.as.DestroyLike.impl.Op.type.1f5: type = fn_type @T.as.DestroyLike.impl.Op, @T.as.DestroyLike.impl(%empty_struct_type) [concrete]
5454
// CHECK:STDOUT: %T.as.DestroyLike.impl.Op.f28: %T.as.DestroyLike.impl.Op.type.1f5 = struct_value () [concrete]
5555
// CHECK:STDOUT: %DestroyLike.facet.736: %DestroyLike.type = facet_value %empty_struct_type, (%DestroyLike.impl_witness.409) [concrete]

toolchain/check/testdata/class/generic/member_type.carbon

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ fn Test() -> i32 {
430430
// CHECK:STDOUT: %Inner.assoc_type.be2: type = assoc_entity_type @Inner, @Inner(%T) [symbolic]
431431
// CHECK:STDOUT: %assoc0.0a9: %Inner.assoc_type.be2 = assoc_entity element0, @Inner.%Inner.F.decl [symbolic]
432432
// CHECK:STDOUT: %C.131: type = class_type @C, @C(%T) [symbolic]
433-
// CHECK:STDOUT: %Inner.impl_witness.154: <witness> = impl_witness @C.%Inner.impl_witness_table, @C.as.Inner.impl(%T) [symbolic]
433+
// CHECK:STDOUT: %Inner.impl_witness.154: <witness> = impl_witness @C.as.Inner.impl.%Inner.impl_witness_table, @C.as.Inner.impl(%T) [symbolic]
434434
// CHECK:STDOUT: %require_complete.0f7: <witness> = require_complete_type %Inner.type.e0e [symbolic]
435435
// CHECK:STDOUT: %pattern_type.fe7: type = pattern_type %C.131 [symbolic]
436436
// CHECK:STDOUT: %C.as.Inner.impl.F.type.9a2: type = fn_type @C.as.Inner.impl.F, @C.as.Inner.impl(%T) [symbolic]
@@ -454,7 +454,7 @@ fn Test() -> i32 {
454454
// CHECK:STDOUT: %Outer.d71: type = class_type @Outer, @Outer(%i32) [concrete]
455455
// CHECK:STDOUT: %Inner.type.b33: type = facet_type <@Inner, @Inner(%i32)> [concrete]
456456
// CHECK:STDOUT: %C.d3f: type = class_type @C, @C(%i32) [concrete]
457-
// CHECK:STDOUT: %Inner.impl_witness.744: <witness> = impl_witness @D.%Inner.impl_witness_table [concrete]
457+
// CHECK:STDOUT: %Inner.impl_witness.744: <witness> = impl_witness @D.as.Inner.impl.%Inner.impl_witness_table [concrete]
458458
// CHECK:STDOUT: %Self.d74: %Inner.type.b33 = symbolic_binding Self, 1 [symbolic]
459459
// CHECK:STDOUT: %Inner.F.type.c8b: type = fn_type @Inner.F, @Inner(%i32) [concrete]
460460
// CHECK:STDOUT: %Inner.F.1cd: %Inner.F.type.c8b = struct_value () [concrete]
@@ -472,7 +472,7 @@ fn Test() -> i32 {
472472
// CHECK:STDOUT: %pattern_type.129: type = pattern_type %C.d3f [concrete]
473473
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
474474
// CHECK:STDOUT: %C.val: %C.d3f = struct_value () [concrete]
475-
// CHECK:STDOUT: %Inner.impl_witness.2d0: <witness> = impl_witness @C.%Inner.impl_witness_table, @C.as.Inner.impl(%i32) [concrete]
475+
// CHECK:STDOUT: %Inner.impl_witness.2d0: <witness> = impl_witness @C.as.Inner.impl.%Inner.impl_witness_table, @C.as.Inner.impl(%i32) [concrete]
476476
// CHECK:STDOUT: %complete_type.75e: <witness> = complete_type_witness %Inner.type.b33 [concrete]
477477
// CHECK:STDOUT: %C.as.Inner.impl.F.type.457: type = fn_type @C.as.Inner.impl.F, @C.as.Inner.impl(%i32) [concrete]
478478
// CHECK:STDOUT: %C.as.Inner.impl.F.cc7: %C.as.Inner.impl.F.type.457 = struct_value () [concrete]
@@ -571,7 +571,7 @@ fn Test() -> i32 {
571571
// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)]
572572
// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.131)]
573573
// CHECK:STDOUT: %Inner.type: type = facet_type <@Inner, @Inner(%T)> [symbolic = %Inner.type (constants.%Inner.type.e0e)]
574-
// CHECK:STDOUT: %Inner.impl_witness: <witness> = impl_witness @C.%Inner.impl_witness_table, @C.as.Inner.impl(%T) [symbolic = %Inner.impl_witness (constants.%Inner.impl_witness.154)]
574+
// CHECK:STDOUT: %Inner.impl_witness.loc10_19.2: <witness> = impl_witness %Inner.impl_witness_table, @C.as.Inner.impl(%T) [symbolic = %Inner.impl_witness.loc10_19.2 (constants.%Inner.impl_witness.154)]
575575
// CHECK:STDOUT:
576576
// CHECK:STDOUT: !definition:
577577
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %Inner.type [symbolic = %require_complete (constants.%require_complete.0f7)]
@@ -595,13 +595,15 @@ fn Test() -> i32 {
595595
// CHECK:STDOUT: %return.param: ref @C.as.Inner.impl.F.%T (%T) = out_param call_param1
596596
// CHECK:STDOUT: %return: ref @C.as.Inner.impl.F.%T (%T) = return_slot %return.param
597597
// CHECK:STDOUT: }
598+
// CHECK:STDOUT: %Inner.impl_witness_table = impl_witness_table (%C.as.Inner.impl.F.decl), @C.as.Inner.impl [concrete]
599+
// CHECK:STDOUT: %Inner.impl_witness.loc10_19.1: <witness> = impl_witness %Inner.impl_witness_table, @C.as.Inner.impl(constants.%T) [symbolic = %Inner.impl_witness.loc10_19.2 (constants.%Inner.impl_witness.154)]
598600
// CHECK:STDOUT:
599601
// CHECK:STDOUT: !members:
600602
// CHECK:STDOUT: .C = <poisoned>
601603
// CHECK:STDOUT: .T = <poisoned>
602604
// CHECK:STDOUT: .F = %C.as.Inner.impl.F.decl
603605
// CHECK:STDOUT: .Inner = <poisoned>
604-
// CHECK:STDOUT: witness = @C.%Inner.impl_witness
606+
// CHECK:STDOUT: witness = %Inner.impl_witness.loc10_19.1
605607
// CHECK:STDOUT: }
606608
// CHECK:STDOUT: }
607609
// CHECK:STDOUT:
@@ -620,11 +622,13 @@ fn Test() -> i32 {
620622
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
621623
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
622624
// CHECK:STDOUT: }
625+
// CHECK:STDOUT: %Inner.impl_witness_table = impl_witness_table (%D.as.Inner.impl.F.decl), @D.as.Inner.impl [concrete]
626+
// CHECK:STDOUT: %Inner.impl_witness: <witness> = impl_witness %Inner.impl_witness_table [concrete = constants.%Inner.impl_witness.744]
623627
// CHECK:STDOUT:
624628
// CHECK:STDOUT: !members:
625629
// CHECK:STDOUT: .D = <poisoned>
626630
// CHECK:STDOUT: .F = %D.as.Inner.impl.F.decl
627-
// CHECK:STDOUT: witness = @D.%Inner.impl_witness
631+
// CHECK:STDOUT: witness = %Inner.impl_witness
628632
// CHECK:STDOUT: }
629633
// CHECK:STDOUT:
630634
// CHECK:STDOUT: generic class @Outer(%T.loc4_13.2: type) {
@@ -657,8 +661,6 @@ fn Test() -> i32 {
657661
// CHECK:STDOUT: %.loc10: type = specific_constant @Outer.%Inner.decl, @Outer(constants.%T) [symbolic = %Inner.type (constants.%Inner.type.e0e)]
658662
// CHECK:STDOUT: %Inner.ref: type = name_ref Inner, %.loc10 [symbolic = %Inner.type (constants.%Inner.type.e0e)]
659663
// CHECK:STDOUT: }
660-
// CHECK:STDOUT: %Inner.impl_witness_table = impl_witness_table (@C.as.Inner.impl.%C.as.Inner.impl.F.decl), @C.as.Inner.impl [concrete]
661-
// CHECK:STDOUT: %Inner.impl_witness: <witness> = impl_witness %Inner.impl_witness_table, @C.as.Inner.impl(constants.%T) [symbolic = @C.as.Inner.impl.%Inner.impl_witness (constants.%Inner.impl_witness.154)]
662664
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357]
663665
// CHECK:STDOUT: complete_type_witness = %complete_type
664666
// CHECK:STDOUT:
@@ -680,8 +682,6 @@ fn Test() -> i32 {
680682
// CHECK:STDOUT: %.loc17: type = specific_constant @Outer.%Inner.decl, @Outer(constants.%i32) [concrete = constants.%Inner.type.b33]
681683
// CHECK:STDOUT: %Inner.ref: type = name_ref Inner, %.loc17 [concrete = constants.%Inner.type.b33]
682684
// CHECK:STDOUT: }
683-
// CHECK:STDOUT: %Inner.impl_witness_table = impl_witness_table (@D.as.Inner.impl.%D.as.Inner.impl.F.decl), @D.as.Inner.impl [concrete]
684-
// CHECK:STDOUT: %Inner.impl_witness: <witness> = impl_witness %Inner.impl_witness_table [concrete = constants.%Inner.impl_witness.744]
685685
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357]
686686
// CHECK:STDOUT: complete_type_witness = %complete_type
687687
// CHECK:STDOUT:
@@ -820,7 +820,7 @@ fn Test() -> i32 {
820820
// CHECK:STDOUT: %T => constants.%T
821821
// CHECK:STDOUT: %C => constants.%C.131
822822
// CHECK:STDOUT: %Inner.type => constants.%Inner.type.e0e
823-
// CHECK:STDOUT: %Inner.impl_witness => constants.%Inner.impl_witness.154
823+
// CHECK:STDOUT: %Inner.impl_witness.loc10_19.2 => constants.%Inner.impl_witness.154
824824
// CHECK:STDOUT:
825825
// CHECK:STDOUT: !definition:
826826
// CHECK:STDOUT: %require_complete => constants.%require_complete.0f7
@@ -889,7 +889,7 @@ fn Test() -> i32 {
889889
// CHECK:STDOUT: %T => constants.%i32
890890
// CHECK:STDOUT: %C => constants.%C.d3f
891891
// CHECK:STDOUT: %Inner.type => constants.%Inner.type.b33
892-
// CHECK:STDOUT: %Inner.impl_witness => constants.%Inner.impl_witness.2d0
892+
// CHECK:STDOUT: %Inner.impl_witness.loc10_19.2 => constants.%Inner.impl_witness.2d0
893893
// CHECK:STDOUT:
894894
// CHECK:STDOUT: !definition:
895895
// CHECK:STDOUT: %require_complete => constants.%complete_type.75e

toolchain/check/testdata/class/virtual_modifiers.carbon

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,7 +2003,7 @@ class T2(G2:! type) {
20032003
// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete]
20042004
// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete]
20052005
// CHECK:STDOUT: %ImplicitAs.type.865: type = facet_type <@ImplicitAs, @ImplicitAs(%T1)> [concrete]
2006-
// CHECK:STDOUT: %ImplicitAs.impl_witness: <witness> = impl_witness file.%ImplicitAs.impl_witness_table [concrete]
2006+
// CHECK:STDOUT: %ImplicitAs.impl_witness: <witness> = impl_witness @T2.as.ImplicitAs.impl.%ImplicitAs.impl_witness_table [concrete]
20072007
// CHECK:STDOUT: %pattern_type.b8b: type = pattern_type %T2 [concrete]
20082008
// CHECK:STDOUT: %pattern_type.818: type = pattern_type %T1 [concrete]
20092009
// CHECK:STDOUT: %T2.as.ImplicitAs.impl.Convert.type: type = fn_type @T2.as.ImplicitAs.impl.Convert [concrete]
@@ -2055,8 +2055,6 @@ class T2(G2:! type) {
20552055
// CHECK:STDOUT: %T1.ref: type = name_ref T1, file.%T1.decl [concrete = constants.%T1]
20562056
// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%T1)> [concrete = constants.%ImplicitAs.type.865]
20572057
// CHECK:STDOUT: }
2058-
// CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (@T2.as.ImplicitAs.impl.%T2.as.ImplicitAs.impl.Convert.decl), @T2.as.ImplicitAs.impl [concrete]
2059-
// CHECK:STDOUT: %ImplicitAs.impl_witness: <witness> = impl_witness %ImplicitAs.impl_witness_table [concrete = constants.%ImplicitAs.impl_witness]
20602058
// CHECK:STDOUT: %Base.decl: type = class_decl @Base [concrete = constants.%Base] {} {}
20612059
// CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {}
20622060
// CHECK:STDOUT: }
@@ -2075,11 +2073,13 @@ class T2(G2:! type) {
20752073
// CHECK:STDOUT: %return.param: ref %T1 = out_param call_param1
20762074
// CHECK:STDOUT: %return: ref %T1 = return_slot %return.param
20772075
// CHECK:STDOUT: }
2076+
// CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (%T2.as.ImplicitAs.impl.Convert.decl), @T2.as.ImplicitAs.impl [concrete]
2077+
// CHECK:STDOUT: %ImplicitAs.impl_witness: <witness> = impl_witness %ImplicitAs.impl_witness_table [concrete = constants.%ImplicitAs.impl_witness]
20782078
// CHECK:STDOUT:
20792079
// CHECK:STDOUT: !members:
20802080
// CHECK:STDOUT: .T1 = <poisoned>
20812081
// CHECK:STDOUT: .Convert = %T2.as.ImplicitAs.impl.Convert.decl
2082-
// CHECK:STDOUT: witness = file.%ImplicitAs.impl_witness
2082+
// CHECK:STDOUT: witness = %ImplicitAs.impl_witness
20832083
// CHECK:STDOUT: }
20842084
// CHECK:STDOUT:
20852085
// CHECK:STDOUT: class @T1 {

0 commit comments

Comments
 (0)