diff --git a/toolchain/check/handle_impl.cpp b/toolchain/check/handle_impl.cpp index 0a826c69a367..474e9a46818d 100644 --- a/toolchain/check/handle_impl.cpp +++ b/toolchain/check/handle_impl.cpp @@ -214,40 +214,11 @@ static auto PopImplIntroducerAndParamsAsNameComponent( Parse::NodeId first_param_node_id = context.node_stack().PopForSoloNodeId(); - // Subtracting 1 since we don't want to include the final `{` or `;` of the // declaration when performing syntactic match. - auto end_node_kind = context.parse_tree().node_kind(end_of_decl_node_id); - CARBON_CHECK(end_node_kind == Parse::NodeKind::ImplDefinitionStart || - end_node_kind == Parse::NodeKind::ImplDecl); Parse::Tree::PostorderIterator last_param_iter(end_of_decl_node_id); --last_param_iter; - // Following proposal #3763, exclude a final `where` clause, if present. See: - // https://github.com/carbon-language/carbon-lang/blob/trunk/proposals/p3763.md#redeclarations - - // Caches the NodeKind for the current value of *last_param_iter so - if (context.parse_tree().node_kind(*last_param_iter) == - Parse::NodeKind::WhereExpr) { - int where_operands_to_skip = 1; - --last_param_iter; - CARBON_CHECK(Parse::Tree::PostorderIterator(first_param_node_id) < - last_param_iter); - do { - auto node_kind = context.parse_tree().node_kind(*last_param_iter); - if (node_kind == Parse::NodeKind::WhereExpr) { - // If we have a nested `where`, we need to see another `WhereOperand` - // before we find the one that matches our original `WhereExpr` node. - ++where_operands_to_skip; - } else if (node_kind == Parse::NodeKind::WhereOperand) { - --where_operands_to_skip; - } - --last_param_iter; - CARBON_CHECK(Parse::Tree::PostorderIterator(first_param_node_id) < - last_param_iter); - } while (where_operands_to_skip > 0); - } - return { .name_loc_id = Parse::NodeId::None, .name_id = SemIR::NameId::None, @@ -315,9 +286,6 @@ static auto IsValidImplRedecl(Context& context, SemIR::Impl& new_impl, // TODO: Only allow redeclaration in a match_first/impl_priority block. - // TODO: Merge information from the new declaration into the old one as - // needed. - return true; } @@ -375,6 +343,8 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id, // Add the impl declaration. bool invalid_redeclaration = false; auto lookup_bucket_ref = context.impls().GetOrAddLookupBucket(impl_info); + // TODO: Detect two impl declarations with the same self type and interface, + // and issue an error if they don't match. for (auto prev_impl_id : lookup_bucket_ref) { if (MergeImplRedecl(context, impl_info, prev_impl_id)) { if (IsValidImplRedecl(context, impl_info, prev_impl_id)) { @@ -392,15 +362,13 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id, if (!impl_decl.impl_id.has_value()) { impl_info.generic_id = BuildGeneric(context, impl_decl_id); impl_info.witness_id = ImplWitnessForDeclaration(context, impl_info); - AddConstantsToImplWitnessFromConstraint( - context, impl_info, impl_info.witness_id, impl_decl.impl_id); + AddConstantsToImplWitnessFromConstraint(context, impl_info, + impl_info.witness_id); FinishGenericDecl(context, impl_decl_id, impl_info.generic_id); impl_decl.impl_id = context.impls().Add(impl_info); lookup_bucket_ref.push_back(impl_decl.impl_id); } else { const auto& first_impl = context.impls().Get(impl_decl.impl_id); - AddConstantsToImplWitnessFromConstraint( - context, impl_info, first_impl.witness_id, impl_decl.impl_id); FinishGenericRedecl(context, impl_decl_id, first_impl.generic_id); } diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index bb28ad0c72f4..2155d8d54db7 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -32,16 +32,6 @@ static auto NoteAssociatedFunction(Context& context, function.name_id); } -// Adds the location of the previous declaration to a diagnostic. -static auto NotePreviousDecl(Context& context, - Context::DiagnosticBuilder& builder, - SemIR::ImplId impl_id) -> void { - CARBON_DIAGNOSTIC(ImplPreviousDeclHere, Note, - "impl previously declared here"); - const auto& impl = context.impls().Get(impl_id); - builder.Note(impl.latest_decl_id(), ImplPreviousDeclHere); -} - // Checks that `impl_function_id` is a valid implementation of the function // described in the interface as `interface_function_id`. Returns the value to // put into the corresponding slot in the witness table, which can be @@ -88,6 +78,7 @@ static auto CheckAssociatedFunctionImplementation( } // Builds an initial empty witness. +// TODO: Fill the witness with the rewrites from the declaration. auto ImplWitnessForDeclaration(Context& context, const SemIR::Impl& impl) -> SemIR::InstId { CARBON_CHECK(!impl.has_definition_started()); @@ -159,11 +150,10 @@ static auto WitnessAccessMatchesInterface( return false; } +// TODO: Merge this function into `ImplWitnessForDeclaration`. auto AddConstantsToImplWitnessFromConstraint(Context& context, const SemIR::Impl& impl, - SemIR::InstId witness_id, - SemIR::ImplId prev_decl_id) - -> void { + SemIR::InstId witness_id) -> void { CARBON_CHECK(!impl.has_definition_started()); CARBON_CHECK(witness_id.has_value()); if (witness_id == SemIR::ErrorInst::SingletonInstId) { @@ -229,16 +219,13 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context, } } - // For each non-function associated constant, update witness entry. + // For each non-function associated constant, set the witness entry. for (auto index : llvm::seq(assoc_entities.size())) { auto decl_id = context.constant_values().GetConstantInstId(assoc_entities[index]); CARBON_CHECK(decl_id.has_value(), "Non-constant associated entity"); if (auto decl = context.insts().TryGetAs(decl_id)) { - const auto& assoc_const = - context.associated_constants().Get(decl->assoc_const_id); - auto& witness_value = witness_block[index]; auto rewrite_value = rewrite_values[index]; // If the associated constant has a symbolic type, convert the rewrite @@ -264,6 +251,8 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context, // value was constant. if (!rewrite_value.is_constant() && rewrite_value != SemIR::ErrorInst::SingletonConstantId) { + const auto& assoc_const = + context.associated_constants().Get(decl->assoc_const_id); CARBON_DIAGNOSTIC( AssociatedConstantNotConstantAfterConversion, Error, "associated constant {0} given value that is not constant " @@ -276,39 +265,9 @@ auto AddConstantsToImplWitnessFromConstraint(Context& context, } } - if (witness_value.has_value() && - witness_value != SemIR::ErrorInst::SingletonInstId) { - // TODO: Support just using the witness values if the redeclaration uses - // `where _`, per proposal #1084. - if (!rewrite_value.has_value()) { - CARBON_DIAGNOSTIC(AssociatedConstantMissingInRedecl, Error, - "associated constant {0} given value in " - "declaration but not redeclaration", - SemIR::NameId); - auto builder = context.emitter().Build( - impl.latest_decl_id(), AssociatedConstantMissingInRedecl, - assoc_const.name_id); - NotePreviousDecl(context, builder, prev_decl_id); - builder.Emit(); - continue; - } - auto witness_const_id = context.constant_values().Get(witness_value); - if (witness_const_id != rewrite_value && - rewrite_value != SemIR::ErrorInst::SingletonConstantId) { - // TODO: Figure out how to print the two different values - CARBON_DIAGNOSTIC( - AssociatedConstantDifferentInRedecl, Error, - "redeclaration with different value for associated constant {0}", - SemIR::NameId); - auto builder = context.emitter().Build( - impl.latest_decl_id(), AssociatedConstantDifferentInRedecl, - assoc_const.name_id); - NotePreviousDecl(context, builder, prev_decl_id); - builder.Emit(); - continue; - } - } else if (rewrite_value.has_value()) { - witness_value = context.constant_values().GetInstId(rewrite_value); + if (rewrite_value.has_value()) { + witness_block[index] = + context.constant_values().GetInstId(rewrite_value); } } } diff --git a/toolchain/check/impl.h b/toolchain/check/impl.h index daf84dbbda2a..7a513bab4b9e 100644 --- a/toolchain/check/impl.h +++ b/toolchain/check/impl.h @@ -16,9 +16,7 @@ auto ImplWitnessForDeclaration(Context& context, const SemIR::Impl& impl) auto AddConstantsToImplWitnessFromConstraint(Context& context, const SemIR::Impl& impl, - SemIR::InstId witness_id, - SemIR::ImplId prev_decl_id) - -> void; + SemIR::InstId witness_id) -> void; // Update `impl`'s witness at the start of a definition. auto ImplWitnessStartDefinition(Context& context, SemIR::Impl& impl) -> void; diff --git a/toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon b/toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon index caaad34b6a70..e786784efab5 100644 --- a/toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon +++ b/toolchain/check/testdata/impl/no_prelude/impl_assoc_const.carbon @@ -23,11 +23,15 @@ interface I2 { let T2:! type; } impl () as I2 where .T2 = {}; impl () as I2 where .T2 = {} {} -// --- redecl_adds_rewrites.carbon +// --- fail_redecl_adds_rewrites.carbon library "[[@TEST_NAME]]"; interface I3 { let T3:! type; } +// CHECK:STDERR: fail_redecl_adds_rewrites.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl () as I3; +// CHECK:STDERR: ^~~~~~~~~~~~~~ +// CHECK:STDERR: impl () as I3; impl () as I3 where .T3 = {} {} @@ -36,14 +40,11 @@ library "[[@TEST_NAME]]"; interface J { let U:! type; } -impl () as J where .U = {}; -// CHECK:STDERR: fail_mismatch.carbon:[[@LINE+7]]:1: error: redeclaration with different value for associated constant U [AssociatedConstantDifferentInRedecl] -// CHECK:STDERR: impl () as J where .U = () {} -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// CHECK:STDERR: fail_mismatch.carbon:[[@LINE-4]]:1: note: impl previously declared here [ImplPreviousDeclHere] +// CHECK:STDERR: fail_mismatch.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] // CHECK:STDERR: impl () as J where .U = {}; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: +impl () as J where .U = {}; impl () as J where .U = () {} // --- fail_mismatch_bad_value.carbon @@ -55,10 +56,6 @@ interface I4 { let T6:! type; } -// This is testing that it won't complain about mismatching values if one of -// them is an error. Note that both impl declarations must have facet types -// with errors in them or they won't match each other. - // CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+8]]:27: error: name `BAD1` not found [NameNotFound] // CHECK:STDERR: impl () as I4 where .T4 = BAD1 and .T5 = {.a: {}} and .T6 = BAD2; // CHECK:STDERR: ^~~~ @@ -69,14 +66,18 @@ interface I4 { // CHECK:STDERR: impl () as I4 where .T4 = BAD1 and .T5 = {.a: {}} and .T6 = BAD2; -// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+8]]:46: error: name `BAD3` not found [NameNotFound] +// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+12]]:46: error: name `BAD3` not found [NameNotFound] // CHECK:STDERR: impl () as I4 where .T4 = {.b: {}} and .T5 = BAD3 and .T6 = BAD4 {} // CHECK:STDERR: ^~~~ // CHECK:STDERR: -// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+4]]:61: error: name `BAD4` not found [NameNotFound] +// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+8]]:61: error: name `BAD4` not found [NameNotFound] // CHECK:STDERR: impl () as I4 where .T4 = {.b: {}} and .T5 = BAD3 and .T6 = BAD4 {} // CHECK:STDERR: ^~~~ // CHECK:STDERR: +// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE-10]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl () as I4 where .T4 = BAD1 and .T5 = {.a: {}} and .T6 = BAD2; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: impl () as I4 where .T4 = {.b: {}} and .T5 = BAD3 and .T6 = BAD4 {} // --- fail_missing_on_definition.carbon @@ -85,10 +86,14 @@ library "[[@TEST_NAME]]"; interface K { let V:! type; } impl () as K where .V = {}; -// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE+7]]:1: error: associated constant V given value in declaration but not redeclaration [AssociatedConstantMissingInRedecl] +// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE+11]]:12: error: associated constant V not given a value in impl of interface K [ImplAssociatedConstantNeedsValue] // CHECK:STDERR: impl () as K {} -// CHECK:STDERR: ^~~~~~~~~~~~~~ -// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE-4]]:1: note: impl previously declared here [ImplPreviousDeclHere] +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE-6]]:19: note: associated constant declared here [AssociatedConstantHere] +// CHECK:STDERR: interface K { let V:! type; } +// CHECK:STDERR: ^~~~~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE-8]]:1: error: impl declared but not defined [ImplMissingDefinition] // CHECK:STDERR: impl () as K where .V = {}; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: @@ -311,7 +316,7 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: // CHECK:STDOUT: specific @T2(constants.%I2.facet) {} // CHECK:STDOUT: -// CHECK:STDOUT: --- redecl_adds_rewrites.carbon +// CHECK:STDOUT: --- fail_redecl_adds_rewrites.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I3.type: type = facet_type <@I3> [template] @@ -319,7 +324,7 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: %I3.assoc_type: type = assoc_entity_type %I3.type [template] // CHECK:STDOUT: %assoc0: %I3.assoc_type = assoc_entity element0, @I3.%T3 [template] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [template] -// CHECK:STDOUT: %impl_witness: = impl_witness (%empty_struct_type) [template] +// CHECK:STDOUT: %impl_witness.85b: = impl_witness () [template] // CHECK:STDOUT: %.Self: %I3.type = bind_symbolic_name .Self [symbolic] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic] // CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self [symbolic] @@ -327,6 +332,7 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template] // CHECK:STDOUT: %I3_where.type: type = facet_type <@I3 where %impl.elem0 = %empty_struct_type> [template] +// CHECK:STDOUT: %impl_witness.6de: = impl_witness (%empty_struct_type) [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -334,29 +340,30 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: .I3 = %I3.decl // CHECK:STDOUT: } // CHECK:STDOUT: %I3.decl: type = interface_decl @I3 [template = constants.%I3.type] {} {} -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %.loc5_7.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc5_7.2: type = converted %.loc5_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %I3.ref.loc5: type = name_ref I3, file.%I3.decl [template = constants.%I3.type] +// CHECK:STDOUT: impl_decl @impl.1 [template] {} { +// CHECK:STDOUT: %.loc9_7.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc9_7.2: type = converted %.loc9_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %I3.ref: type = name_ref I3, file.%I3.decl [template = constants.%I3.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %.loc6_7.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc6_7.2: type = converted %.loc6_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %I3.ref.loc6: type = name_ref I3, file.%I3.decl [template = constants.%I3.type] +// CHECK:STDOUT: %impl_witness.loc9: = impl_witness () [template = constants.%impl_witness.85b] +// CHECK:STDOUT: impl_decl @impl.2 [template] {} { +// CHECK:STDOUT: %.loc10_7.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc10_7.2: type = converted %.loc10_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %I3.ref: type = name_ref I3, file.%I3.decl [template = constants.%I3.type] // CHECK:STDOUT: %.Self: %I3.type = bind_symbolic_name .Self [symbolic = constants.%.Self] // CHECK:STDOUT: %.Self.ref: %I3.type = name_ref .Self, %.Self [symbolic = constants.%.Self] // CHECK:STDOUT: %T3.ref: %I3.assoc_type = name_ref T3, @T3.%assoc0 [template = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc6_21: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc10_21: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0] -// CHECK:STDOUT: %.loc6_28.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc6_28.2: type = converted %.loc6_28.1, constants.%empty_struct_type [template = constants.%empty_struct_type] -// CHECK:STDOUT: %.loc6_15: type = where_expr %.Self [template = constants.%I3_where.type] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc6_28.2 +// CHECK:STDOUT: %.loc10_28.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc10_28.2: type = converted %.loc10_28.1, constants.%empty_struct_type [template = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc10_15: type = where_expr %.Self [template = constants.%I3_where.type] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc10_28.2 // CHECK:STDOUT: } // CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc10: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness.6de] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I3 { @@ -375,9 +382,11 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: assoc_const T3:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %.loc5_7.2 as %I3.ref.loc5 { +// CHECK:STDOUT: impl @impl.1: %.loc9_7.2 as %I3.ref; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.2: %.loc10_7.2 as %.loc10_15 { // CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @T3(constants.%Self) {} @@ -399,8 +408,9 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template] // CHECK:STDOUT: %J_where.type.800: type = facet_type <@J where %impl.elem0 = %empty_struct_type> [template] -// CHECK:STDOUT: %impl_witness: = impl_witness (%empty_struct_type) [template] +// CHECK:STDOUT: %impl_witness.6de: = impl_witness (%empty_struct_type) [template] // CHECK:STDOUT: %J_where.type.25a: type = facet_type <@J where %impl.elem0 = %empty_tuple.type> [template] +// CHECK:STDOUT: %impl_witness.2a6: = impl_witness (%empty_tuple.type) [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -408,41 +418,42 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: .J = %J.decl // CHECK:STDOUT: } // CHECK:STDOUT: %J.decl: type = interface_decl @J [template = constants.%J.type] {} {} -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %.loc5_7.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc5_7.2: type = converted %.loc5_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %J.ref.loc5: type = name_ref J, file.%J.decl [template = constants.%J.type] -// CHECK:STDOUT: %.Self.1: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc5: %J.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self] -// CHECK:STDOUT: %U.ref.loc5: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0] -// CHECK:STDOUT: %.Self.as_type.loc5: type = facet_access_type %.Self.ref.loc5 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc5_20: type = converted %.Self.ref.loc5, %.Self.as_type.loc5 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc5: = facet_access_witness %.Self.ref.loc5 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc5: type = impl_witness_access %.Self.as_wit.loc5, element0 [symbolic = constants.%impl.elem0] -// CHECK:STDOUT: %.loc5_26.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc5_26.2: type = converted %.loc5_26.1, constants.%empty_struct_type [template = constants.%empty_struct_type] -// CHECK:STDOUT: %.loc5_14: type = where_expr %.Self.1 [template = constants.%J_where.type.800] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc5, %.loc5_26.2 +// CHECK:STDOUT: impl_decl @impl.1 [template] {} { +// CHECK:STDOUT: %.loc9_7.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc9_7.2: type = converted %.loc9_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [template = constants.%J.type] +// CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %J.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %U.ref: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc9_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0] +// CHECK:STDOUT: %.loc9_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_26.2: type = converted %.loc9_26.1, constants.%empty_struct_type [template = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc9_14: type = where_expr %.Self [template = constants.%J_where.type.800] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc9_26.2 // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %.loc13_7.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_7.2: type = converted %.loc13_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %J.ref.loc13: type = name_ref J, file.%J.decl [template = constants.%J.type] -// CHECK:STDOUT: %.Self.2: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc13: %J.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self] -// CHECK:STDOUT: %U.ref.loc13: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0] -// CHECK:STDOUT: %.Self.as_type.loc13: type = facet_access_type %.Self.ref.loc13 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc13_20: type = converted %.Self.ref.loc13, %.Self.as_type.loc13 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc13: = facet_access_witness %.Self.ref.loc13 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc13: type = impl_witness_access %.Self.as_wit.loc13, element0 [symbolic = constants.%impl.elem0] -// CHECK:STDOUT: %.loc13_26.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_26.2: type = converted %.loc13_26.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %.loc13_14: type = where_expr %.Self.2 [template = constants.%J_where.type.25a] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc13, %.loc13_26.2 +// CHECK:STDOUT: %impl_witness.loc9: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness.6de] +// CHECK:STDOUT: impl_decl @impl.2 [template] {} { +// CHECK:STDOUT: %.loc10_7.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc10_7.2: type = converted %.loc10_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [template = constants.%J.type] +// CHECK:STDOUT: %.Self: %J.type = bind_symbolic_name .Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %J.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %U.ref: %J.assoc_type = name_ref U, @U.%assoc0 [template = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc10_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0] +// CHECK:STDOUT: %.loc10_26.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc10_26.2: type = converted %.loc10_26.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc10_14: type = where_expr %.Self [template = constants.%J_where.type.25a] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc10_26.2 // CHECK:STDOUT: } // CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc10: = impl_witness (constants.%empty_tuple.type) [template = constants.%impl_witness.2a6] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @J { @@ -461,9 +472,11 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: assoc_const U:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %.loc5_7.2 as %.loc5_14 { +// CHECK:STDOUT: impl @impl.1: %.loc9_7.2 as %.loc9_14; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.2: %.loc10_7.2 as %.loc10_14 { // CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @U(constants.%Self) {} @@ -497,72 +510,72 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: .I4 = %I4.decl // CHECK:STDOUT: } // CHECK:STDOUT: %I4.decl: type = interface_decl @I4 [template = constants.%I4.type] {} {} -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %.loc21_7.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc21_7.2: type = converted %.loc21_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %I4.ref.loc21: type = name_ref I4, file.%I4.decl [template = constants.%I4.type] -// CHECK:STDOUT: %.Self.1: %I4.type = bind_symbolic_name .Self [symbolic = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc21_21: %I4.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T4.ref.loc21: %I4.assoc_type = name_ref T4, @T4.%assoc0 [template = constants.%assoc0] -// CHECK:STDOUT: %.Self.as_type.loc21_21: type = facet_access_type %.Self.ref.loc21_21 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc21_21: type = converted %.Self.ref.loc21_21, %.Self.as_type.loc21_21 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc21_21: = facet_access_witness %.Self.ref.loc21_21 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc21: type = impl_witness_access %.Self.as_wit.loc21_21, element0 [symbolic = constants.%impl.elem0] +// CHECK:STDOUT: impl_decl @impl.1 [template] {} { +// CHECK:STDOUT: %.loc17_7.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc17_7.2: type = converted %.loc17_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %I4.ref: type = name_ref I4, file.%I4.decl [template = constants.%I4.type] +// CHECK:STDOUT: %.Self: %I4.type = bind_symbolic_name .Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc17_21: %I4.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T4.ref: %I4.assoc_type = name_ref T4, @T4.%assoc0 [template = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type.loc17_21: type = facet_access_type %.Self.ref.loc17_21 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc17_21: type = converted %.Self.ref.loc17_21, %.Self.as_type.loc17_21 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit.loc17_21: = facet_access_witness %.Self.ref.loc17_21 [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit.loc17_21, element0 [symbolic = constants.%impl.elem0] // CHECK:STDOUT: %BAD1.ref: = name_ref BAD1, [template = ] -// CHECK:STDOUT: %.Self.ref.loc21_36: %I4.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T5.ref.loc21: %I4.assoc_type = name_ref T5, @T5.%assoc1 [template = constants.%assoc1] -// CHECK:STDOUT: %.Self.as_type.loc21_36: type = facet_access_type %.Self.ref.loc21_36 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc21_36: type = converted %.Self.ref.loc21_36, %.Self.as_type.loc21_36 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc21_36: = facet_access_witness %.Self.ref.loc21_36 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem1.loc21: type = impl_witness_access %.Self.as_wit.loc21_36, element1 [symbolic = constants.%impl.elem1] -// CHECK:STDOUT: %.loc21_48.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc21_48.2: type = converted %.loc21_48.1, constants.%empty_struct_type [template = constants.%empty_struct_type] +// CHECK:STDOUT: %.Self.ref.loc17_36: %I4.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T5.ref: %I4.assoc_type = name_ref T5, @T5.%assoc1 [template = constants.%assoc1] +// CHECK:STDOUT: %.Self.as_type.loc17_36: type = facet_access_type %.Self.ref.loc17_36 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc17_36: type = converted %.Self.ref.loc17_36, %.Self.as_type.loc17_36 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit.loc17_36: = facet_access_witness %.Self.ref.loc17_36 [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem1: type = impl_witness_access %.Self.as_wit.loc17_36, element1 [symbolic = constants.%impl.elem1] +// CHECK:STDOUT: %.loc17_48.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc17_48.2: type = converted %.loc17_48.1, constants.%empty_struct_type [template = constants.%empty_struct_type] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %empty_struct_type} [template = constants.%struct_type.a] -// CHECK:STDOUT: %.Self.ref.loc21_55: %I4.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T6.ref.loc21: %I4.assoc_type = name_ref T6, @T6.%assoc2 [template = constants.%assoc2] -// CHECK:STDOUT: %.Self.as_type.loc21_55: type = facet_access_type %.Self.ref.loc21_55 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc21_55: type = converted %.Self.ref.loc21_55, %.Self.as_type.loc21_55 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc21_55: = facet_access_witness %.Self.ref.loc21_55 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem2.loc21: type = impl_witness_access %.Self.as_wit.loc21_55, element2 [symbolic = constants.%impl.elem2] +// CHECK:STDOUT: %.Self.ref.loc17_55: %I4.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T6.ref: %I4.assoc_type = name_ref T6, @T6.%assoc2 [template = constants.%assoc2] +// CHECK:STDOUT: %.Self.as_type.loc17_55: type = facet_access_type %.Self.ref.loc17_55 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc17_55: type = converted %.Self.ref.loc17_55, %.Self.as_type.loc17_55 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit.loc17_55: = facet_access_witness %.Self.ref.loc17_55 [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem2: type = impl_witness_access %.Self.as_wit.loc17_55, element2 [symbolic = constants.%impl.elem2] // CHECK:STDOUT: %BAD2.ref: = name_ref BAD2, [template = ] -// CHECK:STDOUT: %.loc21_15: type = where_expr %.Self.1 [template = ] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc21, -// CHECK:STDOUT: requirement_rewrite %impl.elem1.loc21, %struct_type.a -// CHECK:STDOUT: requirement_rewrite %impl.elem2.loc21, +// CHECK:STDOUT: %.loc17_15: type = where_expr %.Self [template = ] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, +// CHECK:STDOUT: requirement_rewrite %impl.elem1, %struct_type.a +// CHECK:STDOUT: requirement_rewrite %impl.elem2, // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl [template] {} { +// CHECK:STDOUT: impl_decl @impl.2 [template] {} { // CHECK:STDOUT: %.loc31_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc31_7.2: type = converted %.loc31_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %I4.ref.loc31: type = name_ref I4, file.%I4.decl [template = constants.%I4.type] -// CHECK:STDOUT: %.Self.2: %I4.type = bind_symbolic_name .Self [symbolic = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc31_21: %I4.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T4.ref.loc31: %I4.assoc_type = name_ref T4, @T4.%assoc0 [template = constants.%assoc0] +// CHECK:STDOUT: %I4.ref: type = name_ref I4, file.%I4.decl [template = constants.%I4.type] +// CHECK:STDOUT: %.Self: %I4.type = bind_symbolic_name .Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc31_21: %I4.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T4.ref: %I4.assoc_type = name_ref T4, @T4.%assoc0 [template = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc31_21: type = facet_access_type %.Self.ref.loc31_21 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.loc31_21: type = converted %.Self.ref.loc31_21, %.Self.as_type.loc31_21 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit.loc31_21: = facet_access_witness %.Self.ref.loc31_21 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc31: type = impl_witness_access %.Self.as_wit.loc31_21, element0 [symbolic = constants.%impl.elem0] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit.loc31_21, element0 [symbolic = constants.%impl.elem0] // CHECK:STDOUT: %.loc31_33.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc31_33.2: type = converted %.loc31_33.1, constants.%empty_struct_type [template = constants.%empty_struct_type] // CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %empty_struct_type} [template = constants.%struct_type.b] -// CHECK:STDOUT: %.Self.ref.loc31_40: %I4.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T5.ref.loc31: %I4.assoc_type = name_ref T5, @T5.%assoc1 [template = constants.%assoc1] +// CHECK:STDOUT: %.Self.ref.loc31_40: %I4.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T5.ref: %I4.assoc_type = name_ref T5, @T5.%assoc1 [template = constants.%assoc1] // CHECK:STDOUT: %.Self.as_type.loc31_40: type = facet_access_type %.Self.ref.loc31_40 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.loc31_40: type = converted %.Self.ref.loc31_40, %.Self.as_type.loc31_40 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit.loc31_40: = facet_access_witness %.Self.ref.loc31_40 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem1.loc31: type = impl_witness_access %.Self.as_wit.loc31_40, element1 [symbolic = constants.%impl.elem1] +// CHECK:STDOUT: %impl.elem1: type = impl_witness_access %.Self.as_wit.loc31_40, element1 [symbolic = constants.%impl.elem1] // CHECK:STDOUT: %BAD3.ref: = name_ref BAD3, [template = ] -// CHECK:STDOUT: %.Self.ref.loc31_55: %I4.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T6.ref.loc31: %I4.assoc_type = name_ref T6, @T6.%assoc2 [template = constants.%assoc2] +// CHECK:STDOUT: %.Self.ref.loc31_55: %I4.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T6.ref: %I4.assoc_type = name_ref T6, @T6.%assoc2 [template = constants.%assoc2] // CHECK:STDOUT: %.Self.as_type.loc31_55: type = facet_access_type %.Self.ref.loc31_55 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.loc31_55: type = converted %.Self.ref.loc31_55, %.Self.as_type.loc31_55 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit.loc31_55: = facet_access_witness %.Self.ref.loc31_55 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem2.loc31: type = impl_witness_access %.Self.as_wit.loc31_55, element2 [symbolic = constants.%impl.elem2] +// CHECK:STDOUT: %impl.elem2: type = impl_witness_access %.Self.as_wit.loc31_55, element2 [symbolic = constants.%impl.elem2] // CHECK:STDOUT: %BAD4.ref: = name_ref BAD4, [template = ] -// CHECK:STDOUT: %.loc31_15: type = where_expr %.Self.2 [template = ] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc31, %struct_type.b -// CHECK:STDOUT: requirement_rewrite %impl.elem1.loc31, -// CHECK:STDOUT: requirement_rewrite %impl.elem2.loc31, +// CHECK:STDOUT: %.loc31_15: type = where_expr %.Self [template = ] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %struct_type.b +// CHECK:STDOUT: requirement_rewrite %impl.elem1, +// CHECK:STDOUT: requirement_rewrite %impl.elem2, // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -599,7 +612,9 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: assoc_const T6:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %.loc21_7.2 as %.loc21_15 { +// CHECK:STDOUT: impl @impl.1: %.loc17_7.2 as %.loc17_15; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.2: %.loc31_7.2 as %.loc31_15 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = // CHECK:STDOUT: } @@ -631,7 +646,8 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template] // CHECK:STDOUT: %K_where.type: type = facet_type <@K where %impl.elem0 = %empty_struct_type> [template] -// CHECK:STDOUT: %impl_witness: = impl_witness (%empty_struct_type) [template] +// CHECK:STDOUT: %impl_witness.6de: = impl_witness (%empty_struct_type) [template] +// CHECK:STDOUT: %impl_witness.85b: = impl_witness () [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -639,10 +655,10 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: .K = %K.decl // CHECK:STDOUT: } // CHECK:STDOUT: %K.decl: type = interface_decl @K [template = constants.%K.type] {} {} -// CHECK:STDOUT: impl_decl @impl [template] {} { +// CHECK:STDOUT: impl_decl @impl.1 [template] {} { // CHECK:STDOUT: %.loc5_7.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc5_7.2: type = converted %.loc5_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %K.ref.loc5: type = name_ref K, file.%K.decl [template = constants.%K.type] +// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%K.type] // CHECK:STDOUT: %.Self: %K.type = bind_symbolic_name .Self [symbolic = constants.%.Self] // CHECK:STDOUT: %.Self.ref: %K.type = name_ref .Self, %.Self [symbolic = constants.%.Self] // CHECK:STDOUT: %V.ref: %K.assoc_type = name_ref V, @V.%assoc0 [template = constants.%assoc0] @@ -656,12 +672,13 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc5_26.2 // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %.loc13_7.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_7.2: type = converted %.loc13_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %K.ref.loc13: type = name_ref K, file.%K.decl [template = constants.%K.type] +// CHECK:STDOUT: %impl_witness.loc5: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness.6de] +// CHECK:STDOUT: impl_decl @impl.2 [template] {} { +// CHECK:STDOUT: %.loc17_7.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc17_7.2: type = converted %.loc17_7.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %K.ref: type = name_ref K, file.%K.decl [template = constants.%K.type] // CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc17: = impl_witness () [template = constants.%impl_witness.85b] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @K { @@ -680,9 +697,11 @@ impl () as N where .Y = {.a = {}} { } // CHECK:STDOUT: assoc_const V:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %.loc5_7.2 as %.loc5_14 { +// CHECK:STDOUT: impl @impl.1: %.loc5_7.2 as %.loc5_14; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.2: %.loc17_7.2 as %K.ref { // CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: witness = file.%impl_witness.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @V(constants.%Self) {} diff --git a/toolchain/check/testdata/impl/no_prelude/impl_where_redecl.carbon b/toolchain/check/testdata/impl/no_prelude/impl_where_redecl.carbon index b228186da227..f5d18051f7a1 100644 --- a/toolchain/check/testdata/impl/no_prelude/impl_where_redecl.carbon +++ b/toolchain/check/testdata/impl/no_prelude/impl_where_redecl.carbon @@ -10,38 +10,62 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/no_prelude/impl_where_redecl.carbon -// --- match.carbon +// `impl` declarations only match when they are the same syntactically. + +// --- fail_match_with_associated_type.carbon library "[[@TEST_NAME]]"; interface I { let T:! type; } -interface J {} - -// `impl` matching ignores the `where` clause. It should not get confused by -// nested `where`, so the following should not trigger impl declaration without -// definition diagnostics. +// CHECK:STDERR: fail_match_with_associated_type.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl () as I where .T = {}; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: impl () as I where .T = {}; impl () as I where .T = {} and .T impls (type where .Self impls type) {} +// CHECK:STDERR: fail_match_with_associated_type.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl {} as I; +// CHECK:STDERR: ^~~~~~~~~~~~~ +// CHECK:STDERR: impl {} as I; impl {} as I where .T = {} and .T impls (type where .Self impls type) {} +// CHECK:STDERR: fail_match_with_associated_type.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl ({},) as I where .T = {} and .T impls (type where .Self impls type); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: impl ({},) as I where .T = {} and .T impls (type where .Self impls type); impl ({},) as I where .T = {} {} +// --- fail_match_with_empty_interface.carbon +library "[[@TEST_NAME]]"; + +interface J {} + +// CHECK:STDERR: fail_match_with_empty_interface.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl () as J; +// CHECK:STDERR: ^~~~~~~~~~~~~ +// CHECK:STDERR: impl () as J; impl () as J where .Self impls type and .Self impls (type where .Self impls type) {} +// CHECK:STDERR: fail_match_with_empty_interface.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl {} as J where .Self impls type and .Self impls (type where .Self impls type); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: impl {} as J where .Self impls type and .Self impls (type where .Self impls type); impl {} as J {} -// --- parens_other_nesting.carbon +// --- fail_parens_other_nesting.carbon library "[[@TEST_NAME]]"; interface K {} -// `impl` matching only ignores a root-level `where` clause. - +// CHECK:STDERR: fail_parens_other_nesting.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl {} as (K where .Self impls type) where .Self impls type; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: impl {} as (K where .Self impls type) where .Self impls type; impl {} as (K where .Self impls type) {} diff --git a/toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon b/toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon index f0baf1a128b7..1f351b9f66ea 100644 --- a/toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon +++ b/toolchain/check/testdata/impl/no_prelude/import_interface_assoc_const.carbon @@ -38,11 +38,15 @@ class C2 { } impl C2 as I where .T = {}; impl C2 as I where .T = {} { } -// --- redecl_adds_rewrites.carbon +// --- fail_redecl_adds_rewrites.carbon library "[[@TEST_NAME]]"; import library "interface"; class C3 { } +// CHECK:STDERR: fail_redecl_adds_rewrites.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl C3 as I; +// CHECK:STDERR: ^~~~~~~~~~~~~ +// CHECK:STDERR: impl C3 as I; impl C3 as I where .T = {} { } @@ -51,14 +55,11 @@ library "[[@TEST_NAME]]"; import library "interface"; class C4 { } -impl C4 as I where .T = {}; -// CHECK:STDERR: fail_mismatch.carbon:[[@LINE+7]]:1: error: redeclaration with different value for associated constant T [AssociatedConstantDifferentInRedecl] -// CHECK:STDERR: impl C4 as I where .T = () { } -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// CHECK:STDERR: fail_mismatch.carbon:[[@LINE-4]]:1: note: impl previously declared here [ImplPreviousDeclHere] +// CHECK:STDERR: fail_mismatch.carbon:[[@LINE+4]]:1: error: impl declared but not defined [ImplMissingDefinition] // CHECK:STDERR: impl C4 as I where .T = {}; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: +impl C4 as I where .T = {}; impl C4 as I where .T = () { } // --- fail_mismatch_bad_value.carbon @@ -81,14 +82,18 @@ class C5 { } // CHECK:STDERR: impl C5 as I3 where .T1 = BAD1 and .T2 = {.a: {}} and .T3 = BAD2; -// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+8]]:46: error: name `BAD3` not found [NameNotFound] +// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+12]]:46: error: name `BAD3` not found [NameNotFound] // CHECK:STDERR: impl C5 as I3 where .T1 = {.b: {}} and .T2 = BAD3 and .T3 = BAD4 { } // CHECK:STDERR: ^~~~ // CHECK:STDERR: -// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+4]]:61: error: name `BAD4` not found [NameNotFound] +// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE+8]]:61: error: name `BAD4` not found [NameNotFound] // CHECK:STDERR: impl C5 as I3 where .T1 = {.b: {}} and .T2 = BAD3 and .T3 = BAD4 { } // CHECK:STDERR: ^~~~ // CHECK:STDERR: +// CHECK:STDERR: fail_mismatch_bad_value.carbon:[[@LINE-10]]:1: error: impl declared but not defined [ImplMissingDefinition] +// CHECK:STDERR: impl C5 as I3 where .T1 = BAD1 and .T2 = {.a: {}} and .T3 = BAD2; +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: impl C5 as I3 where .T1 = {.b: {}} and .T2 = BAD3 and .T3 = BAD4 { } // --- fail_missing_on_definition.carbon @@ -97,10 +102,15 @@ import library "interface"; class C6 { } impl C6 as I where .T = {}; -// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE+7]]:1: error: associated constant T given value in declaration but not redeclaration [AssociatedConstantMissingInRedecl] +// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE+12]]:12: error: associated constant T not given a value in impl of interface I [ImplAssociatedConstantNeedsValue] // CHECK:STDERR: impl C6 as I { } -// CHECK:STDERR: ^~~~~~~~~~~~~~ -// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE-4]]:1: note: impl previously declared here [ImplPreviousDeclHere] +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE-7]]:1: in import [InImport] +// CHECK:STDERR: interface.carbon:3:19: note: associated constant declared here [AssociatedConstantHere] +// CHECK:STDERR: interface I { let T:! type; } +// CHECK:STDERR: ^~~~~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_missing_on_definition.carbon:[[@LINE-9]]:1: error: impl declared but not defined [ImplMissingDefinition] // CHECK:STDERR: impl C6 as I where .T = {}; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: @@ -464,7 +474,7 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: // CHECK:STDOUT: specific @T(constants.%I.facet) {} // CHECK:STDOUT: -// CHECK:STDOUT: --- redecl_adds_rewrites.carbon +// CHECK:STDOUT: --- fail_redecl_adds_rewrites.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C3: type = class_type @C3 [template] @@ -472,7 +482,7 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [template] // CHECK:STDOUT: %I.type: type = facet_type <@I> [template] // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %impl_witness: = impl_witness (%empty_struct_type) [template] +// CHECK:STDOUT: %impl_witness.85b: = impl_witness () [template] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type %I.type [template] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.652 [template] @@ -481,6 +491,7 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: %I.facet: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_struct_type> [template] +// CHECK:STDOUT: %impl_witness.6de: = impl_witness (%empty_struct_type) [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -501,27 +512,28 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %C3.decl: type = class_decl @C3 [template = constants.%C3] {} {} -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %C3.ref.loc5: type = name_ref C3, file.%C3.decl [template = constants.%C3] -// CHECK:STDOUT: %I.ref.loc5: type = name_ref I, imports.%Main.I [template = constants.%I.type] +// CHECK:STDOUT: impl_decl @impl.1 [template] {} { +// CHECK:STDOUT: %C3.ref: type = name_ref C3, file.%C3.decl [template = constants.%C3] +// CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [template = constants.%I.type] // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %C3.ref.loc6: type = name_ref C3, file.%C3.decl [template = constants.%C3] -// CHECK:STDOUT: %I.ref.loc6: type = name_ref I, imports.%Main.I [template = constants.%I.type] +// CHECK:STDOUT: %impl_witness.loc9: = impl_witness () [template = constants.%impl_witness.85b] +// CHECK:STDOUT: impl_decl @impl.2 [template] {} { +// CHECK:STDOUT: %C3.ref: type = name_ref C3, file.%C3.decl [template = constants.%C3] +// CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [template = constants.%I.type] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self] // CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self] // CHECK:STDOUT: %T.ref: %I.assoc_type = name_ref T, imports.%Main.import_ref.585 [template = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc6_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc10_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0] -// CHECK:STDOUT: %.loc6_26.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc6_26.2: type = converted %.loc6_26.1, constants.%empty_struct_type [template = constants.%empty_struct_type] -// CHECK:STDOUT: %.loc6_14: type = where_expr %.Self [template = constants.%I_where.type] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc6_26.2 +// CHECK:STDOUT: %.loc10_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc10_26.2: type = converted %.loc10_26.1, constants.%empty_struct_type [template = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc10_14: type = where_expr %.Self [template = constants.%I_where.type] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc10_26.2 // CHECK:STDOUT: } // CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc10: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness.6de] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I [from "interface.carbon"] { @@ -535,9 +547,11 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %C3.ref.loc5 as %I.ref.loc5 { +// CHECK:STDOUT: impl @impl.1: %C3.ref as %I.ref; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.2: %C3.ref as %.loc10_14 { // CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C3 { @@ -569,8 +583,9 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: %I.facet: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic] // CHECK:STDOUT: %I_where.type.f5a: type = facet_type <@I where %impl.elem0 = %empty_struct_type> [template] -// CHECK:STDOUT: %impl_witness: = impl_witness (%empty_struct_type) [template] +// CHECK:STDOUT: %impl_witness.6de: = impl_witness (%empty_struct_type) [template] // CHECK:STDOUT: %I_where.type.05a: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [template] +// CHECK:STDOUT: %impl_witness.2a6: = impl_witness (%empty_tuple.type) [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -591,39 +606,40 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %C4.decl: type = class_decl @C4 [template = constants.%C4] {} {} -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %C4.ref.loc5: type = name_ref C4, file.%C4.decl [template = constants.%C4] -// CHECK:STDOUT: %I.ref.loc5: type = name_ref I, imports.%Main.I [template = constants.%I.type] -// CHECK:STDOUT: %.Self.1: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc5: %I.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T.ref.loc5: %I.assoc_type = name_ref T, imports.%Main.import_ref.585 [template = constants.%assoc0] -// CHECK:STDOUT: %.Self.as_type.loc5: type = facet_access_type %.Self.ref.loc5 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc5_20: type = converted %.Self.ref.loc5, %.Self.as_type.loc5 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc5: = facet_access_witness %.Self.ref.loc5 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc5: type = impl_witness_access %.Self.as_wit.loc5, element0 [symbolic = constants.%impl.elem0] -// CHECK:STDOUT: %.loc5_26.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc5_26.2: type = converted %.loc5_26.1, constants.%empty_struct_type [template = constants.%empty_struct_type] -// CHECK:STDOUT: %.loc5_14: type = where_expr %.Self.1 [template = constants.%I_where.type.f5a] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc5, %.loc5_26.2 +// CHECK:STDOUT: impl_decl @impl.1 [template] {} { +// CHECK:STDOUT: %C4.ref: type = name_ref C4, file.%C4.decl [template = constants.%C4] +// CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [template = constants.%I.type] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T.ref: %I.assoc_type = name_ref T, imports.%Main.import_ref.585 [template = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc9_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0] +// CHECK:STDOUT: %.loc9_26.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc9_26.2: type = converted %.loc9_26.1, constants.%empty_struct_type [template = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc9_14: type = where_expr %.Self [template = constants.%I_where.type.f5a] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc9_26.2 // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %C4.ref.loc13: type = name_ref C4, file.%C4.decl [template = constants.%C4] -// CHECK:STDOUT: %I.ref.loc13: type = name_ref I, imports.%Main.I [template = constants.%I.type] -// CHECK:STDOUT: %.Self.2: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc13: %I.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T.ref.loc13: %I.assoc_type = name_ref T, imports.%Main.import_ref.585 [template = constants.%assoc0] -// CHECK:STDOUT: %.Self.as_type.loc13: type = facet_access_type %.Self.ref.loc13 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc13_20: type = converted %.Self.ref.loc13, %.Self.as_type.loc13 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc13: = facet_access_witness %.Self.ref.loc13 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc13: type = impl_witness_access %.Self.as_wit.loc13, element0 [symbolic = constants.%impl.elem0] -// CHECK:STDOUT: %.loc13_26.1: %empty_tuple.type = tuple_literal () -// CHECK:STDOUT: %.loc13_26.2: type = converted %.loc13_26.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] -// CHECK:STDOUT: %.loc13_14: type = where_expr %.Self.2 [template = constants.%I_where.type.05a] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc13, %.loc13_26.2 +// CHECK:STDOUT: %impl_witness.loc9: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness.6de] +// CHECK:STDOUT: impl_decl @impl.2 [template] {} { +// CHECK:STDOUT: %C4.ref: type = name_ref C4, file.%C4.decl [template = constants.%C4] +// CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [template = constants.%I.type] +// CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T.ref: %I.assoc_type = name_ref T, imports.%Main.import_ref.585 [template = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc10_20: type = converted %.Self.ref, %.Self.as_type [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit: = facet_access_witness %.Self.ref [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic = constants.%impl.elem0] +// CHECK:STDOUT: %.loc10_26.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc10_26.2: type = converted %.loc10_26.1, constants.%empty_tuple.type [template = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc10_14: type = where_expr %.Self [template = constants.%I_where.type.05a] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc10_26.2 // CHECK:STDOUT: } // CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc10: = impl_witness (constants.%empty_tuple.type) [template = constants.%impl_witness.2a6] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I [from "interface.carbon"] { @@ -637,9 +653,11 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %C4.ref.loc5 as %.loc5_14 { +// CHECK:STDOUT: impl @impl.1: %C4.ref as %.loc9_14; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.2: %C4.ref as %.loc10_14 { // CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: witness = file.%impl_witness.loc10 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C4 { @@ -699,70 +717,70 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %C5.decl: type = class_decl @C5 [template = constants.%C5] {} {} -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %C5.ref.loc18: type = name_ref C5, file.%C5.decl [template = constants.%C5] -// CHECK:STDOUT: %I3.ref.loc18: type = name_ref I3, imports.%Main.I3 [template = constants.%I3.type] -// CHECK:STDOUT: %.Self.1: %I3.type = bind_symbolic_name .Self [symbolic = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc18_21: %I3.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T1.ref.loc18: %I3.assoc_type = name_ref T1, imports.%Main.import_ref.760 [template = constants.%assoc0] +// CHECK:STDOUT: impl_decl @impl.1 [template] {} { +// CHECK:STDOUT: %C5.ref: type = name_ref C5, file.%C5.decl [template = constants.%C5] +// CHECK:STDOUT: %I3.ref: type = name_ref I3, imports.%Main.I3 [template = constants.%I3.type] +// CHECK:STDOUT: %.Self: %I3.type = bind_symbolic_name .Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc18_21: %I3.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T1.ref: %I3.assoc_type = name_ref T1, imports.%Main.import_ref.760 [template = constants.%assoc0] // CHECK:STDOUT: %.Self.as_type.loc18_21: type = facet_access_type %.Self.ref.loc18_21 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.loc18_21: type = converted %.Self.ref.loc18_21, %.Self.as_type.loc18_21 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit.loc18_21: = facet_access_witness %.Self.ref.loc18_21 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc18: type = impl_witness_access %.Self.as_wit.loc18_21, element0 [symbolic = constants.%impl.elem0] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit.loc18_21, element0 [symbolic = constants.%impl.elem0] // CHECK:STDOUT: %BAD1.ref: = name_ref BAD1, [template = ] -// CHECK:STDOUT: %.Self.ref.loc18_36: %I3.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T2.ref.loc18: %I3.assoc_type = name_ref T2, imports.%Main.import_ref.309 [template = constants.%assoc1] +// CHECK:STDOUT: %.Self.ref.loc18_36: %I3.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T2.ref: %I3.assoc_type = name_ref T2, imports.%Main.import_ref.309 [template = constants.%assoc1] // CHECK:STDOUT: %.Self.as_type.loc18_36: type = facet_access_type %.Self.ref.loc18_36 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.loc18_36: type = converted %.Self.ref.loc18_36, %.Self.as_type.loc18_36 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit.loc18_36: = facet_access_witness %.Self.ref.loc18_36 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem1.loc18: type = impl_witness_access %.Self.as_wit.loc18_36, element1 [symbolic = constants.%impl.elem1] +// CHECK:STDOUT: %impl.elem1: type = impl_witness_access %.Self.as_wit.loc18_36, element1 [symbolic = constants.%impl.elem1] // CHECK:STDOUT: %.loc18_48.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc18_48.2: type = converted %.loc18_48.1, constants.%empty_struct_type [template = constants.%empty_struct_type] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %empty_struct_type} [template = constants.%struct_type.a] -// CHECK:STDOUT: %.Self.ref.loc18_55: %I3.type = name_ref .Self, %.Self.1 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T3.ref.loc18: %I3.assoc_type = name_ref T3, imports.%Main.import_ref.5c5 [template = constants.%assoc2] +// CHECK:STDOUT: %.Self.ref.loc18_55: %I3.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T3.ref: %I3.assoc_type = name_ref T3, imports.%Main.import_ref.5c5 [template = constants.%assoc2] // CHECK:STDOUT: %.Self.as_type.loc18_55: type = facet_access_type %.Self.ref.loc18_55 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.loc18_55: type = converted %.Self.ref.loc18_55, %.Self.as_type.loc18_55 [symbolic = constants.%.Self.as_type] // CHECK:STDOUT: %.Self.as_wit.loc18_55: = facet_access_witness %.Self.ref.loc18_55 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem2.loc18: type = impl_witness_access %.Self.as_wit.loc18_55, element2 [symbolic = constants.%impl.elem2] +// CHECK:STDOUT: %impl.elem2: type = impl_witness_access %.Self.as_wit.loc18_55, element2 [symbolic = constants.%impl.elem2] // CHECK:STDOUT: %BAD2.ref: = name_ref BAD2, [template = ] -// CHECK:STDOUT: %.loc18_15: type = where_expr %.Self.1 [template = ] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc18, -// CHECK:STDOUT: requirement_rewrite %impl.elem1.loc18, %struct_type.a -// CHECK:STDOUT: requirement_rewrite %impl.elem2.loc18, +// CHECK:STDOUT: %.loc18_15: type = where_expr %.Self [template = ] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, +// CHECK:STDOUT: requirement_rewrite %impl.elem1, %struct_type.a +// CHECK:STDOUT: requirement_rewrite %impl.elem2, // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %C5.ref.loc28: type = name_ref C5, file.%C5.decl [template = constants.%C5] -// CHECK:STDOUT: %I3.ref.loc28: type = name_ref I3, imports.%Main.I3 [template = constants.%I3.type] -// CHECK:STDOUT: %.Self.2: %I3.type = bind_symbolic_name .Self [symbolic = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc28_21: %I3.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T1.ref.loc28: %I3.assoc_type = name_ref T1, imports.%Main.import_ref.760 [template = constants.%assoc0] -// CHECK:STDOUT: %.Self.as_type.loc28_21: type = facet_access_type %.Self.ref.loc28_21 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc28_21: type = converted %.Self.ref.loc28_21, %.Self.as_type.loc28_21 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc28_21: = facet_access_witness %.Self.ref.loc28_21 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem0.loc28: type = impl_witness_access %.Self.as_wit.loc28_21, element0 [symbolic = constants.%impl.elem0] -// CHECK:STDOUT: %.loc28_33.1: %empty_struct_type = struct_literal () -// CHECK:STDOUT: %.loc28_33.2: type = converted %.loc28_33.1, constants.%empty_struct_type [template = constants.%empty_struct_type] +// CHECK:STDOUT: impl_decl @impl.2 [template] {} { +// CHECK:STDOUT: %C5.ref: type = name_ref C5, file.%C5.decl [template = constants.%C5] +// CHECK:STDOUT: %I3.ref: type = name_ref I3, imports.%Main.I3 [template = constants.%I3.type] +// CHECK:STDOUT: %.Self: %I3.type = bind_symbolic_name .Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc32_21: %I3.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T1.ref: %I3.assoc_type = name_ref T1, imports.%Main.import_ref.760 [template = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type.loc32_21: type = facet_access_type %.Self.ref.loc32_21 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc32_21: type = converted %.Self.ref.loc32_21, %.Self.as_type.loc32_21 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit.loc32_21: = facet_access_witness %.Self.ref.loc32_21 [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit.loc32_21, element0 [symbolic = constants.%impl.elem0] +// CHECK:STDOUT: %.loc32_33.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc32_33.2: type = converted %.loc32_33.1, constants.%empty_struct_type [template = constants.%empty_struct_type] // CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %empty_struct_type} [template = constants.%struct_type.b] -// CHECK:STDOUT: %.Self.ref.loc28_40: %I3.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T2.ref.loc28: %I3.assoc_type = name_ref T2, imports.%Main.import_ref.309 [template = constants.%assoc1] -// CHECK:STDOUT: %.Self.as_type.loc28_40: type = facet_access_type %.Self.ref.loc28_40 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc28_40: type = converted %.Self.ref.loc28_40, %.Self.as_type.loc28_40 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc28_40: = facet_access_witness %.Self.ref.loc28_40 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem1.loc28: type = impl_witness_access %.Self.as_wit.loc28_40, element1 [symbolic = constants.%impl.elem1] +// CHECK:STDOUT: %.Self.ref.loc32_40: %I3.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T2.ref: %I3.assoc_type = name_ref T2, imports.%Main.import_ref.309 [template = constants.%assoc1] +// CHECK:STDOUT: %.Self.as_type.loc32_40: type = facet_access_type %.Self.ref.loc32_40 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc32_40: type = converted %.Self.ref.loc32_40, %.Self.as_type.loc32_40 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit.loc32_40: = facet_access_witness %.Self.ref.loc32_40 [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem1: type = impl_witness_access %.Self.as_wit.loc32_40, element1 [symbolic = constants.%impl.elem1] // CHECK:STDOUT: %BAD3.ref: = name_ref BAD3, [template = ] -// CHECK:STDOUT: %.Self.ref.loc28_55: %I3.type = name_ref .Self, %.Self.2 [symbolic = constants.%.Self] -// CHECK:STDOUT: %T3.ref.loc28: %I3.assoc_type = name_ref T3, imports.%Main.import_ref.5c5 [template = constants.%assoc2] -// CHECK:STDOUT: %.Self.as_type.loc28_55: type = facet_access_type %.Self.ref.loc28_55 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.loc28_55: type = converted %.Self.ref.loc28_55, %.Self.as_type.loc28_55 [symbolic = constants.%.Self.as_type] -// CHECK:STDOUT: %.Self.as_wit.loc28_55: = facet_access_witness %.Self.ref.loc28_55 [symbolic = constants.%.Self.as_wit] -// CHECK:STDOUT: %impl.elem2.loc28: type = impl_witness_access %.Self.as_wit.loc28_55, element2 [symbolic = constants.%impl.elem2] +// CHECK:STDOUT: %.Self.ref.loc32_55: %I3.type = name_ref .Self, %.Self [symbolic = constants.%.Self] +// CHECK:STDOUT: %T3.ref: %I3.assoc_type = name_ref T3, imports.%Main.import_ref.5c5 [template = constants.%assoc2] +// CHECK:STDOUT: %.Self.as_type.loc32_55: type = facet_access_type %.Self.ref.loc32_55 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.loc32_55: type = converted %.Self.ref.loc32_55, %.Self.as_type.loc32_55 [symbolic = constants.%.Self.as_type] +// CHECK:STDOUT: %.Self.as_wit.loc32_55: = facet_access_witness %.Self.ref.loc32_55 [symbolic = constants.%.Self.as_wit] +// CHECK:STDOUT: %impl.elem2: type = impl_witness_access %.Self.as_wit.loc32_55, element2 [symbolic = constants.%impl.elem2] // CHECK:STDOUT: %BAD4.ref: = name_ref BAD4, [template = ] -// CHECK:STDOUT: %.loc28_15: type = where_expr %.Self.2 [template = ] { -// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc28, %struct_type.b -// CHECK:STDOUT: requirement_rewrite %impl.elem1.loc28, -// CHECK:STDOUT: requirement_rewrite %impl.elem2.loc28, +// CHECK:STDOUT: %.loc32_15: type = where_expr %.Self [template = ] { +// CHECK:STDOUT: requirement_rewrite %impl.elem0, %struct_type.b +// CHECK:STDOUT: requirement_rewrite %impl.elem1, +// CHECK:STDOUT: requirement_rewrite %impl.elem2, // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -788,7 +806,9 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: assoc_const T3:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %C5.ref.loc18 as %.loc18_15 { +// CHECK:STDOUT: impl @impl.1: %C5.ref as %.loc18_15; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.2: %C5.ref as %.loc32_15 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = // CHECK:STDOUT: } @@ -829,7 +849,8 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: %I.facet: %I.type = facet_value %.Self.as_type, %.Self.as_wit [symbolic] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %.Self.as_wit, element0 [symbolic] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_struct_type> [template] -// CHECK:STDOUT: %impl_witness: = impl_witness (%empty_struct_type) [template] +// CHECK:STDOUT: %impl_witness.6de: = impl_witness (%empty_struct_type) [template] +// CHECK:STDOUT: %impl_witness.85b: = impl_witness () [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -850,9 +871,9 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: } // CHECK:STDOUT: %default.import = import // CHECK:STDOUT: %C6.decl: type = class_decl @C6 [template = constants.%C6] {} {} -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %C6.ref.loc5: type = name_ref C6, file.%C6.decl [template = constants.%C6] -// CHECK:STDOUT: %I.ref.loc5: type = name_ref I, imports.%Main.I [template = constants.%I.type] +// CHECK:STDOUT: impl_decl @impl.1 [template] {} { +// CHECK:STDOUT: %C6.ref: type = name_ref C6, file.%C6.decl [template = constants.%C6] +// CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [template = constants.%I.type] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic = constants.%.Self] // CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic = constants.%.Self] // CHECK:STDOUT: %T.ref: %I.assoc_type = name_ref T, imports.%Main.import_ref.585 [template = constants.%assoc0] @@ -866,11 +887,12 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc5_26.2 // CHECK:STDOUT: } // CHECK:STDOUT: } -// CHECK:STDOUT: %impl_witness: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness] -// CHECK:STDOUT: impl_decl @impl [template] {} { -// CHECK:STDOUT: %C6.ref.loc13: type = name_ref C6, file.%C6.decl [template = constants.%C6] -// CHECK:STDOUT: %I.ref.loc13: type = name_ref I, imports.%Main.I [template = constants.%I.type] +// CHECK:STDOUT: %impl_witness.loc5: = impl_witness (constants.%empty_struct_type) [template = constants.%impl_witness.6de] +// CHECK:STDOUT: impl_decl @impl.2 [template] {} { +// CHECK:STDOUT: %C6.ref: type = name_ref C6, file.%C6.decl [template = constants.%C6] +// CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [template = constants.%I.type] // CHECK:STDOUT: } +// CHECK:STDOUT: %impl_witness.loc18: = impl_witness () [template = constants.%impl_witness.85b] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I [from "interface.carbon"] { @@ -884,9 +906,11 @@ impl CC as NonType where .Y = {.a = {}} { } // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: impl @impl: %C6.ref.loc5 as %.loc5_14 { +// CHECK:STDOUT: impl @impl.1: %C6.ref as %.loc5_14; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @impl.2: %C6.ref as %I.ref { // CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = file.%impl_witness +// CHECK:STDOUT: witness = file.%impl_witness.loc18 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C6 { diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 4d7b8f1ffa2a..d2ff4958c61b 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -256,9 +256,7 @@ CARBON_DIAGNOSTIC_KIND(InterfaceForwardDeclaredHere) CARBON_DIAGNOSTIC_KIND(InterfaceUndefinedWithinDefinition) // Impl checking. -CARBON_DIAGNOSTIC_KIND(AssociatedConstantDifferentInRedecl) CARBON_DIAGNOSTIC_KIND(AssociatedConstantHere) -CARBON_DIAGNOSTIC_KIND(AssociatedConstantMissingInRedecl) CARBON_DIAGNOSTIC_KIND(AssociatedConstantNotConstantAfterConversion) CARBON_DIAGNOSTIC_KIND(AssociatedFunctionHere) CARBON_DIAGNOSTIC_KIND(ExtendImplForall) @@ -273,7 +271,6 @@ CARBON_DIAGNOSTIC_KIND(ImplFunctionWithNonFunction) CARBON_DIAGNOSTIC_KIND(ImplMissingDefinition) CARBON_DIAGNOSTIC_KIND(ImplMissingFunction) CARBON_DIAGNOSTIC_KIND(ImplPreviousDefinition) -CARBON_DIAGNOSTIC_KIND(ImplPreviousDeclHere) CARBON_DIAGNOSTIC_KIND(ImplRedefinition) CARBON_DIAGNOSTIC_KIND(ImplOfUndefinedInterface) diff --git a/toolchain/parse/testdata/where_expr/impl_where.carbon b/toolchain/parse/testdata/where_expr/impl_where.carbon index ca0ca60a9dca..b4f76fa95d52 100644 --- a/toolchain/parse/testdata/where_expr/impl_where.carbon +++ b/toolchain/parse/testdata/where_expr/impl_where.carbon @@ -17,6 +17,13 @@ impl i32 as Interface where .T = () { impl bool as Interface where .T = i32; +impl () as (Interface where .T = {}) {} + +impl {} as (Interface where .T = ()) where .T = (); + +impl f64 as Interface where .T = (type where .Self impls type) { +} + // CHECK:STDOUT: - filename: impl_where.carbon // CHECK:STDOUT: parse_tree: [ // CHECK:STDOUT: {kind: 'FileStart', text: ''}, @@ -53,5 +60,63 @@ impl bool as Interface where .T = i32; // CHECK:STDOUT: {kind: 'RequirementEqual', text: '=', subtree_size: 4}, // CHECK:STDOUT: {kind: 'WhereExpr', text: 'where', subtree_size: 7}, // CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'}, +// CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParenExprStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'}, +// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, +// CHECK:STDOUT: {kind: 'DesignatorExpr', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'StructLiteralStart', text: '{'}, +// CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'RequirementEqual', text: '=', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'WhereExpr', text: 'where', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 16}, +// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'}, +// CHECK:STDOUT: {kind: 'StructLiteralStart', text: '{'}, +// CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParenExprStart', text: '('}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'}, +// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, +// CHECK:STDOUT: {kind: 'DesignatorExpr', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'RequirementEqual', text: '=', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'WhereExpr', text: 'where', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, +// CHECK:STDOUT: {kind: 'DesignatorExpr', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'RequirementEqual', text: '=', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'WhereExpr', text: 'where', subtree_size: 17}, +// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 22}, +// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'}, +// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f64'}, +// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'}, +// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'}, +// CHECK:STDOUT: {kind: 'DesignatorExpr', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ParenExprStart', text: '('}, +// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'}, +// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'SelfTypeName', text: 'Self'}, +// CHECK:STDOUT: {kind: 'DesignatorExpr', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'}, +// CHECK:STDOUT: {kind: 'RequirementImpls', text: 'impls', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'WhereExpr', text: 'where', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'RequirementEqual', text: '=', subtree_size: 12}, +// CHECK:STDOUT: {kind: 'WhereExpr', text: 'where', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 19}, +// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 20}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ]