Skip to content

Commit

Permalink
Use more compact storage for impl lookup buckets.
Browse files Browse the repository at this point in the history
If the bucket is of size zero or one, which is expected to be the common
case, then store it directly. For the remaining cases, use a side table
of lookup buckets.
  • Loading branch information
zygoloid committed Sep 27, 2024
1 parent b0df74b commit 3b8650f
Show file tree
Hide file tree
Showing 3 changed files with 302 additions and 83 deletions.
6 changes: 3 additions & 3 deletions toolchain/check/handle_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
{.self_id = self_type_id, .constraint_id = constraint_type_id}};

// Add the impl declaration.
auto& lookup_bucket = context.impls().GetOrAddLookupBucket(
auto lookup_bucket_ref = context.impls().GetOrAddLookupBucket(
impl_info.self_id, impl_info.constraint_id);
for (auto prev_impl_id : lookup_bucket) {
for (auto prev_impl_id : lookup_bucket_ref) {
if (MergeImplRedecl(context, impl_info, prev_impl_id)) {
impl_decl.impl_id = prev_impl_id;
break;
Expand All @@ -291,7 +291,7 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id,
if (!impl_decl.impl_id.is_valid()) {
impl_info.generic_id = FinishGenericDecl(context, impl_decl_id);
impl_decl.impl_id = context.impls().Add(impl_info);
lookup_bucket.push_back(impl_decl.impl_id);
lookup_bucket_ref.push_back(impl_decl.impl_id);
} else {
FinishGenericRedecl(context, impl_decl_id,
context.impls().Get(impl_decl.impl_id).generic_id);
Expand Down
257 changes: 192 additions & 65 deletions toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,24 @@

library "[[@TEST_NAME]]";

interface Interface {}

interface I {}
interface J {}
interface K {}
interface L {}

impl forall [T:! I] T as K;
impl forall [T:! J] T as K;
impl forall [T:! I] T as Interface;
impl forall [T:! J] T as Interface;
impl forall [T:! K] T as Interface;
impl forall [T:! L] T as Interface;

// These are two different impls, so this is not a redefinition, even though the
// self type and constraint type are the same.
impl forall [T:! I] T as K {}
impl forall [T:! J] T as K {}
impl forall [T:! I] T as Interface {}
impl forall [T:! J] T as Interface {}
impl forall [T:! K] T as Interface {}
impl forall [T:! L] T as Interface {}

// --- fail_same_self_and_interface_redefined.carbon

Expand Down Expand Up @@ -59,128 +66,232 @@ impl (C, C).0 as I {}
// CHECK:STDOUT: --- same_self_and_interface.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %.1: type = interface_type @I [template]
// CHECK:STDOUT: %.1: type = interface_type @Interface [template]
// CHECK:STDOUT: %Self.1: %.1 = bind_symbolic_name Self 0 [symbolic]
// CHECK:STDOUT: %.2: type = interface_type @J [template]
// CHECK:STDOUT: %.2: type = interface_type @I [template]
// CHECK:STDOUT: %Self.2: %.2 = bind_symbolic_name Self 0 [symbolic]
// CHECK:STDOUT: %.3: type = interface_type @K [template]
// CHECK:STDOUT: %.3: type = interface_type @J [template]
// CHECK:STDOUT: %Self.3: %.3 = bind_symbolic_name Self 0 [symbolic]
// CHECK:STDOUT: %T.1: %.1 = bind_symbolic_name T 0 [symbolic]
// CHECK:STDOUT: %T.2: %.2 = bind_symbolic_name T 0 [symbolic]
// CHECK:STDOUT: %.4: type = tuple_type () [template]
// CHECK:STDOUT: %.5: <witness> = interface_witness () [template]
// CHECK:STDOUT: %.4: type = interface_type @K [template]
// CHECK:STDOUT: %Self.4: %.4 = bind_symbolic_name Self 0 [symbolic]
// CHECK:STDOUT: %.5: type = interface_type @L [template]
// CHECK:STDOUT: %Self.5: %.5 = bind_symbolic_name Self 0 [symbolic]
// CHECK:STDOUT: %T.1: %.2 = bind_symbolic_name T 0 [symbolic]
// CHECK:STDOUT: %T.2: %.3 = bind_symbolic_name T 0 [symbolic]
// CHECK:STDOUT: %T.3: %.4 = bind_symbolic_name T 0 [symbolic]
// CHECK:STDOUT: %T.4: %.5 = bind_symbolic_name T 0 [symbolic]
// CHECK:STDOUT: %.6: type = tuple_type () [template]
// CHECK:STDOUT: %.7: <witness> = interface_witness () [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [template] {
// CHECK:STDOUT: .Interface = %Interface.decl
// CHECK:STDOUT: .I = %I.decl
// CHECK:STDOUT: .J = %J.decl
// CHECK:STDOUT: .K = %K.decl
// CHECK:STDOUT: .L = %L.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %I.decl: type = interface_decl @I [template = constants.%.1] {} {}
// CHECK:STDOUT: %J.decl: type = interface_decl @J [template = constants.%.2] {} {}
// CHECK:STDOUT: %K.decl: type = interface_decl @K [template = constants.%.3] {} {}
// CHECK:STDOUT: %Interface.decl: type = interface_decl @Interface [template = constants.%.1] {} {}
// CHECK:STDOUT: %I.decl: type = interface_decl @I [template = constants.%.2] {} {}
// CHECK:STDOUT: %J.decl: type = interface_decl @J [template = constants.%.3] {} {}
// CHECK:STDOUT: %K.decl: type = interface_decl @K [template = constants.%.4] {} {}
// CHECK:STDOUT: %L.decl: type = interface_decl @L [template = constants.%.5] {} {}
// CHECK:STDOUT: impl_decl @impl.1 {
// CHECK:STDOUT: %T.patt: %.1 = symbolic_binding_pattern T 0
// CHECK:STDOUT: %T.patt: %.2 = symbolic_binding_pattern T 0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [template = constants.%.1]
// CHECK:STDOUT: %T.param: %.1 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc8: %.1 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %T.ref: %.1 = name_ref T, %T.loc8 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %.loc8_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %.loc8_21.2: type = converted %T.ref, %.loc8_21.1 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%.3]
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [template = constants.%.2]
// CHECK:STDOUT: %T.param: %.2 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc11: %.2 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %T.ref: %.2 = name_ref T, %T.loc11 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %.loc11_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %.loc11_21.2: type = converted %T.ref, %.loc11_21.1 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @impl.2 {
// CHECK:STDOUT: %T.patt: %.2 = symbolic_binding_pattern T 0
// CHECK:STDOUT: %T.patt: %.3 = symbolic_binding_pattern T 0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [template = constants.%.2]
// CHECK:STDOUT: %T.param: %.2 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc9: %.2 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %T.ref: %.2 = name_ref T, %T.loc9 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %.loc9_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %.loc9_21.2: type = converted %T.ref, %.loc9_21.1 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%.3]
// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [template = constants.%.3]
// CHECK:STDOUT: %T.param: %.3 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc12: %.3 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %T.ref: %.3 = name_ref T, %T.loc12 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %.loc12_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %.loc12_21.2: type = converted %T.ref, %.loc12_21.1 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @impl.3 {
// CHECK:STDOUT: %T.patt: %.1 = symbolic_binding_pattern T 0
// CHECK:STDOUT: %T.patt: %.4 = symbolic_binding_pattern T 0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [template = constants.%.1]
// CHECK:STDOUT: %T.param: %.1 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc13: %.1 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %T.ref: %.1 = name_ref T, %T.loc13 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %.loc13_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %.loc13_21.2: type = converted %T.ref, %.loc13_21.1 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%.3]
// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%.4]
// CHECK:STDOUT: %T.param: %.4 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc13: %.4 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT: %T.ref: %.4 = name_ref T, %T.loc13 [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT: %.loc13_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT: %.loc13_21.2: type = converted %T.ref, %.loc13_21.1 [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @impl.4 {
// CHECK:STDOUT: %T.patt: %.5 = symbolic_binding_pattern T 0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %L.ref: type = name_ref L, file.%L.decl [template = constants.%.5]
// CHECK:STDOUT: %T.param: %.5 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc14: %.5 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT: %T.ref: %.5 = name_ref T, %T.loc14 [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT: %.loc14_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT: %.loc14_21.2: type = converted %T.ref, %.loc14_21.1 [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @impl.5 {
// CHECK:STDOUT: %T.patt: %.2 = symbolic_binding_pattern T 0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [template = constants.%.2]
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [template = constants.%.2]
// CHECK:STDOUT: %T.param: %.2 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc14: %.2 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %T.ref: %.2 = name_ref T, %T.loc14 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %.loc14_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %.loc14_21.2: type = converted %T.ref, %.loc14_21.1 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%.3]
// CHECK:STDOUT: %T.loc18: %.2 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %T.ref: %.2 = name_ref T, %T.loc18 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %.loc18_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %.loc18_21.2: type = converted %T.ref, %.loc18_21.1 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @impl.6 {
// CHECK:STDOUT: %T.patt: %.3 = symbolic_binding_pattern T 0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [template = constants.%.3]
// CHECK:STDOUT: %T.param: %.3 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc19: %.3 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %T.ref: %.3 = name_ref T, %T.loc19 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %.loc19_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %.loc19_21.2: type = converted %T.ref, %.loc19_21.1 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @impl.7 {
// CHECK:STDOUT: %T.patt: %.4 = symbolic_binding_pattern T 0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%.4]
// CHECK:STDOUT: %T.param: %.4 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc20: %.4 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT: %T.ref: %.4 = name_ref T, %T.loc20 [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT: %.loc20_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT: %.loc20_21.2: type = converted %T.ref, %.loc20_21.1 [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @impl.8 {
// CHECK:STDOUT: %T.patt: %.5 = symbolic_binding_pattern T 0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %L.ref: type = name_ref L, file.%L.decl [template = constants.%.5]
// CHECK:STDOUT: %T.param: %.5 = param T, runtime_param<invalid>
// CHECK:STDOUT: %T.loc21: %.5 = bind_symbolic_name T 0, %T.param [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT: %T.ref: %.5 = name_ref T, %T.loc21 [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT: %.loc21_21.1: type = facet_type_access %T.ref [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT: %.loc21_21.2: type = converted %T.ref, %.loc21_21.1 [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @I {
// CHECK:STDOUT: interface @Interface {
// CHECK:STDOUT: %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self.1]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @J {
// CHECK:STDOUT: interface @I {
// CHECK:STDOUT: %Self: %.2 = bind_symbolic_name Self 0 [symbolic = constants.%Self.2]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @K {
// CHECK:STDOUT: interface @J {
// CHECK:STDOUT: %Self: %.3 = bind_symbolic_name Self 0 [symbolic = constants.%Self.3]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.1(%T.loc8: %.1) {
// CHECK:STDOUT: %T.1: %.1 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: interface @K {
// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 0 [symbolic = constants.%Self.4]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.1 as %.3;
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.2(%T.loc9: %.2) {
// CHECK:STDOUT: %T.1: %.2 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: interface @L {
// CHECK:STDOUT: %Self: %.5 = bind_symbolic_name Self 0 [symbolic = constants.%Self.5]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.2 as %.3;
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.3(%T.loc13: %.1) {
// CHECK:STDOUT: %T.1: %.1 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT: generic impl @impl.1(%T.loc11: %.2) {
// CHECK:STDOUT: %T.1: %.2 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.1 as %.3 {
// CHECK:STDOUT: %.loc13_28: <witness> = interface_witness () [template = constants.%.5]
// CHECK:STDOUT: impl: %T.1 as %.1;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.2(%T.loc12: %.3) {
// CHECK:STDOUT: %T.1: %.3 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.2 as %.1;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.3(%T.loc13: %.4) {
// CHECK:STDOUT: %T.1: %.4 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.3 as %.1;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.4(%T.loc14: %.5) {
// CHECK:STDOUT: %T.1: %.5 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.4 as %.1;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.5(%T.loc18: %.2) {
// CHECK:STDOUT: %T.1: %.2 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.1)]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.1 as %.1 {
// CHECK:STDOUT: %.loc18_36: <witness> = interface_witness () [template = constants.%.7]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: witness = %.loc18_36
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.6(%T.loc19: %.3) {
// CHECK:STDOUT: %T.1: %.3 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.2 as %.1 {
// CHECK:STDOUT: %.loc19_36: <witness> = interface_witness () [template = constants.%.7]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: witness = %.loc19_36
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.7(%T.loc20: %.4) {
// CHECK:STDOUT: %T.1: %.4 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.3)]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.3 as %.1 {
// CHECK:STDOUT: %.loc20_36: <witness> = interface_witness () [template = constants.%.7]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: witness = %.loc13_28
// CHECK:STDOUT: witness = %.loc20_36
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic impl @impl.4(%T.loc14: %.2) {
// CHECK:STDOUT: %T.1: %.2 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.2)]
// CHECK:STDOUT: generic impl @impl.8(%T.loc21: %.5) {
// CHECK:STDOUT: %T.1: %.5 = bind_symbolic_name T 0 [symbolic = %T.1 (constants.%T.4)]
// CHECK:STDOUT:
// CHECK:STDOUT: impl: %T.2 as %.3 {
// CHECK:STDOUT: %.loc14_28: <witness> = interface_witness () [template = constants.%.5]
// CHECK:STDOUT: impl: %T.4 as %.1 {
// CHECK:STDOUT: %.loc21_36: <witness> = interface_witness () [template = constants.%.7]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: witness = %.loc14_28
// CHECK:STDOUT: witness = %.loc21_36
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
Expand All @@ -192,14 +303,30 @@ impl (C, C).0 as I {}
// CHECK:STDOUT: %T.1 => constants.%T.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @impl.3(constants.%T.1) {
// CHECK:STDOUT: specific @impl.3(constants.%T.3) {
// CHECK:STDOUT: %T.1 => constants.%T.3
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @impl.4(constants.%T.4) {
// CHECK:STDOUT: %T.1 => constants.%T.4
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @impl.5(constants.%T.1) {
// CHECK:STDOUT: %T.1 => constants.%T.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @impl.4(constants.%T.2) {
// CHECK:STDOUT: specific @impl.6(constants.%T.2) {
// CHECK:STDOUT: %T.1 => constants.%T.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @impl.7(constants.%T.3) {
// CHECK:STDOUT: %T.1 => constants.%T.3
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @impl.8(constants.%T.4) {
// CHECK:STDOUT: %T.1 => constants.%T.4
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_same_self_and_interface_redefined.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
Expand Down
Loading

0 comments on commit 3b8650f

Please sign in to comment.