From 201e408252c1eec3680e1d4f68e8473b1dc583be Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 21 Nov 2025 17:28:08 -0500 Subject: [PATCH] Type completion of facet types is separate from Identifying (#6385) Identifying a facet type is an operation on a pair of (self type, facet type). It substitutes that self in as the `Self` of any require declarations in order to form the set of (self type, SpecificInterface) pairs that constitute the requirements of the IdentifiedFacetType. Currently we don't pass around any self type, and assume all require declarations are written against `Self` but this will change in the future. By contrast, type completion is done in the abstract and does not form specifics for the require declarations. The purpose of type completion is to enumerate the scopes where name lookup can occur and ensure they are completed. With this change, type completion is: - No longer built on top of identification for facet types. - Recursively ensures all `extend` scopes are complete since name lookup can find symbols in them. We add some test cases that demonstrate consistency between a resolving the specific of a generic class, and a generic interface/constraint, both used in a type position. In all cases, an invalid specific is not materialized for the type completion when the specific's arguments are used in a non-extend context. But they specific is materialized and checked for type completion when in an extend context (extend impl or extend require). Type completion itself does not need to recurse into named constraints or interfaces as the `extend require` declarations require the type to be complete immediately, just as for `extend impl` in a class. We had a test (`fail_incomplete_where.carbon`) with `impl as J where .Self impls K` and `J` is incomplete, which used to be diagnosed but no longer is, because we don't require non-extend interfaces to be complete in type completion, nor in identification. The test was trying to test the presence of rewrite constraints though, which it didn't even use. So we remove the diagnostic that we can't hit anymore and replaced it with a TODO, and add a test that should reach that TODO once qualified rewrite constraints work. --- toolchain/check/eval.cpp | 8 + toolchain/check/facet_type.cpp | 26 +- toolchain/check/handle_require.cpp | 37 +- toolchain/check/interface.cpp | 2 +- .../testdata/facet/fail_incomplete.carbon | 93 -- .../generic/extend_type_completion.carbon | 139 +++ .../impl/fail_undefined_interface.carbon | 290 ------ .../impl/impl_as_named_constraint.carbon | 12 +- .../check/testdata/impl/import_generic.carbon | 613 ++++++++++++- .../check/testdata/impl/incomplete.carbon | 862 ++++++++++++++++++ ...c_const.carbon => use_assoc_entity.carbon} | 4 +- .../testdata/interface/incomplete.carbon | 162 ++-- .../named_constraint/empty_generic.carbon | 11 +- toolchain/check/type_completion.cpp | 102 ++- toolchain/diagnostics/diagnostic_kind.def | 2 +- toolchain/sem_ir/require_impls.h | 2 + toolchain/sem_ir/stringify.cpp | 4 + 17 files changed, 1831 insertions(+), 538 deletions(-) create mode 100644 toolchain/check/testdata/generic/extend_type_completion.carbon delete mode 100644 toolchain/check/testdata/impl/fail_undefined_interface.carbon create mode 100644 toolchain/check/testdata/impl/incomplete.carbon rename toolchain/check/testdata/impl/{use_assoc_const.carbon => use_assoc_entity.carbon} (99%) diff --git a/toolchain/check/eval.cpp b/toolchain/check/eval.cpp index 1a8bfe02a326..5e08925158f3 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 73dd7ebc3926..d68df95e1f5b 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 20ab48063ba9..14c3a5c7378a 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 779e6a15e23f..760db856b473 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 53495105b060..c2c5e88130f1 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 000000000000..360657d3bdf5 --- /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 b93ce2af5d23..000000000000 --- 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 ff78010220ba..fd725dd9b42f 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 41faf2bc9654..101e48fb0901 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 000000000000..f26016adc203 --- /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 d89e5a5f630b..3f115580b315 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 2436d928bf70..138cd83d97c5 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; -} - -// --- fail_incomplete_interface_in_where.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 { + // 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: - require impls A where .X = {}; + extend require impls A; +} + +// --- fail_extend_require_enclosing_generic.carbon +library "[[@TEST_NAME]]"; + +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: + 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: interface @B { -// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// 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: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .A = -// CHECK:STDOUT: witness = () +// 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: !requires: +// 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: 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: specific @A(constants.%T) { +// CHECK:STDOUT: %T.loc3_13.1 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// 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 82ec701a0a4f..5d9a00b91be5 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 4cf75ce9d63e..041be17e7028 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 39cace550c30..377d24857c30 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 cb95f491b088..6b526ce3bbcd 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 119ed5d39bc0..99490ebdb91e 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);