diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 1a8bfe02a326b..5e08925158f3c 100644 --- a/toolchain/check/eval.cpp +++ b/toolchain/check/eval.cpp @@ -867,6 +867,14 @@ static auto ResolveSpecificDeclForInst(EvalContext& eval_context, for (const auto& interface : info.self_impls_constraints) { ResolveSpecificDeclForSpecificId(eval_context, interface.specific_id); } + for (const auto& constraint : info.extend_named_constraints) { + ResolveSpecificDeclForSpecificId(eval_context, + constraint.specific_id); + } + for (const auto& constraint : info.self_impls_named_constraints) { + ResolveSpecificDeclForSpecificId(eval_context, + constraint.specific_id); + } break; } case CARBON_KIND(SemIR::SpecificId specific_id): { diff --git a/toolchain/check/facet_type.cpp b/toolchain/check/facet_type.cpp index 73dd7ebc39265..d68df95e1f5b2 100644 --- a/toolchain/check/facet_type.cpp +++ b/toolchain/check/facet_type.cpp @@ -55,20 +55,15 @@ static auto WitnessQueryMatchesInterface( static auto IncompleteFacetTypeDiagnosticBuilder( Context& context, SemIR::LocId loc_id, SemIR::TypeInstId facet_type_inst_id, bool is_definition) -> DiagnosticBuilder { - if (is_definition) { - CARBON_DIAGNOSTIC(ImplAsIncompleteFacetTypeDefinition, Error, - "definition of impl as incomplete facet type {0}", - InstIdAsType); - return context.emitter().Build(loc_id, ImplAsIncompleteFacetTypeDefinition, - facet_type_inst_id); - } else { - CARBON_DIAGNOSTIC( - ImplAsIncompleteFacetTypeRewrites, Error, - "declaration of impl as incomplete facet type {0} with rewrites", - InstIdAsType); - return context.emitter().Build(loc_id, ImplAsIncompleteFacetTypeRewrites, - facet_type_inst_id); - } + // TODO: Remove this parameter. Facet types don't need to be complete for impl + // declarations, unless there's a rewrite into `.Self`. But that completeness + // is checked/required by the member access of the rewrite. + CARBON_CHECK(is_definition); + CARBON_DIAGNOSTIC(ImplAsIncompleteFacetTypeDefinition, Error, + "definition of impl as incomplete facet type {0}", + InstIdAsType); + return context.emitter().Build(loc_id, ImplAsIncompleteFacetTypeDefinition, + facet_type_inst_id); } auto GetImplWitnessAccessWithoutSubstitution(Context& context, @@ -105,6 +100,9 @@ auto InitialFacetTypeImplWitness( .specific_id = self_specific_id}); } + // The presence of any rewrite constraints requires that we know how many + // entries to allocate in the witness table, which requires the entire facet + // type to be complete, even if this was a declaration. if (!RequireCompleteType( context, facet_type_id, SemIR::LocId(facet_type_inst_id), [&] { return IncompleteFacetTypeDiagnosticBuilder( diff --git a/toolchain/check/handle_require.cpp b/toolchain/check/handle_require.cpp index 20ab48063ba99..14c3a5c7378ac 100644 --- a/toolchain/check/handle_require.cpp +++ b/toolchain/check/handle_require.cpp @@ -154,6 +154,7 @@ static auto TypeStructureReferencesSelf( struct ValidateRequireResult { SemIR::FacetType facet_type; + SemIR::TypeId facet_type_type_id; const SemIR::IdentifiedFacetType* identified; }; @@ -164,12 +165,14 @@ static auto ValidateRequire(Context& context, SemIR::LocId loc_id, SemIR::InstId constraint_inst_id, SemIR::InstId scope_inst_id) -> std::optional { - auto constraint_constant_value_inst_id = - context.constant_values().GetConstantInstId(constraint_inst_id); - auto constraint_facet_type = context.insts().TryGetAs( - constraint_constant_value_inst_id); + auto constraint_constant_value_id = + context.constant_values().Get(constraint_inst_id); + auto constraint_type_id = + SemIR::TypeId::ForTypeConstant(constraint_constant_value_id); + auto constraint_facet_type = + context.types().TryGetAs(constraint_type_id); if (!constraint_facet_type) { - if (constraint_constant_value_inst_id != SemIR::ErrorInst::InstId) { + if (constraint_constant_value_id != SemIR::ErrorInst::ConstantId) { CARBON_DIAGNOSTIC( RequireImplsMissingFacetType, Error, "`require` declaration constrained by a non-facet type; " @@ -218,6 +221,7 @@ static auto ValidateRequire(Context& context, SemIR::LocId loc_id, } return ValidateRequireResult{.facet_type = *constraint_facet_type, + .facet_type_type_id = constraint_type_id, .identified = &identified}; } @@ -244,7 +248,7 @@ auto HandleParseNode(Context& context, Parse::RequireDeclId node_id) -> bool { return true; } - auto [constraint_facet_type, identified] = *validated; + auto [constraint_facet_type, constraint_type_id, identified] = *validated; if (identified->required_interfaces().empty()) { // A `require T impls type` adds no actual constraints, so nothing to do. DiscardGenericDecl(context); @@ -271,8 +275,27 @@ auto HandleParseNode(Context& context, Parse::RequireDeclId node_id) -> bool { require_impls_decl.require_impls_id = require_impls_id; ReplaceInstBeforeConstantUse(context, decl_id, require_impls_decl); - context.require_impls_stack().AppendToTop(require_impls_id); + // We look for a complete type after BuildGenericDecl, so that the resulting + // RequireCompleteType instruction is part of the enclosing interface or named + // constraint generic definition. Then requiring enclosing entity to be + // complete will resolve that definition (via ResolveSpecificDefinition()) and + // also construct a specific for the `constraint_inst_id`, finding any + // monomorphization errors that result. + if (extend) { + if (!RequireCompleteType( + context, constraint_type_id, SemIR::LocId(constraint_inst_id), [&] { + CARBON_DIAGNOSTIC(RequireImplsIncompleteFacetType, Error, + "`extend require` of incomplete facet type {0}", + InstIdAsType); + return context.emitter().Build(constraint_inst_id, + RequireImplsIncompleteFacetType, + constraint_inst_id); + })) { + return true; + } + } + context.require_impls_stack().AppendToTop(require_impls_id); return true; } diff --git a/toolchain/check/interface.cpp b/toolchain/check/interface.cpp index 779e6a15e23fb..760db856b473f 100644 --- a/toolchain/check/interface.cpp +++ b/toolchain/check/interface.cpp @@ -122,7 +122,7 @@ static auto GetGenericArgsWithSelfType(Context& context, arg_ids.reserve(std::max(reserve_args_size, interface_args.size() + 1)); // Start with the enclosing arguments from the interface. - arg_ids.assign(interface_args.begin(), interface_args.end()); + llvm::append_range(arg_ids, interface_args); // Add the `Self` argument. arg_ids.push_back(GetSelfFacet(context, interface_specific_id, generic_id, diff --git a/toolchain/check/testdata/facet/fail_incomplete.carbon b/toolchain/check/testdata/facet/fail_incomplete.carbon index 53495105b0608..c2c5e88130f16 100644 --- a/toolchain/check/testdata/facet/fail_incomplete.carbon +++ b/toolchain/check/testdata/facet/fail_incomplete.carbon @@ -10,99 +10,6 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/fail_incomplete.carbon -// --- fail_incomplete_interface.carbon -library "[[@TEST_NAME]]"; - -interface X; -class C {} - -// Requires X identified. -impl C as X; - -// Requires X complete. -// CHECK:STDERR: fail_incomplete_interface.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `X` [ImplAsIncompleteFacetTypeDefinition] -// CHECK:STDERR: impl C as X {} -// CHECK:STDERR: ^~~~~~~~~~~~~ -// CHECK:STDERR: fail_incomplete_interface.carbon:[[@LINE-10]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] -// CHECK:STDERR: interface X; -// CHECK:STDERR: ^~~~~~~~~~~~ -// CHECK:STDERR: -impl C as X {} - -// --- fail_incomplete_interface_without_forward_decl.carbon -library "[[@TEST_NAME]]"; - -interface X; -class C {} - -// Requires X complete. -// CHECK:STDERR: fail_incomplete_interface_without_forward_decl.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `X` [ImplAsIncompleteFacetTypeDefinition] -// CHECK:STDERR: impl C as X {} -// CHECK:STDERR: ^~~~~~~~~~~~~ -// CHECK:STDERR: fail_incomplete_interface_without_forward_decl.carbon:[[@LINE-7]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] -// CHECK:STDERR: interface X; -// CHECK:STDERR: ^~~~~~~~~~~~ -// CHECK:STDERR: -impl C as X {} - -// --- fail_unidentified_constraint.carbon -library "[[@TEST_NAME]]"; - -constraint X; -class C {} - -// Requires X identified. -// CHECK:STDERR: fail_unidentified_constraint.carbon:[[@LINE+7]]:1: error: facet type `X` cannot be identified in `impl as` [ImplOfUnidentifiedFacetType] -// CHECK:STDERR: impl C as X; -// CHECK:STDERR: ^~~~~~~~~~~~ -// CHECK:STDERR: fail_unidentified_constraint.carbon:[[@LINE-7]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] -// CHECK:STDERR: constraint X; -// CHECK:STDERR: ^~~~~~~~~~~~~ -// CHECK:STDERR: -impl C as X; - -// --- nested_require_incomplete_interface.carbon -library "[[@TEST_NAME]]"; - -interface Z; -constraint Y { - require impls Z; -} -interface X { - require impls Y; -} - -class C {} - -// Requires X identified. -impl C as X; - -// Requires X complete. -impl C as X {} - -// --- fail_incomplete_through_constraint.carbon -library "[[@TEST_NAME]]"; - -interface Z; -constraint Y { - extend require impls Z; -} - -class C {} - -// Requires Y identified. -impl C as Y; - -// Requires Y complete. -// CHECK:STDERR: fail_incomplete_through_constraint.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `Y` [ImplAsIncompleteFacetTypeDefinition] -// CHECK:STDERR: impl C as Y {} -// CHECK:STDERR: ^~~~~~~~~~~~~ -// CHECK:STDERR: fail_incomplete_through_constraint.carbon:[[@LINE-14]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] -// CHECK:STDERR: interface Z; -// CHECK:STDERR: ^~~~~~~~~~~~ -// CHECK:STDERR: -impl C as Y {} - // --- fail_impl_lookup_incomplete.carbon library "[[@TEST_NAME]]"; diff --git a/toolchain/check/testdata/generic/extend_type_completion.carbon b/toolchain/check/testdata/generic/extend_type_completion.carbon new file mode 100644 index 0000000000000..360657d3bdf5f --- /dev/null +++ b/toolchain/check/testdata/generic/extend_type_completion.carbon @@ -0,0 +1,139 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/generic/extend_type_completion.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/generic/extend_type_completion.carbon + +// --- class_impl_doesnt_need_complete_interface.carbon +library "[[@TEST_NAME]]"; + +interface K(T:! type) {} + +class C(N:! i32) { + impl as K(array(i32, N)) {} +} + +// C does not extend K so the type of K is not completed. No error. +var v: C(-1); + +// --- fail_class_extend_impl_does_need_complete_interface.carbon +library "[[@TEST_NAME]]"; + +interface K(T:! type) {} + +class C(N:! i32) { + // CHECK:STDERR: fail_class_extend_impl_does_need_complete_interface.carbon:[[@LINE+3]]:18: error: array bound of -1 is negative [ArrayBoundNegative] + // CHECK:STDERR: extend impl as K(array(i32, N)) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + extend impl as K(array(i32, N)) {} +} + +// C extends K so the type of K is completed, but is invalid. +// CHECK:STDERR: fail_class_extend_impl_does_need_complete_interface.carbon:[[@LINE+4]]:8: note: in `C(-1)` used here [ResolvingSpecificHere] +// CHECK:STDERR: var v: C(-1); +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: +var v: C(-1); + +// --- interface_require_impls_doesnt_need_complete_interface.carbon +library "[[@TEST_NAME]]"; + +interface K(T:! type) {} +interface J(N:! i32) { + require impls K(array(i32, N)); +} + +// J does not extend K so the type of K is not completed. No error. +var v: J(-1); + +// --- fail_interface_extend_require_impls_does_need_complete_interface.carbon +library "[[@TEST_NAME]]"; + +interface K(T:! type) {} +interface J(N:! i32) { + // CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: error: array bound of -1 is negative [ArrayBoundNegative] + // CHECK:STDERR: extend require impls K(array(i32, N)); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + extend require impls K(array(i32, N)); +} +interface I(N:! i32) { + // CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: note: in `J(-1)` used here [ResolvingSpecificHere] + // CHECK:STDERR: extend require impls J(N); + // CHECK:STDERR: ^~~~ + extend require impls J(N); +} + +// I extends J extends K so the type of K is completed, but is invalid. +// +// TODO: The error location should be the type, like in the class case above. We +// need a location for the type in context.bind_name_map() to use as the +// location to Convert(). +// +// CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+4]]:1: note: in `I(-1)` used here [ResolvingSpecificHere] +// CHECK:STDERR: var v: I(-1); +// CHECK:STDERR: ^~~~~~~~~~~~ +// CHECK:STDERR: +var v: I(-1); + +// --- constraint_require_impls_doesnt_need_complete_interface.carbon +library "[[@TEST_NAME]]"; + +interface K(T:! type) {} +constraint J(N:! i32) { + require impls K(array(i32, N)); +} + +// J does not extend K so the type of K is not completed. No error. +var v: J(-1); + +// --- fail_constraint_extend_require_impls_does_need_complete_interface.carbon +library "[[@TEST_NAME]]"; + +interface K(T:! type) {} +constraint J(N:! i32) { + // CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: error: array bound of -1 is negative [ArrayBoundNegative] + // CHECK:STDERR: extend require impls K(array(i32, N)); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + extend require impls K(array(i32, N)); +} +constraint I(N:! i32) { + // CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: note: in `{}` used here [ResolvingSpecificHere] + // CHECK:STDERR: extend require impls J(N); + // CHECK:STDERR: ^~~~ + extend require impls J(N); +} + +// I extends J extends K so the type of K is completed, but is invalid. +// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+4]]:1: note: in `{}` used here [ResolvingSpecificHere] +// CHECK:STDERR: var v: I(-1); +// CHECK:STDERR: ^~~~~~~~~~~~ +// CHECK:STDERR: +var v: I(-1); + +// --- interface_require_impls_doesnt_need_complete_self.carbon +library "[[@TEST_NAME]]"; + +interface K {} +interface J(N:! i32) { + require array(Self, N) impls K; +} + +// J does not extend K so the type of Self impling K is not completed. No error. +var v: J(-1); + +// --- constraint_require_impls_doesnt_need_complete_self.carbon +library "[[@TEST_NAME]]"; + +interface K {} +constraint J(N:! i32) { + require array(Self, N) impls K; +} + +// J does not extend K so the type of Self impling K is not completed. No error. +var v: J(-1); diff --git a/toolchain/check/testdata/impl/fail_undefined_interface.carbon b/toolchain/check/testdata/impl/fail_undefined_interface.carbon deleted file mode 100644 index b93ce2af5d23b..0000000000000 --- a/toolchain/check/testdata/impl/fail_undefined_interface.carbon +++ /dev/null @@ -1,290 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon -// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". -// EXTRA-ARGS: --dump-sem-ir-ranges=if-present -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/fail_undefined_interface.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/fail_undefined_interface.carbon - -// --- fail_empty_struct.carbon - -library "[[@TEST_NAME]]"; - -interface I; -// CHECK:STDERR: fail_empty_struct.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `I` [ImplAsIncompleteFacetTypeDefinition] -// CHECK:STDERR: impl {} as I {} -// CHECK:STDERR: ^~~~~~~~~~~~~~ -// CHECK:STDERR: fail_empty_struct.carbon:[[@LINE-4]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] -// CHECK:STDERR: interface I; -// CHECK:STDERR: ^~~~~~~~~~~~ -// CHECK:STDERR: -impl {} as I {} - -// --- fail_class.carbon - -library "[[@TEST_NAME]]"; - -interface J; -class C {} -// CHECK:STDERR: fail_class.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `J` [ImplAsIncompleteFacetTypeDefinition] -// CHECK:STDERR: impl C as J {} -// CHECK:STDERR: ^~~~~~~~~~~~~ -// CHECK:STDERR: fail_class.carbon:[[@LINE-5]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] -// CHECK:STDERR: interface J; -// CHECK:STDERR: ^~~~~~~~~~~~ -// CHECK:STDERR: -impl C as J {} - -// --- fail_incomplete_where.carbon -library "[[@TEST_NAME]]"; - -class C {} - -interface I {} -interface Incomplete; - -// CHECK:STDERR: fail_incomplete_where.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `I where .Self impls Incomplete` [ImplAsIncompleteFacetTypeDefinition] -// CHECK:STDERR: impl C as I where .Self impls Incomplete {} -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// CHECK:STDERR: fail_incomplete_where.carbon:[[@LINE-5]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] -// CHECK:STDERR: interface Incomplete; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ -// CHECK:STDERR: -impl C as I where .Self impls Incomplete {} - -// --- fail_declaration_incomplete_where_rewrite.carbon -library "[[@TEST_NAME]]"; - -class C {} - -interface J { let T:! type; } -interface Incomplete; - -// CHECK:STDERR: fail_declaration_incomplete_where_rewrite.carbon:[[@LINE+7]]:1: error: declaration of impl as incomplete facet type `J where .Self impls Incomplete and .(J.T) = ()` with rewrites [ImplAsIncompleteFacetTypeRewrites] -// CHECK:STDERR: impl C as J where .Self impls Incomplete and .T = (); -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// CHECK:STDERR: fail_declaration_incomplete_where_rewrite.carbon:[[@LINE-5]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] -// CHECK:STDERR: interface Incomplete; -// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ -// CHECK:STDERR: -impl C as J where .Self impls Incomplete and .T = (); - -// CHECK:STDOUT: --- fail_empty_struct.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: impl_decl @empty_struct_type.as.I.impl [concrete] {} { -// CHECK:STDOUT: %.loc12_7.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %.loc12_7.2: type = converted %.loc12_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I; -// CHECK:STDOUT: -// CHECK:STDOUT: impl @empty_struct_type.as.I.impl: %.loc12_7.2 as %I.ref { -// CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_class.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .J = %J.decl -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} { -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @J; -// CHECK:STDOUT: -// CHECK:STDOUT: impl @C.as.J.impl: %C.ref as %J.ref { -// CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_incomplete_where.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete] -// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self] -// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] -// CHECK:STDOUT: %I_where.type: type = facet_type <@I where .Self impls @Incomplete> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: .I = %I.decl -// CHECK:STDOUT: .Incomplete = %Incomplete.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} -// CHECK:STDOUT: %Incomplete.decl: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {} -// CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] -// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] -// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] -// CHECK:STDOUT: %.loc15_19: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] -// CHECK:STDOUT: %.loc15_13: type = where_expr %.Self [concrete = constants.%I_where.type] { -// CHECK:STDOUT: requirement_base_facet_type constants.%I.type -// CHECK:STDOUT: requirement_impls %.loc15_19, %Incomplete.ref -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: -// CHECK:STDOUT: !requires: -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @Incomplete; -// CHECK:STDOUT: -// CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %.loc15_13 { -// CHECK:STDOUT: !members: -// CHECK:STDOUT: witness = -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_declaration_incomplete_where_rewrite.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] -// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] -// CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%T [concrete] -// CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete] -// CHECK:STDOUT: %.Self: %J.type = symbolic_binding .Self [symbolic_self] -// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %J.lookup_impl_witness: = lookup_impl_witness %.Self, @J [symbolic_self] -// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %J.lookup_impl_witness, element0 [symbolic_self] -// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] -// CHECK:STDOUT: %J_where.type: type = facet_type <@J where .Self impls @Incomplete and %impl.elem0 = %empty_tuple.type> [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .C = %C.decl -// CHECK:STDOUT: .J = %J.decl -// CHECK:STDOUT: .Incomplete = %Incomplete.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} -// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} -// CHECK:STDOUT: %Incomplete.decl: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {} -// CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} { -// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] -// CHECK:STDOUT: %.Self: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %.Self.ref.loc15_19: %J.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] -// CHECK:STDOUT: %.Self.as_type.loc15_19: type = facet_access_type %.Self.ref.loc15_19 [symbolic_self = constants.%.Self.binding.as_type] -// CHECK:STDOUT: %.loc15_19: type = converted %.Self.ref.loc15_19, %.Self.as_type.loc15_19 [symbolic_self = constants.%.Self.binding.as_type] -// CHECK:STDOUT: %.Self.ref.loc15_46: %J.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] -// CHECK:STDOUT: %T.ref: %J.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] -// CHECK:STDOUT: %.Self.as_type.loc15_46: type = facet_access_type %.Self.ref.loc15_46 [symbolic_self = constants.%.Self.binding.as_type] -// CHECK:STDOUT: %.loc15_46: type = converted %.Self.ref.loc15_46, %.Self.as_type.loc15_46 [symbolic_self = constants.%.Self.binding.as_type] -// CHECK:STDOUT: %impl.elem0: type = impl_witness_access constants.%J.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0] -// CHECK:STDOUT: %.loc15_52.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] -// CHECK:STDOUT: %.loc15_52.2: type = converted %.loc15_52.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] -// CHECK:STDOUT: %.loc15_13: type = where_expr %.Self [concrete = constants.%J_where.type] { -// CHECK:STDOUT: requirement_base_facet_type constants.%J.type -// CHECK:STDOUT: requirement_impls %.loc15_19, %Incomplete.ref -// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc15_52.2 -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @J { -// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] { -// CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%T [concrete = constants.%assoc0] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .T = @T.%assoc0 -// CHECK:STDOUT: witness = (%T) -// CHECK:STDOUT: -// CHECK:STDOUT: !requires: -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @Incomplete; -// CHECK:STDOUT: -// CHECK:STDOUT: generic assoc_const @T(@J.%Self: %J.type) { -// CHECK:STDOUT: assoc_const T:! type; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: impl @C.as.J.impl: %C.ref as %.loc15_13; -// CHECK:STDOUT: -// CHECK:STDOUT: class @C { -// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] -// CHECK:STDOUT: complete_type_witness = %complete_type -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @T(constants.%Self) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @T(constants.%.Self) {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/impl_as_named_constraint.carbon b/toolchain/check/testdata/impl/impl_as_named_constraint.carbon index ff78010220baa..fd725dd9b42f6 100644 --- a/toolchain/check/testdata/impl/impl_as_named_constraint.carbon +++ b/toolchain/check/testdata/impl/impl_as_named_constraint.carbon @@ -24,8 +24,8 @@ impl () as A {} // --- fail_too_many_interfaces_in_constraint.carbon library "[[@TEST_NAME]]"; -interface A1; -interface A2; +interface A1 {} +interface A2 {} constraint B { extend require impls A1; extend require impls A2; @@ -40,17 +40,11 @@ impl () as B {} // --- one_extend_impls_interface_in_constraint.carbon library "[[@TEST_NAME]]"; -interface A; +interface A {} constraint B { extend require impls A; } -// Requries B identified. -impl () as B; - -interface A {} - -// Requries B complete. impl () as B {} // --- fail_one_impls_interface_in_constraint.carbon diff --git a/toolchain/check/testdata/impl/import_generic.carbon b/toolchain/check/testdata/impl/import_generic.carbon index 41faf2bc9654b..101e48fb09014 100644 --- a/toolchain/check/testdata/impl/import_generic.carbon +++ b/toolchain/check/testdata/impl/import_generic.carbon @@ -12,6 +12,32 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/import_generic.carbon +// --- basic_import_generic_interface.carbon +library "[[@TEST_NAME]]"; + +interface I(T:! type) {} +interface J(T:! type) { + extend require impls I(T); +} + +// --- basic_import_generic_interface.impl.carbon +impl library "[[@TEST_NAME]]"; + +impl {} as J({}) {} + +// --- basic_import_generic_constraint.carbon +library "[[@TEST_NAME]]"; + +interface I(T:! type) {} +constraint J(T:! type) { + extend require impls I(T); +} + +// --- basic_import_generic_constraint.impl.carbon +impl library "[[@TEST_NAME]]"; + +impl {} as J({}) {} + // --- import_generic.carbon library "[[@TEST_NAME]]"; @@ -157,6 +183,520 @@ impl forall [T:! type] D as N(T) {} // CHECK:STDERR: impl forall [T:! type] D as N(T*) {} +// CHECK:STDOUT: --- basic_import_generic_interface.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %I.type.dac: type = generic_interface_type @I [concrete] +// CHECK:STDOUT: %I.generic: %I.type.dac = struct_value () [concrete] +// CHECK:STDOUT: %I.type.070: type = facet_type <@I, @I(%T)> [symbolic] +// CHECK:STDOUT: %Self.269: %I.type.070 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %J.type.2b8: type = generic_interface_type @J [concrete] +// CHECK:STDOUT: %J.generic: %J.type.2b8 = struct_value () [concrete] +// CHECK:STDOUT: %J.type.8ec: type = facet_type <@J, @J(%T)> [symbolic] +// CHECK:STDOUT: %Self.f68: %J.type.8ec = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.f68 [symbolic] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type.070 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .J = %J.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: %I.type.dac = interface_decl @I [concrete = constants.%I.generic] { +// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %T.loc3_13.2: type = symbolic_binding T, 0 [symbolic = %T.loc3_13.1 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %J.decl: %J.type.2b8 = interface_decl @J [concrete = constants.%J.generic] { +// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %T.loc4_13.2: type = symbolic_binding T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I(%T.loc3_13.2: type) { +// CHECK:STDOUT: %T.loc3_13.1: type = symbolic_binding T, 0 [symbolic = %T.loc3_13.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T.loc3_13.1)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %Self.loc3_23.2: @I.%I.type (%I.type.070) = symbolic_binding Self, 1 [symbolic = %Self.loc3_23.2 (constants.%Self.269)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.loc3_23.1: @I.%I.type (%I.type.070) = symbolic_binding Self, 1 [symbolic = %Self.loc3_23.2 (constants.%Self.269)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.loc3_23.1 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @J(%T.loc4_13.2: type) { +// CHECK:STDOUT: %T.loc4_13.1: type = symbolic_binding T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T.loc4_13.1)> [symbolic = %J.type (constants.%J.type.8ec)] +// CHECK:STDOUT: %Self.loc4_23.2: @J.%J.type (%J.type.8ec) = symbolic_binding Self, 1 [symbolic = %Self.loc4_23.2 (constants.%Self.f68)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T.loc4_13.1)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.loc4_23.1: @J.%J.type (%J.type.8ec) = symbolic_binding Self, 1 [symbolic = %Self.loc4_23.2 (constants.%Self.f68)] +// CHECK:STDOUT: %J.require0.decl = require_decl @J.require0 [concrete] { +// CHECK:STDOUT: require %Self.as_type impls <@I, @I(constants.%T)> +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Self.as_type: type = facet_access_type @J.%Self.loc4_23.1 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %T.ref: type = name_ref T, @J.%T.loc4_13.2 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %I.type.loc5_27.1: type = facet_type <@I, @I(constants.%T)> [symbolic = %I.type.loc5_27.2 (constants.%I.type.070)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.loc4_23.1 +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .T = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: @J.require0 { +// CHECK:STDOUT: require @J.require0.%Self.as_type impls <@I, @I(constants.%T)> +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic require @J.require0(@J.%T.loc4_13.2: type, @J.%Self.loc4_23.1: @J.%J.type (%J.type.8ec)) { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.8ec)] +// CHECK:STDOUT: %Self: @J.require0.%J.type (%J.type.8ec) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.f68)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %I.type.loc5_27.2: type = facet_type <@I, @I(%T)> [symbolic = %I.type.loc5_27.2 (constants.%I.type.070)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%T) { +// CHECK:STDOUT: %T.loc3_13.1 => constants.%T +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.070 +// CHECK:STDOUT: %Self.loc3_23.2 => constants.%Self.269 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J(constants.%T) { +// CHECK:STDOUT: %T.loc4_13.1 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J.require0(constants.%T, constants.%Self.f68) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %J.type => constants.%J.type.8ec +// CHECK:STDOUT: %Self => constants.%Self.f68 +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %I.type.loc5_27.2 => constants.%I.type.070 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- basic_import_generic_interface.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %J.type.2b8: type = generic_interface_type @J [concrete] +// CHECK:STDOUT: %J.generic: %J.type.2b8 = struct_value () [concrete] +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %J.type.8ec: type = facet_type <@J, @J(%T)> [symbolic] +// CHECK:STDOUT: %Self.f68: %J.type.8ec = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %I.type.070: type = facet_type <@I, @I(%T)> [symbolic] +// CHECK:STDOUT: %Self.269: %I.type.070 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.f68 [symbolic] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type.070 [symbolic] +// CHECK:STDOUT: %J.type.457: type = facet_type <@J, @J(%empty_struct_type)> [concrete] +// CHECK:STDOUT: %Self.07b: %J.type.457 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %I.type.399: type = facet_type <@I, @I(%empty_struct_type)> [concrete] +// CHECK:STDOUT: %Self.32d: %I.type.399 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %complete_type: = complete_type_witness %I.type.399 [concrete] +// CHECK:STDOUT: %J.impl_witness: = impl_witness file.%J.impl_witness_table [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.I = import_ref Main//basic_import_generic_interface, I, unloaded +// CHECK:STDOUT: %Main.J: %J.type.2b8 = import_ref Main//basic_import_generic_interface, J, loaded [concrete = constants.%J.generic] +// CHECK:STDOUT: %Main.import_ref.769 = import_ref Main//basic_import_generic_interface, loc3_23, unloaded +// CHECK:STDOUT: %Main.import_ref.efcd44.1: type = import_ref Main//basic_import_generic_interface, loc3_13, loaded [symbolic = @I.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.ce5: type = import_ref Main//basic_import_generic_interface, loc5_18, loaded [symbolic = constants.%Self.binding.as_type] +// CHECK:STDOUT: %Main.import_ref.efcd44.2: type = import_ref Main//basic_import_generic_interface, loc4_13, loaded [symbolic = @J.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.cc4: @J.%J.type (%J.type.8ec) = import_ref Main//basic_import_generic_interface, loc4_23, loaded [symbolic = @J.%Self (constants.%Self.f68)] +// CHECK:STDOUT: %Main.import_ref.b3b = import_ref Main//basic_import_generic_interface, loc4_23, unloaded +// CHECK:STDOUT: %Main.import_ref.efcd44.3: type = import_ref Main//basic_import_generic_interface, loc4_13, loaded [symbolic = @J.%T (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = imports.%Main.I +// CHECK:STDOUT: .J = imports.%Main.J +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc1_46.1 = import +// CHECK:STDOUT: %default.import.loc1_46.2 = import +// CHECK:STDOUT: impl_decl @empty_struct_type.as.J.impl [concrete] {} { +// CHECK:STDOUT: %.loc3_7.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc3_7.2: type = converted %.loc3_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %J.ref: %J.type.2b8 = name_ref J, imports.%Main.J [concrete = constants.%J.generic] +// CHECK:STDOUT: %.loc3_15: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc3_16: type = converted %.loc3_15, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(constants.%empty_struct_type)> [concrete = constants.%J.type.457] +// CHECK:STDOUT: } +// CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (), @empty_struct_type.as.J.impl [concrete] +// CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @J(imports.%Main.import_ref.efcd44.3: type) [from "basic_import_generic_interface.carbon"] { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.8ec)] +// CHECK:STDOUT: %Self: @J.%J.type (%J.type.8ec) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.f68)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.b3b +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: @J.require0 { +// CHECK:STDOUT: require imports.%Main.import_ref.ce5 impls <@I, @I(constants.%T)> +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I(imports.%Main.import_ref.efcd44.1: type) [from "basic_import_generic_interface.carbon"] { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %Self: @I.%I.type (%I.type.070) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.269)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.769 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic require @J.require0(imports.%Main.import_ref.efcd44.2: type, imports.%Main.import_ref.cc4: @J.%J.type (%J.type.8ec)) [from "basic_import_generic_interface.carbon"] { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.8ec)] +// CHECK:STDOUT: %Self: @J.require0.%J.type (%J.type.8ec) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.f68)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @empty_struct_type.as.J.impl: %.loc3_7.2 as %J.type { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%J.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.070 +// CHECK:STDOUT: %Self => constants.%Self.269 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J.require0(constants.%T, constants.%Self.f68) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %J.type => constants.%J.type.8ec +// CHECK:STDOUT: %Self => constants.%Self.f68 +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %I.type => constants.%I.type.070 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J(constants.%empty_struct_type) { +// CHECK:STDOUT: %T => constants.%empty_struct_type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %J.type => constants.%J.type.457 +// CHECK:STDOUT: %Self => constants.%Self.07b +// CHECK:STDOUT: %I.type => constants.%I.type.399 +// CHECK:STDOUT: %require_complete => constants.%complete_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%empty_struct_type) { +// CHECK:STDOUT: %T => constants.%empty_struct_type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.399 +// CHECK:STDOUT: %Self => constants.%Self.32d +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- basic_import_generic_constraint.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %I.type.dac: type = generic_interface_type @I [concrete] +// CHECK:STDOUT: %I.generic: %I.type.dac = struct_value () [concrete] +// CHECK:STDOUT: %I.type.070: type = facet_type <@I, @I(%T)> [symbolic] +// CHECK:STDOUT: %Self.269: %I.type.070 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %J.type.267: type = generic_named_constaint_type @J [concrete] +// CHECK:STDOUT: %empty_struct: %J.type.267 = struct_value () [concrete] +// CHECK:STDOUT: %J.type.b8d: type = facet_type <@J, @J(%T)> [symbolic] +// CHECK:STDOUT: %Self.aa1: %J.type.b8d = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.aa1 [symbolic] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type.070 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .J = %J.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: %I.type.dac = interface_decl @I [concrete = constants.%I.generic] { +// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %T.loc3_13.2: type = symbolic_binding T, 0 [symbolic = %T.loc3_13.1 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %J.decl: %J.type.267 = constraint_decl @J [concrete = constants.%empty_struct] { +// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %T.loc4_14.2: type = symbolic_binding T, 0 [symbolic = %T.loc4_14.1 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I(%T.loc3_13.2: type) { +// CHECK:STDOUT: %T.loc3_13.1: type = symbolic_binding T, 0 [symbolic = %T.loc3_13.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T.loc3_13.1)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %Self.loc3_23.2: @I.%I.type (%I.type.070) = symbolic_binding Self, 1 [symbolic = %Self.loc3_23.2 (constants.%Self.269)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.loc3_23.1: @I.%I.type (%I.type.070) = symbolic_binding Self, 1 [symbolic = %Self.loc3_23.2 (constants.%Self.269)] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.loc3_23.1 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic constraint @J(%T.loc4_14.2: type) { +// CHECK:STDOUT: %T.loc4_14.1: type = symbolic_binding T, 0 [symbolic = %T.loc4_14.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T.loc4_14.1)> [symbolic = %J.type (constants.%J.type.b8d)] +// CHECK:STDOUT: %Self.loc4_24.2: @J.%J.type (%J.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self.loc4_24.2 (constants.%Self.aa1)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T.loc4_14.1)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: constraint { +// CHECK:STDOUT: %Self.loc4_24.1: @J.%J.type (%J.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self.loc4_24.2 (constants.%Self.aa1)] +// CHECK:STDOUT: %J.require0.decl = require_decl @J.require0 [concrete] { +// CHECK:STDOUT: require %Self.as_type impls <@I, @I(constants.%T)> +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Self.as_type: type = facet_access_type @J.%Self.loc4_24.1 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %T.ref: type = name_ref T, @J.%T.loc4_14.2 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %I.type.loc5_27.1: type = facet_type <@I, @I(constants.%T)> [symbolic = %I.type.loc5_27.2 (constants.%I.type.070)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.loc4_24.1 +// CHECK:STDOUT: .I = +// CHECK:STDOUT: .T = +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: @J.require0 { +// CHECK:STDOUT: require @J.require0.%Self.as_type impls <@I, @I(constants.%T)> +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic require @J.require0(@J.%T.loc4_14.2: type, @J.%Self.loc4_24.1: @J.%J.type (%J.type.b8d)) { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.b8d)] +// CHECK:STDOUT: %Self: @J.require0.%J.type (%J.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %I.type.loc5_27.2: type = facet_type <@I, @I(%T)> [symbolic = %I.type.loc5_27.2 (constants.%I.type.070)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%T) { +// CHECK:STDOUT: %T.loc3_13.1 => constants.%T +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.070 +// CHECK:STDOUT: %Self.loc3_23.2 => constants.%Self.269 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J(constants.%T) { +// CHECK:STDOUT: %T.loc4_14.1 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J.require0(constants.%T, constants.%Self.aa1) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %J.type => constants.%J.type.b8d +// CHECK:STDOUT: %Self => constants.%Self.aa1 +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %I.type.loc5_27.2 => constants.%I.type.070 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- basic_import_generic_constraint.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %empty_struct.a40: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %J.type.267: type = generic_named_constaint_type @J [concrete] +// CHECK:STDOUT: %empty_struct.b6f: %J.type.267 = struct_value () [concrete] +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %J.type.b8d23b.1: type = facet_type <@J, @J(%T)> [symbolic] +// CHECK:STDOUT: %Self.aa1546.1: %J.type.b8d23b.1 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %I.type.070: type = facet_type <@I, @I(%T)> [symbolic] +// CHECK:STDOUT: %Self.269: %I.type.070 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.aa1546.1 [symbolic] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type.070 [symbolic] +// CHECK:STDOUT: %J.type.b8d23b.2: type = facet_type <@J, @J(%empty_struct_type)> [concrete] +// CHECK:STDOUT: %Self.aa1546.2: %J.type.b8d23b.2 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %I.type.399: type = facet_type <@I, @I(%empty_struct_type)> [concrete] +// CHECK:STDOUT: %Self.32d: %I.type.399 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %complete_type: = complete_type_witness %I.type.399 [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.I = import_ref Main//basic_import_generic_constraint, I, unloaded +// CHECK:STDOUT: %Main.J: %J.type.267 = import_ref Main//basic_import_generic_constraint, J, loaded [concrete = constants.%empty_struct.b6f] +// CHECK:STDOUT: %Main.import_ref.769 = import_ref Main//basic_import_generic_constraint, loc3_23, unloaded +// CHECK:STDOUT: %Main.import_ref.efcd44.1: type = import_ref Main//basic_import_generic_constraint, loc3_13, loaded [symbolic = @I.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.f92: type = import_ref Main//basic_import_generic_constraint, loc5_18, loaded [symbolic = constants.%Self.binding.as_type] +// CHECK:STDOUT: %Main.import_ref.efcd44.2: type = import_ref Main//basic_import_generic_constraint, loc4_14, loaded [symbolic = @J.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.d4d: @J.%J.type (%J.type.b8d23b.1) = import_ref Main//basic_import_generic_constraint, loc4_24, loaded [symbolic = @J.%Self (constants.%Self.aa1546.1)] +// CHECK:STDOUT: %Main.import_ref.388 = import_ref Main//basic_import_generic_constraint, loc4_24, unloaded +// CHECK:STDOUT: %Main.import_ref.efcd44.3: type = import_ref Main//basic_import_generic_constraint, loc4_14, loaded [symbolic = @J.%T (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = imports.%Main.I +// CHECK:STDOUT: .J = imports.%Main.J +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc1_47.1 = import +// CHECK:STDOUT: %default.import.loc1_47.2 = import +// CHECK:STDOUT: impl_decl @empty_struct_type.as.I.impl [concrete] {} { +// CHECK:STDOUT: %.loc3_7.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct.a40] +// CHECK:STDOUT: %.loc3_7.2: type = converted %.loc3_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %J.ref: %J.type.267 = name_ref J, imports.%Main.J [concrete = constants.%empty_struct.b6f] +// CHECK:STDOUT: %.loc3_15: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct.a40] +// CHECK:STDOUT: %.loc3_16: type = converted %.loc3_15, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(constants.%empty_struct_type)> [concrete = constants.%J.type.b8d23b.2] +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @empty_struct_type.as.I.impl [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic interface @I(imports.%Main.import_ref.efcd44.1: type) [from "basic_import_generic_constraint.carbon"] { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %Self: @I.%I.type (%I.type.070) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.269)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.769 +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic constraint @J(imports.%Main.import_ref.efcd44.3: type) [from "basic_import_generic_constraint.carbon"] { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.b8d23b.1)] +// CHECK:STDOUT: %Self: @J.%J.type (%J.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1546.1)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: +// CHECK:STDOUT: constraint { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.388 +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: @J.require0 { +// CHECK:STDOUT: require imports.%Main.import_ref.f92 impls <@I, @I(constants.%T)> +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic require @J.require0(imports.%Main.import_ref.efcd44.2: type, imports.%Main.import_ref.d4d: @J.%J.type (%J.type.b8d23b.1)) [from "basic_import_generic_constraint.carbon"] { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.b8d23b.1)] +// CHECK:STDOUT: %Self: @J.require0.%J.type (%J.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1546.1)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @empty_struct_type.as.I.impl: %.loc3_7.2 as %J.type { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%I.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.070 +// CHECK:STDOUT: %Self => constants.%Self.269 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J.require0(constants.%T, constants.%Self.aa1546.1) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %J.type => constants.%J.type.b8d23b.1 +// CHECK:STDOUT: %Self => constants.%Self.aa1546.1 +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %I.type => constants.%I.type.070 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @J(constants.%empty_struct_type) { +// CHECK:STDOUT: %T => constants.%empty_struct_type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %J.type => constants.%J.type.b8d23b.2 +// CHECK:STDOUT: %Self => constants.%Self.aa1546.2 +// CHECK:STDOUT: %I.type => constants.%I.type.399 +// CHECK:STDOUT: %require_complete => constants.%complete_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%empty_struct_type) { +// CHECK:STDOUT: %T => constants.%empty_struct_type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.type => constants.%I.type.399 +// CHECK:STDOUT: %Self => constants.%Self.32d +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- import_generic.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -265,6 +805,8 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T.loc14_14.1)> [symbolic = %N.type (constants.%N.type.b8d)] // CHECK:STDOUT: %Self.loc14_24.2: @N.%N.type (%N.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self.loc14_24.2 (constants.%Self.aa1)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T.loc14_14.1)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete.c94)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { // CHECK:STDOUT: %Self.loc14_24.1: @N.%N.type (%N.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self.loc14_24.2 (constants.%Self.aa1)] @@ -531,6 +1073,8 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.b8d23b.1)] // CHECK:STDOUT: %Self: @N.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete.c94)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { // CHECK:STDOUT: !members: @@ -805,6 +1349,8 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T.loc9_14.1)> [symbolic = %N.type (constants.%N.type.b8d)] // CHECK:STDOUT: %Self.loc9_24.2: @N.%N.type (%N.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self.loc9_24.2 (constants.%Self.aa1)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T.loc9_14.1)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { // CHECK:STDOUT: %Self.loc9_24.1: @N.%N.type (%N.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self.loc9_24.2 (constants.%Self.aa1)] @@ -910,10 +1456,13 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %N.type.673: type = generic_named_constaint_type @N [concrete] // CHECK:STDOUT: %empty_struct: %N.type.673 = struct_value () [concrete] // CHECK:STDOUT: %N.type.b8d23b.1: type = facet_type <@N, @N(%T)> [symbolic] -// CHECK:STDOUT: %Self.aa1: %N.type.b8d23b.1 = symbolic_binding Self, 1 [symbolic] -// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.aa1 [symbolic] +// CHECK:STDOUT: %Self.aa1546.1: %N.type.b8d23b.1 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.aa1546.1 [symbolic] // CHECK:STDOUT: %ptr.3f2: type = ptr_type %ptr.4f0 [symbolic] // CHECK:STDOUT: %N.type.b8d23b.2: type = facet_type <@N, @N(%ptr.3f2)> [symbolic] +// CHECK:STDOUT: %Self.aa1546.2: %N.type.b8d23b.2 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %I.type.71a: type = facet_type <@I, @I(%ptr.3f2)> [symbolic] +// CHECK:STDOUT: %require_complete.08c: = require_complete_type %I.type.71a [symbolic] // CHECK:STDOUT: %require_complete.a37: = require_complete_type %N.type.b8d23b.2 [symbolic] // CHECK:STDOUT: %I.impl_witness.524: = impl_witness file.%I.impl_witness_table.loc6, @C.as.I.impl.3f8(%T) [symbolic] // CHECK:STDOUT: } @@ -933,7 +1482,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %Main.import_ref.efcd44.2: type = import_ref Main//import_generic_with_different_specific, loc7_14, loaded [symbolic = @C.as.I.impl.f3e.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.f92: type = import_ref Main//import_generic_with_different_specific, loc10_18, loaded [symbolic = constants.%Self.binding.as_type] // CHECK:STDOUT: %Main.import_ref.efcd44.3: type = import_ref Main//import_generic_with_different_specific, loc9_14, loaded [symbolic = @N.%T (constants.%T)] -// CHECK:STDOUT: %Main.import_ref.d4d: @N.%N.type (%N.type.b8d23b.1) = import_ref Main//import_generic_with_different_specific, loc9_24, loaded [symbolic = @N.%Self (constants.%Self.aa1)] +// CHECK:STDOUT: %Main.import_ref.d4d: @N.%N.type (%N.type.b8d23b.1) = import_ref Main//import_generic_with_different_specific, loc9_24, loaded [symbolic = @N.%Self (constants.%Self.aa1546.1)] // CHECK:STDOUT: %Main.import_ref.388 = import_ref Main//import_generic_with_different_specific, loc9_24, unloaded // CHECK:STDOUT: %Main.import_ref.efcd44.4: type = import_ref Main//import_generic_with_different_specific, loc9_14, loaded [symbolic = @N.%T (constants.%T)] // CHECK:STDOUT: } @@ -996,7 +1545,9 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.b8d23b.1)] -// CHECK:STDOUT: %Self: @N.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1)] +// CHECK:STDOUT: %Self: @N.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1546.1)] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type [symbolic = %require_complete (constants.%require_complete.c94)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { // CHECK:STDOUT: !members: @@ -1012,7 +1563,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: generic require @N.require0(imports.%Main.import_ref.efcd44.3: type, imports.%Main.import_ref.d4d: @N.%N.type (%N.type.b8d23b.1)) [from "import_generic_with_different_specific.carbon"] { // CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.b8d23b.1)] -// CHECK:STDOUT: %Self: @N.require0.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1)] +// CHECK:STDOUT: %Self: @N.require0.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1546.1)] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] // CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.070)] // CHECK:STDOUT: } @@ -1104,16 +1655,22 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @N.require0(constants.%T, constants.%Self.aa1) { +// CHECK:STDOUT: specific @N.require0(constants.%T, constants.%Self.aa1546.1) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %N.type => constants.%N.type.b8d23b.1 -// CHECK:STDOUT: %Self => constants.%Self.aa1 +// CHECK:STDOUT: %Self => constants.%Self.aa1546.1 // CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type // CHECK:STDOUT: %I.type => constants.%I.type.070 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%ptr.3f2) { // CHECK:STDOUT: %T => constants.%ptr.3f2 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %N.type => constants.%N.type.b8d23b.2 +// CHECK:STDOUT: %Self => constants.%Self.aa1546.2 +// CHECK:STDOUT: %I.type => constants.%I.type.71a +// CHECK:STDOUT: %require_complete => constants.%require_complete.08c // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @C.as.I.impl.3f8(constants.%T) { @@ -1125,6 +1682,10 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %I.impl_witness => constants.%I.impl_witness.524 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @I(constants.%ptr.3f2) { +// CHECK:STDOUT: %T => constants.%ptr.3f2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_import_generic_decl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1144,6 +1705,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %N.type.b8d: type = facet_type <@N, @N(%T)> [symbolic] // CHECK:STDOUT: %Self.aa1: %N.type.b8d = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.aa1 [symbolic] +// CHECK:STDOUT: %require_complete: = require_complete_type %J.type.8ec [symbolic] // CHECK:STDOUT: %J.impl_witness.224: = impl_witness file.%J.impl_witness_table.loc15, @D.as.J.impl.b47(%T) [symbolic] // CHECK:STDOUT: %ptr: type = ptr_type %T [symbolic] // CHECK:STDOUT: %J.type.4fa: type = facet_type <@J, @J(%ptr)> [symbolic] @@ -1220,6 +1782,8 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T.loc7_14.1)> [symbolic = %N.type (constants.%N.type.b8d)] // CHECK:STDOUT: %Self.loc7_24.2: @N.%N.type (%N.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self.loc7_24.2 (constants.%Self.aa1)] +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T.loc7_14.1)> [symbolic = %J.type (constants.%J.type.8ec)] +// CHECK:STDOUT: %require_complete: = require_complete_type %J.type [symbolic = %require_complete (constants.%require_complete)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { // CHECK:STDOUT: %Self.loc7_24.1: @N.%N.type (%N.type.b8d) = symbolic_binding Self, 1 [symbolic = %Self.loc7_24.2 (constants.%Self.aa1)] @@ -1279,6 +1843,10 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @J(constants.%T) { // CHECK:STDOUT: %T.loc5_13.1 => constants.%T +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %J.type => constants.%J.type.8ec +// CHECK:STDOUT: %Self.loc5_23.2 => constants.%Self.f68 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%T) { @@ -1331,11 +1899,14 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %N.type.673: type = generic_named_constaint_type @N [concrete] // CHECK:STDOUT: %empty_struct: %N.type.673 = struct_value () [concrete] // CHECK:STDOUT: %N.type.b8d23b.1: type = facet_type <@N, @N(%T)> [symbolic] -// CHECK:STDOUT: %Self.aa1: %N.type.b8d23b.1 = symbolic_binding Self, 1 [symbolic] -// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.aa1 [symbolic] +// CHECK:STDOUT: %Self.aa1546.1: %N.type.b8d23b.1 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.aa1546.1 [symbolic] +// CHECK:STDOUT: %require_complete.387: = require_complete_type %J.type.8ec [symbolic] // CHECK:STDOUT: %require_complete.a37d6c.1: = require_complete_type %N.type.b8d23b.1 [symbolic] // CHECK:STDOUT: %J.impl_witness.b5245e.1: = impl_witness file.%J.impl_witness_table.loc29, @D.as.J.impl.3b0484.1(%T) [symbolic] // CHECK:STDOUT: %N.type.b8d23b.2: type = facet_type <@N, @N(%ptr)> [symbolic] +// CHECK:STDOUT: %Self.aa1546.2: %N.type.b8d23b.2 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %require_complete.d4d: = require_complete_type %J.type.4fa [symbolic] // CHECK:STDOUT: %require_complete.a37d6c.2: = require_complete_type %N.type.b8d23b.2 [symbolic] // CHECK:STDOUT: %J.impl_witness.b5245e.2: = impl_witness file.%J.impl_witness_table.loc39, @D.as.J.impl.3b0484.2(%T) [symbolic] // CHECK:STDOUT: } @@ -1358,7 +1929,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: %Main.import_ref.efcd44.3: type = import_ref Main//import_generic_decl, loc21_14, loaded [symbolic = @D.as.J.impl.265db6.1.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.f92: type = import_ref Main//import_generic_decl, loc8_18, loaded [symbolic = constants.%Self.binding.as_type] // CHECK:STDOUT: %Main.import_ref.efcd44.4: type = import_ref Main//import_generic_decl, loc7_14, loaded [symbolic = @N.%T (constants.%T)] -// CHECK:STDOUT: %Main.import_ref.d4d: @N.%N.type (%N.type.b8d23b.1) = import_ref Main//import_generic_decl, loc7_24, loaded [symbolic = @N.%Self (constants.%Self.aa1)] +// CHECK:STDOUT: %Main.import_ref.d4d: @N.%N.type (%N.type.b8d23b.1) = import_ref Main//import_generic_decl, loc7_24, loaded [symbolic = @N.%Self (constants.%Self.aa1546.1)] // CHECK:STDOUT: %Main.import_ref.388 = import_ref Main//import_generic_decl, loc7_24, unloaded // CHECK:STDOUT: %Main.import_ref.efcd44.5: type = import_ref Main//import_generic_decl, loc7_14, loaded [symbolic = @N.%T (constants.%T)] // CHECK:STDOUT: } @@ -1461,7 +2032,9 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.b8d23b.1)] -// CHECK:STDOUT: %Self: @N.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1)] +// CHECK:STDOUT: %Self: @N.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1546.1)] +// CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.8ec)] +// CHECK:STDOUT: %require_complete: = require_complete_type %J.type [symbolic = %require_complete (constants.%require_complete.387)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { // CHECK:STDOUT: !members: @@ -1477,7 +2050,7 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: generic require @N.require0(imports.%Main.import_ref.efcd44.4: type, imports.%Main.import_ref.d4d: @N.%N.type (%N.type.b8d23b.1)) [from "fail_import_generic_decl.carbon"] { // CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %N.type: type = facet_type <@N, @N(%T)> [symbolic = %N.type (constants.%N.type.b8d23b.1)] -// CHECK:STDOUT: %Self: @N.require0.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1)] +// CHECK:STDOUT: %Self: @N.require0.%N.type (%N.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self.aa1546.1)] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] // CHECK:STDOUT: %J.type: type = facet_type <@J, @J(%T)> [symbolic = %J.type (constants.%J.type.8ec)] // CHECK:STDOUT: } @@ -1624,12 +2197,18 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%T) { // CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %N.type => constants.%N.type.b8d23b.1 +// CHECK:STDOUT: %Self => constants.%Self.aa1546.1 +// CHECK:STDOUT: %J.type => constants.%J.type.8ec +// CHECK:STDOUT: %require_complete => constants.%require_complete.387 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @N.require0(constants.%T, constants.%Self.aa1) { +// CHECK:STDOUT: specific @N.require0(constants.%T, constants.%Self.aa1546.1) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %N.type => constants.%N.type.b8d23b.1 -// CHECK:STDOUT: %Self => constants.%Self.aa1 +// CHECK:STDOUT: %Self => constants.%Self.aa1546.1 // CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type // CHECK:STDOUT: %J.type => constants.%J.type.8ec // CHECK:STDOUT: } @@ -1643,6 +2222,12 @@ impl forall [T:! type] D as N(T*) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @N(constants.%ptr) { // CHECK:STDOUT: %T => constants.%ptr +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %N.type => constants.%N.type.b8d23b.2 +// CHECK:STDOUT: %Self => constants.%Self.aa1546.2 +// CHECK:STDOUT: %J.type => constants.%J.type.4fa +// CHECK:STDOUT: %require_complete => constants.%require_complete.d4d // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @D.as.J.impl.3b0484.2(constants.%T) { diff --git a/toolchain/check/testdata/impl/incomplete.carbon b/toolchain/check/testdata/impl/incomplete.carbon new file mode 100644 index 0000000000000..f26016adc203b --- /dev/null +++ b/toolchain/check/testdata/impl/incomplete.carbon @@ -0,0 +1,862 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon +// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". +// EXTRA-ARGS: --dump-sem-ir-ranges=if-present +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/incomplete.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/incomplete.carbon + +// --- fail_empty_struct.carbon +library "[[@TEST_NAME]]"; + +interface I; + +// Requires I identified. +impl {} as I; + +// CHECK:STDERR: fail_empty_struct.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `I` [ImplAsIncompleteFacetTypeDefinition] +// CHECK:STDERR: impl {} as I {} +// CHECK:STDERR: ^~~~~~~~~~~~~~ +// CHECK:STDERR: fail_empty_struct.carbon:[[@LINE-8]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] +// CHECK:STDERR: interface I; +// CHECK:STDERR: ^~~~~~~~~~~~ +// CHECK:STDERR: +impl {} as I {} + +// --- fail_class.carbon +library "[[@TEST_NAME]]"; + +interface J; +class C {} + +// Requires I identified. +// CHECK:STDERR: fail_class.carbon:[[@LINE+4]]:11: error: name `I` not found [NameNotFound] +// CHECK:STDERR: impl C as I; +// CHECK:STDERR: ^ +// CHECK:STDERR: +impl C as I; + +// CHECK:STDERR: fail_class.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `J` [ImplAsIncompleteFacetTypeDefinition] +// CHECK:STDERR: impl C as J {} +// CHECK:STDERR: ^~~~~~~~~~~~~ +// CHECK:STDERR: fail_class.carbon:[[@LINE-13]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] +// CHECK:STDERR: interface J; +// CHECK:STDERR: ^~~~~~~~~~~~ +// CHECK:STDERR: +impl C as J {} + +// --- fail_class_no_forward_decl.carbon +library "[[@TEST_NAME]]"; + +interface J; +class C {} + +// CHECK:STDERR: fail_class_no_forward_decl.carbon:[[@LINE+7]]:1: error: definition of impl as incomplete facet type `J` [ImplAsIncompleteFacetTypeDefinition] +// CHECK:STDERR: impl C as J {} +// CHECK:STDERR: ^~~~~~~~~~~~~ +// CHECK:STDERR: fail_class_no_forward_decl.carbon:[[@LINE-6]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] +// CHECK:STDERR: interface J; +// CHECK:STDERR: ^~~~~~~~~~~~ +// CHECK:STDERR: +impl C as J {} + +// --- fail_class_with_rewrite.carbon +library "[[@TEST_NAME]]"; + +interface J; +class C {} + +// CHECK:STDERR: fail_class_with_rewrite.carbon:[[@LINE+7]]:19: error: member access into object of incomplete type `J` [IncompleteTypeInMemberAccess] +// CHECK:STDERR: impl C as J where .X = (); +// CHECK:STDERR: ^~ +// CHECK:STDERR: fail_class_with_rewrite.carbon:[[@LINE-6]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] +// CHECK:STDERR: interface J; +// CHECK:STDERR: ^~~~~~~~~~~~ +// CHECK:STDERR: +impl C as J where .X = (); + +// CHECK:STDERR: fail_class_with_rewrite.carbon:[[@LINE+7]]:19: error: member access into object of incomplete type `J` [IncompleteTypeInMemberAccess] +// CHECK:STDERR: impl C as J where .X = () {} +// CHECK:STDERR: ^~ +// CHECK:STDERR: fail_class_with_rewrite.carbon:[[@LINE-15]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] +// CHECK:STDERR: interface J; +// CHECK:STDERR: ^~~~~~~~~~~~ +// CHECK:STDERR: +impl C as J where .X = () {} + +// --- fail_todo_class_with_qualified_rewrite.carbon +library "[[@TEST_NAME]]"; + +interface J; +interface K { let X:! type; } +class C {} + +// TODO: There should be no error here. +// +// CHECK:STDERR: fail_todo_class_with_qualified_rewrite.carbon:[[@LINE+8]]:38: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod] +// CHECK:STDERR: impl C as J where .Self impls K and .(K.X) = (); +// CHECK:STDERR: ^ +// CHECK:STDERR: +// CHECK:STDERR: fail_todo_class_with_qualified_rewrite.carbon:[[@LINE+4]]:38: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] +// CHECK:STDERR: impl C as J where .Self impls K and .(K.X) = (); +// CHECK:STDERR: ^ +// CHECK:STDERR: +impl C as J where .Self impls K and .(K.X) = (); + +// TODO: The failure here should be that J is incomplete, once the rewrite of +// `.(K.X)` works. Since any rewrite in the decl requires us to know the size of +// the witness table which requires all interfaces to be complete. +// +// CHECK:STDERR: fail_todo_class_with_qualified_rewrite.carbon:[[@LINE+4]]:38: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod] +// CHECK:STDERR: impl C as J where .Self impls K and .(K.X) = () {} +// CHECK:STDERR: ^ +// CHECK:STDERR: +impl C as J where .Self impls K and .(K.X) = () {} + +// --- incomplete_where.carbon +library "[[@TEST_NAME]]"; + +class C {} + +interface I {} +interface Incomplete; + +impl C as I where .Self impls Incomplete {} + +// --- declaration_incomplete_where_rewrite.carbon +library "[[@TEST_NAME]]"; + +class C {} + +interface J { let T:! type; } +interface Incomplete; + +impl C as J where .Self impls Incomplete and .T = (); + +impl C as J where .Self impls Incomplete and .T = () {} + +// --- fail_declaration_lookup_into_incomplete.carbon +library "[[@TEST_NAME]]"; + +class C {} + +interface I {} +interface Incomplete; + +impl C as I where .Self impls Incomplete { + // CHECK:STDERR: fail_declaration_lookup_into_incomplete.carbon:[[@LINE+7]]:19: error: member access into incomplete facet type `Incomplete` [QualifiedExprInIncompleteFacetTypeScope] + // CHECK:STDERR: fn F() -> Self.(Incomplete.T); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: fail_declaration_lookup_into_incomplete.carbon:[[@LINE-6]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] + // CHECK:STDERR: interface Incomplete; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + fn F() -> Self.(Incomplete.T); +}; + +// --- fail_unidentified_constraint.carbon +library "[[@TEST_NAME]]"; + +constraint X; +class C {} + +// Requires X identified. +// CHECK:STDERR: fail_unidentified_constraint.carbon:[[@LINE+7]]:1: error: facet type `X` cannot be identified in `impl as` [ImplOfUnidentifiedFacetType] +// CHECK:STDERR: impl C as X; +// CHECK:STDERR: ^~~~~~~~~~~~ +// CHECK:STDERR: fail_unidentified_constraint.carbon:[[@LINE-7]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] +// CHECK:STDERR: constraint X; +// CHECK:STDERR: ^~~~~~~~~~~~~ +// CHECK:STDERR: +impl C as X; + +// --- nested_require_incomplete_interface.carbon +library "[[@TEST_NAME]]"; + +interface Z; +constraint Y { + // Not extend, so only required to be identified. + require impls Z; +} +interface X { + // Not extend, so only required to be identified. + require impls Y; +} + +class C {} +impl C as X {} + +// --- fail_incomplete_constraint.carbon +library "[[@TEST_NAME]]"; + +constraint A; + +interface B { + // CHECK:STDERR: fail_incomplete_constraint.carbon:[[@LINE+7]]:17: error: facet type `A` cannot be identified in `require` declaration [RequireImplsUnidentifiedFacetType] + // CHECK:STDERR: require impls A; + // CHECK:STDERR: ^ + // CHECK:STDERR: fail_incomplete_constraint.carbon:[[@LINE-6]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] + // CHECK:STDERR: constraint A; + // CHECK:STDERR: ^~~~~~~~~~~~~ + // CHECK:STDERR: + require impls A; +} + +// CHECK:STDOUT: --- fail_empty_struct.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: impl_decl @empty_struct_type.as.I.impl [concrete] {} { +// CHECK:STDOUT: %.loc6_7.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc6_7.2: type = converted %.loc6_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %I.ref.loc6: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @empty_struct_type.as.I.impl [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] +// CHECK:STDOUT: impl_decl @empty_struct_type.as.I.impl [concrete] {} { +// CHECK:STDOUT: %.loc15_7.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc15_7.2: type = converted %.loc15_7.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %I.ref.loc15: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @empty_struct_type.as.I.impl: %.loc6_7.2 as %I.ref.loc6 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_class.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .J = %J.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .I = +// CHECK:STDOUT: } +// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @C.as..impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %I.ref: = name_ref I, [concrete = ] +// CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @J; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as..impl: %C.ref as ; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.J.impl: %C.ref as %J.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_class_no_forward_decl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .J = %J.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @J; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.J.impl: %C.ref as %J.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_class_with_rewrite.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %.Self: %J.type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .J = %J.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @C.as..impl [concrete] {} { +// CHECK:STDOUT: %C.ref.loc13: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %J.ref.loc13: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: %.Self.2: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc13: %J.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.loc13_25: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc13_13: type = where_expr %.Self.2 [concrete = ] { +// CHECK:STDOUT: requirement_base_facet_type constants.%J.type +// CHECK:STDOUT: requirement_rewrite , +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as..impl [concrete] {} { +// CHECK:STDOUT: %C.ref.loc22: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %J.ref.loc22: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: %.Self.1: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc22: %J.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.loc22_25: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc22_13: type = where_expr %.Self.1 [concrete = ] { +// CHECK:STDOUT: requirement_base_facet_type constants.%J.type +// CHECK:STDOUT: requirement_rewrite , +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @J; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as..impl: %C.ref.loc13 as %.loc13_13 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_class_with_qualified_rewrite.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %K.type: type = facet_type <@K> [concrete] +// CHECK:STDOUT: %Self: %K.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %K.assoc_type: type = assoc_entity_type @K [concrete] +// CHECK:STDOUT: %assoc0: %K.assoc_type = assoc_entity element0, @K.%X [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @J; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @K { +// CHECK:STDOUT: %Self: %K.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %X: type = assoc_const_decl @X [concrete] { +// CHECK:STDOUT: %assoc0: %K.assoc_type = assoc_entity element0, @K.%X [concrete = constants.%assoc0] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .X = @X.%assoc0 +// CHECK:STDOUT: witness = (%X) +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic assoc_const @X(@K.%Self: %K.type) { +// CHECK:STDOUT: assoc_const X:! type; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @X(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- incomplete_where.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete] +// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] +// CHECK:STDOUT: %I_where.type: type = facet_type <@I where .Self impls @Incomplete> [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .Incomplete = %Incomplete.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %Incomplete.decl: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {} +// CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_19: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_13: type = where_expr %.Self [concrete = constants.%I_where.type] { +// CHECK:STDOUT: requirement_base_facet_type constants.%I.type +// CHECK:STDOUT: requirement_impls %.loc8_19, %Incomplete.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @C.as.I.impl [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Incomplete; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %.loc8_13 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%I.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- declaration_incomplete_where_rewrite.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] +// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] +// CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%T [concrete] +// CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete] +// CHECK:STDOUT: %.Self: %J.type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %J.lookup_impl_witness: = lookup_impl_witness %.Self, @J [symbolic_self] +// CHECK:STDOUT: %impl.elem0: type = impl_witness_access %J.lookup_impl_witness, element0 [symbolic_self] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: %J_where.type: type = facet_type <@J where .Self impls @Incomplete and %impl.elem0 = %empty_tuple.type> [concrete] +// CHECK:STDOUT: %J.impl_witness: = impl_witness file.%J.impl_witness_table [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .J = %J.decl +// CHECK:STDOUT: .Incomplete = %Incomplete.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} +// CHECK:STDOUT: %Incomplete.decl: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {} +// CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} { +// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %J.ref.loc8: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: %.Self.2: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc8_19: %J.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %Incomplete.ref.loc8: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] +// CHECK:STDOUT: %.Self.as_type.loc8_19: type = facet_access_type %.Self.ref.loc8_19 [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_19: type = converted %.Self.ref.loc8_19, %.Self.as_type.loc8_19 [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.Self.ref.loc8_46: %J.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %T.ref.loc8: %J.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type.loc8_46: type = facet_access_type %.Self.ref.loc8_46 [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_46: type = converted %.Self.ref.loc8_46, %.Self.as_type.loc8_46 [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %impl.elem0.loc8: type = impl_witness_access constants.%J.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0] +// CHECK:STDOUT: %.loc8_52.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc8_52.2: type = converted %.loc8_52.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc8_13: type = where_expr %.Self.2 [concrete = constants.%J_where.type] { +// CHECK:STDOUT: requirement_base_facet_type constants.%J.type +// CHECK:STDOUT: requirement_impls %.loc8_19, %Incomplete.ref.loc8 +// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc8, %.loc8_52.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant), @C.as.J.impl [concrete] +// CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness] +// CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} { +// CHECK:STDOUT: %C.ref.loc10: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %J.ref.loc10: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: %.Self.1: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref.loc10_19: %J.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %Incomplete.ref.loc10: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] +// CHECK:STDOUT: %.Self.as_type.loc10_19: type = facet_access_type %.Self.ref.loc10_19 [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc10_19: type = converted %.Self.ref.loc10_19, %.Self.as_type.loc10_19 [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.Self.ref.loc10_46: %J.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %T.ref.loc10: %J.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %.Self.as_type.loc10_46: type = facet_access_type %.Self.ref.loc10_46 [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc10_46: type = converted %.Self.ref.loc10_46, %.Self.as_type.loc10_46 [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %impl.elem0.loc10: type = impl_witness_access constants.%J.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0] +// CHECK:STDOUT: %.loc10_52.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc10_52.2: type = converted %.loc10_52.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc10_13: type = where_expr %.Self.1 [concrete = constants.%J_where.type] { +// CHECK:STDOUT: requirement_base_facet_type constants.%J.type +// CHECK:STDOUT: requirement_impls %.loc10_19, %Incomplete.ref.loc10 +// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc10, %.loc10_52.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @J { +// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] { +// CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%T [concrete = constants.%assoc0] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .T = @T.%assoc0 +// CHECK:STDOUT: witness = (%T) +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Incomplete; +// CHECK:STDOUT: +// CHECK:STDOUT: generic assoc_const @T(@J.%Self: %J.type) { +// CHECK:STDOUT: assoc_const T:! type; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.J.impl: %C.ref.loc8 as %.loc8_13 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%J.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T(constants.%.Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_declaration_lookup_into_incomplete.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete] +// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self [symbolic_self] +// CHECK:STDOUT: %I_where.type: type = facet_type <@I where .Self impls @Incomplete> [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] +// CHECK:STDOUT: %C.as.I.impl.F.type: type = fn_type @C.as.I.impl.F [concrete] +// CHECK:STDOUT: %C.as.I.impl.F: %C.as.I.impl.F.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .Incomplete = %Incomplete.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %Incomplete.decl: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {} +// CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] +// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_19: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type] +// CHECK:STDOUT: %.loc8_13: type = where_expr %.Self [concrete = constants.%I_where.type] { +// CHECK:STDOUT: requirement_base_facet_type constants.%I.type +// CHECK:STDOUT: requirement_impls %.loc8_19, %Incomplete.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @C.as.I.impl [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Incomplete; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %.loc8_13 { +// CHECK:STDOUT: %C.as.I.impl.F.decl: %C.as.I.impl.F.type = fn_decl @C.as.I.impl.F [concrete = constants.%C.as.I.impl.F] { +// CHECK:STDOUT: %return.patt: = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @C.as.I.impl.%C.ref [concrete = constants.%C] +// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type] +// CHECK:STDOUT: %T.ref: = name_ref T, [concrete = ] +// CHECK:STDOUT: %return.param: ref = out_param call_param0 +// CHECK:STDOUT: %return: ref = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Incomplete = +// CHECK:STDOUT: .F = %C.as.I.impl.F.decl +// CHECK:STDOUT: witness = file.%I.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.I.impl.F() -> ; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_unidentified_constraint.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %X.type: type = facet_type <@X> [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .X = %X.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %X.decl: type = constraint_decl @X [concrete = constants.%X.type] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @C.as..impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: constraint @X; +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as..impl: %C.ref as %X.ref; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- nested_require_incomplete_interface.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Z.type: type = facet_type <@Z> [concrete] +// CHECK:STDOUT: %Y.type: type = facet_type <@Y> [concrete] +// CHECK:STDOUT: %Self.861: %Y.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type.1a1: type = symbolic_binding_type Self, 0, %Self.861 [symbolic] +// CHECK:STDOUT: %X.type: type = facet_type <@X> [concrete] +// CHECK:STDOUT: %Self.40f: %X.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type.dcc: type = symbolic_binding_type Self, 0, %Self.40f [symbolic] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %X.impl_witness: = impl_witness file.%X.impl_witness_table [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Z = %Z.decl +// CHECK:STDOUT: .Y = %Y.decl +// CHECK:STDOUT: .X = %X.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Z.decl: type = interface_decl @Z [concrete = constants.%Z.type] {} {} +// CHECK:STDOUT: %Y.decl: type = constraint_decl @Y [concrete = constants.%Y.type] {} {} +// CHECK:STDOUT: %X.decl: type = interface_decl @X [concrete = constants.%X.type] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @C.as.X.impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %X.impl_witness_table = impl_witness_table (), @C.as.X.impl [concrete] +// CHECK:STDOUT: %X.impl_witness: = impl_witness %X.impl_witness_table [concrete = constants.%X.impl_witness] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Z; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @X { +// CHECK:STDOUT: %Self: %X.type = symbolic_binding Self, 0 [symbolic = constants.%Self.40f] +// CHECK:STDOUT: %X.require1.decl = require_decl @X.require1 [concrete] { +// CHECK:STDOUT: require %Self.as_type impls <@Y> +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Self.as_type: type = facet_access_type @X.%Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type.dcc)] +// CHECK:STDOUT: %Y.ref: type = name_ref Y, file.%Y.decl [concrete = constants.%Y.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Y = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: @X.require1 { +// CHECK:STDOUT: require @X.require1.%Self.as_type impls <@Y> +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: constraint @Y { +// CHECK:STDOUT: %Self: %Y.type = symbolic_binding Self, 0 [symbolic = constants.%Self.861] +// CHECK:STDOUT: %Y.require0.decl = require_decl @Y.require0 [concrete] { +// CHECK:STDOUT: require %Self.as_type impls <@Z> +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Self.as_type: type = facet_access_type @Y.%Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type.1a1)] +// CHECK:STDOUT: %Z.ref: type = name_ref Z, file.%Z.decl [concrete = constants.%Z.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Z = +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: @Y.require0 { +// CHECK:STDOUT: require @Y.require0.%Self.as_type impls <@Z> +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic require @Y.require0(@Y.%Self: %Y.type) { +// CHECK:STDOUT: %Self: %Y.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.861)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type.1a1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic require @X.require1(@X.%Self: %X.type) { +// CHECK:STDOUT: %Self: %X.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.40f)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type.dcc)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.X.impl: %C.ref as %X.ref { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = file.%X.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Y.require0(constants.%Self.861) { +// CHECK:STDOUT: %Self => constants.%Self.861 +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type.1a1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @X.require1(constants.%Self.40f) { +// CHECK:STDOUT: %Self => constants.%Self.40f +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type.dcc +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_incomplete_constraint.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete] +// CHECK:STDOUT: %B.type: type = facet_type <@B> [concrete] +// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %A.decl: type = constraint_decl @A [concrete = constants.%A.type] {} {} +// CHECK:STDOUT: %B.decl: type = interface_decl @B [concrete = constants.%B.type] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @B { +// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .A = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: constraint @A; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/use_assoc_const.carbon b/toolchain/check/testdata/impl/use_assoc_entity.carbon similarity index 99% rename from toolchain/check/testdata/impl/use_assoc_const.carbon rename to toolchain/check/testdata/impl/use_assoc_entity.carbon index d89e5a5f630b4..3f115580b3151 100644 --- a/toolchain/check/testdata/impl/use_assoc_const.carbon +++ b/toolchain/check/testdata/impl/use_assoc_entity.carbon @@ -8,9 +8,9 @@ // // AUTOUPDATE // TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/use_assoc_const.carbon +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/use_assoc_entity.carbon // TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/use_assoc_const.carbon +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/use_assoc_entity.carbon // --- associated_type_in_method_signature.carbon library "[[@TEST_NAME]]"; diff --git a/toolchain/check/testdata/interface/incomplete.carbon b/toolchain/check/testdata/interface/incomplete.carbon index 2436d928bf701..138cd83d97c5f 100644 --- a/toolchain/check/testdata/interface/incomplete.carbon +++ b/toolchain/check/testdata/interface/incomplete.carbon @@ -28,45 +28,48 @@ interface I { let T:! C; } -// --- fail_incomplete_constraint.carbon +// --- fail_incomplete_extend_constraint.carbon library "[[@TEST_NAME]]"; constraint A; interface B { - // CHECK:STDERR: fail_incomplete_constraint.carbon:[[@LINE+7]]:17: error: facet type `A` cannot be identified in `require` declaration [RequireImplsUnidentifiedFacetType] - // CHECK:STDERR: require impls A; - // CHECK:STDERR: ^ - // CHECK:STDERR: fail_incomplete_constraint.carbon:[[@LINE-6]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] + // CHECK:STDERR: fail_incomplete_extend_constraint.carbon:[[@LINE+7]]:24: error: facet type `A` cannot be identified in `require` declaration [RequireImplsUnidentifiedFacetType] + // CHECK:STDERR: extend require impls A; + // CHECK:STDERR: ^ + // CHECK:STDERR: fail_incomplete_extend_constraint.carbon:[[@LINE-6]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere] // CHECK:STDERR: constraint A; // CHECK:STDERR: ^~~~~~~~~~~~~ // CHECK:STDERR: - require impls A; + extend require impls A; } -// --- incomplete_interface.carbon +// --- fail_extend_require_enclosing.carbon library "[[@TEST_NAME]]"; -interface A; - -interface B { - require impls A; +interface A { + // CHECK:STDERR: fail_extend_require_enclosing.carbon:[[@LINE+7]]:24: error: `extend require` of incomplete facet type `A` [RequireImplsIncompleteFacetType] + // CHECK:STDERR: extend require impls A; + // CHECK:STDERR: ^ + // CHECK:STDERR: fail_extend_require_enclosing.carbon:[[@LINE-4]]:1: note: interface is currently being defined [InterfaceIncompleteWithinDefinition] + // CHECK:STDERR: interface A { + // CHECK:STDERR: ^~~~~~~~~~~~~ + // CHECK:STDERR: + extend require impls A; } -// --- fail_incomplete_interface_in_where.carbon +// --- fail_extend_require_enclosing_generic.carbon library "[[@TEST_NAME]]"; -interface A; - -interface B { - // CHECK:STDERR: fail_incomplete_interface_in_where.carbon:[[@LINE+7]]:25: error: member access into object of incomplete type `A` [IncompleteTypeInMemberAccess] - // CHECK:STDERR: require impls A where .X = {}; - // CHECK:STDERR: ^~ - // CHECK:STDERR: fail_incomplete_interface_in_where.carbon:[[@LINE-6]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere] - // CHECK:STDERR: interface A; - // CHECK:STDERR: ^~~~~~~~~~~~ +interface A(T:! type) { + // CHECK:STDERR: fail_extend_require_enclosing_generic.carbon:[[@LINE+7]]:24: error: `extend require` of incomplete facet type `A({})` [RequireImplsIncompleteFacetType] + // CHECK:STDERR: extend require impls A({}); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: fail_extend_require_enclosing_generic.carbon:[[@LINE-4]]:1: note: interface is currently being defined [InterfaceIncompleteWithinDefinition] + // CHECK:STDERR: interface A(T:! type) { + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: - require impls A where .X = {}; + extend require impls A({}); } // CHECK:STDOUT: --- fail_incomplete_type.carbon @@ -111,7 +114,7 @@ interface B { // CHECK:STDOUT: // CHECK:STDOUT: specific @T(constants.%Self) {} // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_incomplete_constraint.carbon +// CHECK:STDOUT: --- fail_incomplete_extend_constraint.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete] @@ -141,32 +144,27 @@ interface B { // CHECK:STDOUT: // CHECK:STDOUT: constraint @A; // CHECK:STDOUT: -// CHECK:STDOUT: --- incomplete_interface.carbon +// CHECK:STDOUT: --- fail_extend_require_enclosing.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete] -// CHECK:STDOUT: %B.type: type = facet_type <@B> [concrete] -// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self: %A.type = symbolic_binding Self, 0 [symbolic] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { // CHECK:STDOUT: .A = %A.decl -// CHECK:STDOUT: .B = %B.decl // CHECK:STDOUT: } // CHECK:STDOUT: %A.decl: type = interface_decl @A [concrete = constants.%A.type] {} {} -// CHECK:STDOUT: %B.decl: type = interface_decl @B [concrete = constants.%B.type] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: interface @A; -// CHECK:STDOUT: -// CHECK:STDOUT: interface @B { -// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: %B.require0.decl = require_decl @B.require0 [concrete] { +// CHECK:STDOUT: interface @A { +// CHECK:STDOUT: %Self: %A.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %A.require0.decl = require_decl @A.require0 [concrete] { // CHECK:STDOUT: require %Self.as_type impls <@A> // CHECK:STDOUT: } { -// CHECK:STDOUT: %Self.as_type: type = facet_access_type @B.%Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type @A.%Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -176,48 +174,94 @@ interface B { // CHECK:STDOUT: witness = () // CHECK:STDOUT: // CHECK:STDOUT: !requires: -// CHECK:STDOUT: @B.require0 { -// CHECK:STDOUT: require @B.require0.%Self.as_type impls <@A> -// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic require @B.require0(@B.%Self: %B.type) { -// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: generic require @A.require0(@A.%Self: %A.type) { +// CHECK:STDOUT: %Self: %A.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] // CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @B.require0(constants.%Self) { +// CHECK:STDOUT: specific @A.require0(constants.%Self) { // CHECK:STDOUT: %Self => constants.%Self // CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_incomplete_interface_in_where.carbon +// CHECK:STDOUT: --- fail_extend_require_enclosing_generic.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete] -// CHECK:STDOUT: %B.type: type = facet_type <@B> [concrete] -// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %A.type.495: type = generic_interface_type @A [concrete] +// CHECK:STDOUT: %A.generic: %A.type.495 = struct_value () [concrete] +// CHECK:STDOUT: %A.type.c1c: type = facet_type <@A, @A(%T)> [symbolic] +// CHECK:STDOUT: %Self: %A.type.c1c = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %A.type.23f: type = facet_type <@A, @A(%empty_struct_type)> [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { // CHECK:STDOUT: .A = %A.decl -// CHECK:STDOUT: .B = %B.decl // CHECK:STDOUT: } -// CHECK:STDOUT: %A.decl: type = interface_decl @A [concrete = constants.%A.type] {} {} -// CHECK:STDOUT: %B.decl: type = interface_decl @B [concrete = constants.%B.type] {} {} +// CHECK:STDOUT: %A.decl: %A.type.495 = interface_decl @A [concrete = constants.%A.generic] { +// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %T.loc3_13.2: type = symbolic_binding T, 0 [symbolic = %T.loc3_13.1 (constants.%T)] +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: interface @A; +// CHECK:STDOUT: generic interface @A(%T.loc3_13.2: type) { +// CHECK:STDOUT: %T.loc3_13.1: type = symbolic_binding T, 0 [symbolic = %T.loc3_13.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.type: type = facet_type <@A, @A(%T.loc3_13.1)> [symbolic = %A.type (constants.%A.type.c1c)] +// CHECK:STDOUT: %Self.loc3_23.2: @A.%A.type (%A.type.c1c) = symbolic_binding Self, 1 [symbolic = %Self.loc3_23.2 (constants.%Self)] +// CHECK:STDOUT: +// CHECK:STDOUT: interface { +// CHECK:STDOUT: %Self.loc3_23.1: @A.%A.type (%A.type.c1c) = symbolic_binding Self, 1 [symbolic = %Self.loc3_23.2 (constants.%Self)] +// CHECK:STDOUT: %A.require0.decl = require_decl @A.require0 [concrete] { +// CHECK:STDOUT: require %Self.as_type impls <@A, @A(constants.%empty_struct_type)> +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Self.as_type: type = facet_access_type @A.%Self.loc3_23.1 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %A.ref: %A.type.495 = name_ref A, file.%A.decl [concrete = constants.%A.generic] +// CHECK:STDOUT: %.loc11_27: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc11_28: type = converted %.loc11_27, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %A.type.loc11_28: type = facet_type <@A, @A(constants.%empty_struct_type)> [concrete = constants.%A.type.23f] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self.loc3_23.1 +// CHECK:STDOUT: .A = +// CHECK:STDOUT: witness = () +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: interface @B { -// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: generic require @A.require0(@A.%T.loc3_13.2: type, @A.%Self.loc3_23.1: @A.%A.type (%A.type.c1c)) { +// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %A.type.loc11_18: type = facet_type <@A, @A(%T)> [symbolic = %A.type.loc11_18 (constants.%A.type.c1c)] +// CHECK:STDOUT: %Self: @A.require0.%A.type.loc11_18 (%A.type.c1c) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .A = -// CHECK:STDOUT: witness = () +// CHECK:STDOUT: specific @A(constants.%T) { +// CHECK:STDOUT: %T.loc3_13.1 => constants.%T +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: !requires: +// CHECK:STDOUT: specific @A(constants.%empty_struct_type) { +// CHECK:STDOUT: %T.loc3_13.1 => constants.%empty_struct_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.require0(constants.%T, constants.%Self) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %A.type.loc11_18 => constants.%A.type.c1c +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/named_constraint/empty_generic.carbon b/toolchain/check/testdata/named_constraint/empty_generic.carbon index 82ec701a0a4ff..5d9a00b91be5a 100644 --- a/toolchain/check/testdata/named_constraint/empty_generic.carbon +++ b/toolchain/check/testdata/named_constraint/empty_generic.carbon @@ -36,7 +36,7 @@ fn G(T:! Z, U:! Empty(T), V:! type) { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %empty_struct.4bc: %Empty.type.a8a = struct_value () [concrete] // CHECK:STDOUT: %Empty.type.b8d23b.1: type = facet_type <@Empty, @Empty(%T.d9f)> [symbolic] -// CHECK:STDOUT: %Self.aa1: %Empty.type.b8d23b.1 = symbolic_binding Self, 1 [symbolic] +// CHECK:STDOUT: %Self.aa1546.1: %Empty.type.b8d23b.1 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %U.aa1546.1: %Empty.type.b8d23b.1 = symbolic_binding U, 1 [symbolic] // CHECK:STDOUT: %pattern_type.e25e9f.1: type = pattern_type %Empty.type.b8d23b.1 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] @@ -58,6 +58,7 @@ fn G(T:! Z, U:! Empty(T), V:! type) { // CHECK:STDOUT: %F.specific_fn.55c: = specific_function %F, @F(%T.binding.as_type, %Empty.facet.832) [symbolic] // CHECK:STDOUT: %Empty.facet.146: %Empty.type.b8d23b.2 = facet_value %T.binding.as_type, () [symbolic] // CHECK:STDOUT: %F.specific_fn.d3f: = specific_function %F, @F(%T.binding.as_type, %Empty.facet.146) [symbolic] +// CHECK:STDOUT: %Self.aa1546.2: %Empty.type.b8d23b.2 = symbolic_binding Self, 1 [symbolic] // CHECK:STDOUT: %F.specific_fn.4af: = specific_function %F, @F(%T.binding.as_type, %U.aa1546.2) [symbolic] // CHECK:STDOUT: %Empty.facet.920: %Empty.type.b8d23b.2 = facet_value %V, () [symbolic] // CHECK:STDOUT: %F.specific_fn.905: = specific_function %F, @F(%T.binding.as_type, %Empty.facet.920) [symbolic] @@ -113,10 +114,10 @@ fn G(T:! Z, U:! Empty(T), V:! type) { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Empty.type: type = facet_type <@Empty, @Empty(%T.loc16_18.1)> [symbolic = %Empty.type (constants.%Empty.type.b8d23b.1)] -// CHECK:STDOUT: %Self.loc16_28.2: @Empty.%Empty.type (%Empty.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self.loc16_28.2 (constants.%Self.aa1)] +// CHECK:STDOUT: %Self.loc16_28.2: @Empty.%Empty.type (%Empty.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self.loc16_28.2 (constants.%Self.aa1546.1)] // CHECK:STDOUT: // CHECK:STDOUT: constraint { -// CHECK:STDOUT: %Self.loc16_28.1: @Empty.%Empty.type (%Empty.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self.loc16_28.2 (constants.%Self.aa1)] +// CHECK:STDOUT: %Self.loc16_28.1: @Empty.%Empty.type (%Empty.type.b8d23b.1) = symbolic_binding Self, 1 [symbolic = %Self.loc16_28.2 (constants.%Self.aa1546.1)] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self.loc16_28.1 @@ -221,6 +222,10 @@ fn G(T:! Z, U:! Empty(T), V:! type) { // CHECK:STDOUT: // CHECK:STDOUT: specific @Empty(constants.%T.binding.as_type) { // CHECK:STDOUT: %T.loc16_18.1 => constants.%T.binding.as_type +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Empty.type => constants.%Empty.type.b8d23b.2 +// CHECK:STDOUT: %Self.loc16_28.2 => constants.%Self.aa1546.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @G(constants.%T.3b3, constants.%U.aa1546.2, constants.%V) { diff --git a/toolchain/check/type_completion.cpp b/toolchain/check/type_completion.cpp index 4cf75ce9d63e1..041be17e70286 100644 --- a/toolchain/check/type_completion.cpp +++ b/toolchain/check/type_completion.cpp @@ -14,7 +14,9 @@ #include "toolchain/check/type.h" #include "toolchain/diagnostics/format_providers.h" #include "toolchain/sem_ir/constant.h" +#include "toolchain/sem_ir/generic.h" #include "toolchain/sem_ir/ids.h" +#include "toolchain/sem_ir/specific_interface.h" #include "toolchain/sem_ir/specific_named_constraint.h" #include "toolchain/sem_ir/type_info.h" #include "toolchain/sem_ir/typed_insts.h" @@ -70,16 +72,47 @@ static auto NoteIncompleteNamedConstraint( } } -template - requires SameAsOneOf -static auto ForEachRequireImpls( - Context& context, const T& entity, - llvm::function_refvoid> f) -> void { - for (auto require_impls_id : - context.require_impls_blocks().Get(entity.require_impls_block_id)) { - const auto& require = context.require_impls().Get(require_impls_id); - f(require); +static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id, + const SemIR::FacetType& facet_type, + MakeDiagnosticBuilderFn diagnoser) + -> bool { + const auto& facet_type_info = + context.facet_types().Get(facet_type.facet_type_id); + + for (auto extends : facet_type_info.extend_constraints) { + auto interface_id = extends.interface_id; + const auto& interface = context.interfaces().Get(interface_id); + if (!interface.is_complete()) { + if (diagnoser) { + auto builder = diagnoser(); + NoteIncompleteInterface(context, interface_id, builder); + builder.Emit(); + } + return false; + } + if (interface.generic_id.has_value()) { + ResolveSpecificDefinition(context, loc_id, extends.specific_id); + } } + + for (auto extends : facet_type_info.extend_named_constraints) { + auto named_constraint_id = extends.named_constraint_id; + const auto& constraint = + context.named_constraints().Get(named_constraint_id); + if (!constraint.is_complete()) { + if (diagnoser) { + auto builder = diagnoser(); + NoteIncompleteNamedConstraint(context, named_constraint_id, builder); + builder.Emit(); + } + return false; + } + if (constraint.generic_id.has_value()) { + ResolveSpecificDefinition(context, loc_id, extends.specific_id); + } + } + + return true; } namespace { @@ -396,32 +429,9 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool { break; } case CARBON_KIND(SemIR::FacetType inst): { - auto identified_id = - RequireIdentifiedFacetType(*context_, inst, diagnoser_); - if (!identified_id.has_value()) { + if (!RequireCompleteFacetType(*context_, loc_id_, inst, diagnoser_)) { return false; } - - const auto& identified = - context_->identified_facet_types().Get(identified_id); - - for (auto req_interface : identified.required_interfaces()) { - auto interface_id = req_interface.interface_id; - const auto& interface = context_->interfaces().Get(interface_id); - if (!interface.is_complete()) { - if (diagnoser_) { - auto builder = diagnoser_(); - NoteIncompleteInterface(*context_, interface_id, builder); - builder.Emit(); - } - return false; - } - - if (req_interface.specific_id.has_value()) { - ResolveSpecificDefinition(*context_, loc_id_, - req_interface.specific_id); - } - } break; } @@ -844,23 +854,25 @@ auto RequireIdentifiedFacetType(Context& context, for (auto extend : facet_type_info.extend_named_constraints) { const auto& constraint = context.named_constraints().Get(extend.named_constraint_id); - ForEachRequireImpls( - context, constraint, [&](const SemIR::RequireImpls& require) { - if (facet_type_extends && require.extend_self) { - extend_facet_types.push_back(require.facet_type_id); - } else { - impls_facet_types.push_back(require.facet_type_id); - } - }); + for (auto require_impls_id : context.require_impls_blocks().Get( + constraint.require_impls_block_id)) { + const auto& require = context.require_impls().Get(require_impls_id); + if (facet_type_extends && require.extend_self) { + extend_facet_types.push_back(require.facet_type_id); + } else { + impls_facet_types.push_back(require.facet_type_id); + } + } } for (auto impls : facet_type_info.self_impls_named_constraints) { const auto& constraint = context.named_constraints().Get(impls.named_constraint_id); - ForEachRequireImpls(context, constraint, - [&](const SemIR::RequireImpls& require) { - impls_facet_types.push_back(require.facet_type_id); - }); + for (auto require_impls_id : context.require_impls_blocks().Get( + constraint.require_impls_block_id)) { + const auto& require = context.require_impls().Get(require_impls_id); + impls_facet_types.push_back(require.facet_type_id); + } } } diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 39cace550c306..377d24857c305 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -328,7 +328,6 @@ CARBON_DIAGNOSTIC_KIND(ExtendImplSelfAs) CARBON_DIAGNOSTIC_KIND(ExtendImplSelfAsDefault) CARBON_DIAGNOSTIC_KIND(ImplAccessMemberBeforeSet) CARBON_DIAGNOSTIC_KIND(ImplAsIncompleteFacetTypeDefinition) -CARBON_DIAGNOSTIC_KIND(ImplAsIncompleteFacetTypeRewrites) CARBON_DIAGNOSTIC_KIND(ImplAsNonFacetType) CARBON_DIAGNOSTIC_KIND(ImplAsOutsideClass) CARBON_DIAGNOSTIC_KIND(ImplAssociatedConstantNeedsValue) @@ -364,6 +363,7 @@ CARBON_DIAGNOSTIC_KIND(ImplLookupInUnidentifiedFacetType) CARBON_DIAGNOSTIC_KIND(RequireImplsExtendWithExplicitSelf) CARBON_DIAGNOSTIC_KIND(RequireImplsMissingFacetType) CARBON_DIAGNOSTIC_KIND(RequireImplsMissingSelf) +CARBON_DIAGNOSTIC_KIND(RequireImplsIncompleteFacetType) CARBON_DIAGNOSTIC_KIND(RequireImplsUnidentifiedFacetType) CARBON_DIAGNOSTIC_KIND(RequireInWrongScope) diff --git a/toolchain/sem_ir/require_impls.h b/toolchain/sem_ir/require_impls.h index cb95f491b0883..6b526ce3bbcd2 100644 --- a/toolchain/sem_ir/require_impls.h +++ b/toolchain/sem_ir/require_impls.h @@ -23,6 +23,8 @@ struct RequireImpls : Printable { // Evaluates to the `FacetType` that the self-type must implement. TypeInstId facet_type_inst_id; // The `FacetTypeInfo` derived from the `facet_type_inst_id` instruction. + // TODO: Remove this, we need to use the inst to get a constant value in the + // appropriate specific. FacetTypeId facet_type_id; // If the facet type extends `Self`. When true, the `self_id` will be `Self`. bool extend_self; diff --git a/toolchain/sem_ir/stringify.cpp b/toolchain/sem_ir/stringify.cpp index 119ed5d39bc0f..99490ebdb91e2 100644 --- a/toolchain/sem_ir/stringify.cpp +++ b/toolchain/sem_ir/stringify.cpp @@ -814,6 +814,10 @@ auto StringifySpecific(const File& sem_ir, SpecificId specific_id) sem_ir.interfaces().Get(interface_decl.interface_id), specific_id); break; } + case CARBON_KIND(RequireImplsDecl _): { + step_stack.Push("require"); + break; + } default: { // TODO: Include the specific arguments here. step_stack.PushInstId(generic.decl_id);