diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 2e07c156bbd3..de182c1baf5a 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -131,30 +131,38 @@ auto VerifySameCanonicalImportIRInst(Context& context, SemIR::InstId prev_id, // - If `retry` is set, we process it again, because it didn't complete last // time, even though we have a constant value already. // 2. Resolve the instruction: (TryResolveInst/TryResolveTypedInst) +// - For a symbolic constant within a generic, find the generic itself. If it +// needs to be imported, return Retry() to import the generic before we +// import the constant. // - For instructions that can be forward declared, if we don't already have // a constant value from a previous attempt at resolution, start by making // a forward declared constant value to address circular references. // - Gather all input constants. // - Gathering constants directly adds unresolved values to work_stack_. // - If any need to be resolved (HasNewWork), return Retry(): this -// instruction needs two calls to complete. +// instruction needs another call to complete. // - If the constant value is already known because we have made a forward // declaration, pass it to Retry(). It will be passed to future attempts // to resolve this instruction so the earlier work can be found, and will // be made available for other instructions to use. -// - The second attempt to resolve this instruction must produce the same -// constant, because the value may have already been used by resolved -// instructions. +// - The subsequent attempt to resolve this instruction must produce the +// same constant, because the value may have already been used by +// resolved instructions. // - Build any necessary IR structures, and return the output constant. // 3. If resolve didn't return Retry(), pop the work. Otherwise, it needs to // remain, and may no longer be at the top of the stack; set `retry` on it so // we'll make sure to run it again later. // -// TryResolveInst/TryResolveTypedInst can complete in one call for a given -// instruction, but should always complete within two calls. However, due to the -// chance of a second call, it's important to reserve all expensive logic until -// it's been established that input constants are available; this in particular -// includes GetTypeIdForTypeConstant calls which do a hash table lookup. +// TryResolveInst can complete in one call for a given instruction, but should +// always complete within three calls: +// +// - TryResolveInst can retry once if the generic is not yet loaded. +// - TryResolveTypedInst can retry once if its inputs are not yet loaded. +// - The third call should succeed. +// +// Due to the chance of a second call to TryResolveTypedInst, it's important to +// reserve all expensive logic until it's been established that input constants +// are available. // // TODO: Fix class `extern` handling and merging, rewrite tests. // - check/testdata/class/cross_package_import.carbon @@ -210,20 +218,52 @@ class ImportRefResolver { return constant_id; } + // Wraps constant evaluation with logic to handle constants. + auto ResolveConstant(SemIR::ConstantId import_const_id) -> SemIR::ConstantId { + if (!import_const_id.is_valid()) { + return import_const_id; + } + + // For template constants, the corresponding instruction has the desired + // constant value. + if (!import_const_id.is_symbolic()) { + return Resolve(import_ir_.constant_values().GetInstId(import_const_id)); + } + + // For abstract symbolic constants, the corresponding instruction has the + // desired constant value. + const auto& symbolic_const = + import_ir_.constant_values().GetSymbolicConstant(import_const_id); + if (!symbolic_const.generic_id.is_valid()) { + return Resolve(import_ir_.constant_values().GetInstId(import_const_id)); + } + + // For a symbolic constant in a generic, pick the corresponding instruction + // out of the eval block for the generic and resolve its constant value. + const auto& generic = import_ir_.generics().Get(symbolic_const.generic_id); + auto block = generic.GetEvalBlock(symbolic_const.index.region()); + return Resolve( + import_ir_.inst_blocks().Get(block)[symbolic_const.index.index()]); + } + // Wraps constant evaluation with logic to handle types. auto ResolveType(SemIR::TypeId import_type_id) -> SemIR::TypeId { if (!import_type_id.is_valid()) { return import_type_id; } - auto import_type_inst_id = import_ir_.types().GetInstId(import_type_id); - CARBON_CHECK(import_type_inst_id.is_valid()); + auto import_type_const_id = + import_ir_.types().GetConstantId(import_type_id); + CARBON_CHECK(import_type_const_id.is_valid()); - if (import_type_inst_id.is_builtin()) { + if (auto import_type_inst_id = + import_ir_.constant_values().GetInstId(import_type_const_id); + import_type_inst_id.is_builtin()) { // Builtins don't require constant resolution; we can use them directly. return context_.GetBuiltinType(import_type_inst_id.builtin_inst_kind()); } else { - return context_.GetTypeIdForTypeConstant(Resolve(import_type_inst_id)); + return context_.GetTypeIdForTypeConstant( + ResolveConstant(import_type_id.AsConstantId())); } } @@ -847,6 +887,39 @@ class ImportRefResolver { // TODO: Error is returned when support is missing, but that should go away. auto TryResolveInst(SemIR::InstId inst_id, SemIR::ConstantId const_id) -> ResolveResult { + auto inst_const_id = import_ir_.constant_values().Get(inst_id); + if (!inst_const_id.is_valid() || !inst_const_id.is_symbolic() || + const_id.is_valid()) { + return TryResolveInstCanonical(inst_id, const_id); + } + + // Try to import the generic, and retry if it's not ready yet. Note that if + // this retries, we can require three passes to import an instruction. + const auto& symbolic_const = + import_ir_.constant_values().GetSymbolicConstant(inst_const_id); + auto initial_work = work_stack_.size(); + auto generic_const_id = GetLocalConstantId(symbolic_const.generic_id); + if (HasNewWork(initial_work)) { + return ResolveResult::Retry(); + } + + // Import the constant and rebuild the symbolic constant data. + auto result = TryResolveInstCanonical(inst_id, const_id); + if (result.const_id.is_valid()) { + result.const_id = context_.constant_values().AddSymbolicConstant( + {.inst_id = context_.constant_values().GetInstId(result.const_id), + .generic_id = GetLocalGenericId(generic_const_id), + .index = symbolic_const.index}); + } + return result; + } + + // Tries to resolve the InstId, returning a canonical constant when ready, or + // Invalid if more has been added to the stack. This is the same as + // TryResolveInst, except that it may resolve symbolic constants as canonical + // constants instead of as constants associated with a particular generic. + auto TryResolveInstCanonical(SemIR::InstId inst_id, + SemIR::ConstantId const_id) -> ResolveResult { if (inst_id.is_builtin()) { CARBON_CHECK(!const_id.is_valid()); // Constants for builtins can be directly copied. @@ -890,7 +963,7 @@ class ImportRefResolver { return TryResolveTypedInst(inst, inst_id); } case CARBON_KIND(SemIR::FunctionDecl inst): { - return TryResolveTypedInst(inst); + return TryResolveTypedInst(inst, const_id); } case CARBON_KIND(SemIR::FunctionType inst): { return TryResolveTypedInst(inst); @@ -1253,73 +1326,101 @@ class ImportRefResolver { return {.const_id = context_.constant_values().Get(inst_id)}; } - auto TryResolveTypedInst(SemIR::FunctionDecl inst) -> ResolveResult { - auto initial_work = work_stack_.size(); - - const auto& function = import_ir_.functions().Get(inst.function_id); - auto return_type_const_id = SemIR::ConstantId::Invalid; - if (function.return_storage_id.is_valid()) { - return_type_const_id = - GetLocalConstantId(function.GetDeclaredReturnType(import_ir_)); - } - auto parent_scope_id = GetLocalNameScopeId(function.parent_scope_id); - llvm::SmallVector implicit_param_const_ids = - GetLocalParamConstantIds(function.implicit_param_refs_id); - llvm::SmallVector param_const_ids = - GetLocalParamConstantIds(function.param_refs_id); - auto generic_data = GetLocalGenericData(function.generic_id); - - if (HasNewWork(initial_work)) { - return ResolveResult::Retry(); - } - - // Add the function declaration. + // Make a declaration of a function. This is done as a separate step from + // importing the function declaration in order to resolve cycles. + auto MakeFunctionDecl(const SemIR::Function& import_function) + -> std::pair { SemIR::FunctionDecl function_decl = { .type_id = SemIR::TypeId::Invalid, .function_id = SemIR::FunctionId::Invalid, .decl_block_id = SemIR::InstBlockId::Empty}; - auto import_ir_inst_id = AddImportIRInst(function.latest_decl_id()); - auto function_decl_id = context_.AddPlaceholderInstInNoBlock( - SemIR::LocIdAndInst(import_ir_inst_id, function_decl)); - // TODO: Implement import for generics. - auto generic_id = - MakeIncompleteGeneric(function_decl_id, function.generic_id); - SetGenericData(function.generic_id, generic_id, generic_data); + auto function_decl_id = + context_.AddPlaceholderInstInNoBlock(SemIR::LocIdAndInst( + AddImportIRInst(import_function.latest_decl_id()), function_decl)); - auto new_return_storage = SemIR::InstId::Invalid; - if (function.return_storage_id.is_valid()) { - // Recreate the return slot from scratch. - // TODO: Once we import function definitions, we'll need to make sure we - // use the same return storage variable in the declaration and definition. - new_return_storage = context_.AddInstInNoBlock( - AddImportIRInst(function.return_storage_id), - {.type_id = context_.GetTypeIdForTypeConstant(return_type_const_id), - .name_id = SemIR::NameId::ReturnSlot}); - } + // Start with an incomplete function. function_decl.function_id = context_.functions().Add( - {{.name_id = GetLocalNameId(function.name_id), - .parent_scope_id = parent_scope_id, - .generic_id = generic_id, - .first_param_node_id = Parse::NodeId::Invalid, - .last_param_node_id = Parse::NodeId::Invalid, - .implicit_param_refs_id = GetLocalParamRefsId( - function.implicit_param_refs_id, implicit_param_const_ids), - .param_refs_id = - GetLocalParamRefsId(function.param_refs_id, param_const_ids), - .decl_id = function_decl_id, - .definition_id = function.definition_id.is_valid() - ? function_decl_id - : SemIR::InstId::Invalid}, - {.return_storage_id = new_return_storage, - .is_extern = function.is_extern, - .builtin_function_kind = function.builtin_function_kind}}); + {GetIncompleteLocalEntityBase(function_decl_id, import_function), + {.return_storage_id = SemIR::InstId::Invalid, + .is_extern = import_function.is_extern, + .builtin_function_kind = import_function.builtin_function_kind}}); + // TODO: Import this or recompute it. auto specific_id = SemIR::SpecificId::Invalid; function_decl.type_id = context_.GetFunctionType(function_decl.function_id, specific_id); - // Write the function ID into the FunctionDecl. + + // Write the function ID and type into the FunctionDecl. context_.ReplaceInstBeforeConstantUse(function_decl_id, function_decl); - return {.const_id = context_.constant_values().Get(function_decl_id)}; + return {function_decl.function_id, + context_.constant_values().Get(function_decl_id)}; + } + + auto TryResolveTypedInst(SemIR::FunctionDecl inst, + SemIR::ConstantId function_const_id) + -> ResolveResult { + const auto& import_function = import_ir_.functions().Get(inst.function_id); + + SemIR::FunctionId function_id = SemIR::FunctionId::Invalid; + if (!function_const_id.is_valid()) { + // On the first pass, create a forward declaration of the interface. + std::tie(function_id, function_const_id) = + MakeFunctionDecl(import_function); + } else { + // On the second pass, compute the function ID from the constant value of + // the declaration. + auto function_const_inst = context_.insts().Get( + context_.constant_values().GetInstId(function_const_id)); + auto function_type = context_.types().GetAs( + function_const_inst.type_id()); + function_id = function_type.function_id; + } + + auto initial_work = work_stack_.size(); + + auto return_type_const_id = SemIR::ConstantId::Invalid; + if (import_function.return_storage_id.is_valid()) { + return_type_const_id = + GetLocalConstantId(import_function.GetDeclaredReturnType(import_ir_)); + } + auto parent_scope_id = GetLocalNameScopeId(import_function.parent_scope_id); + llvm::SmallVector implicit_param_const_ids = + GetLocalParamConstantIds(import_function.implicit_param_refs_id); + llvm::SmallVector param_const_ids = + GetLocalParamConstantIds(import_function.param_refs_id); + auto generic_data = GetLocalGenericData(import_function.generic_id); + + if (HasNewWork(initial_work)) { + return ResolveResult::Retry(function_const_id); + } + + // Add the function declaration. + auto& new_function = context_.functions().Get(function_id); + new_function.parent_scope_id = parent_scope_id; + new_function.implicit_param_refs_id = GetLocalParamRefsId( + import_function.implicit_param_refs_id, implicit_param_const_ids); + new_function.param_refs_id = + GetLocalParamRefsId(import_function.param_refs_id, param_const_ids); + SetGenericData(import_function.generic_id, new_function.generic_id, + generic_data); + + if (import_function.return_storage_id.is_valid()) { + // Recreate the return slot from scratch. + // TODO: Once we import function definitions, we'll need to make sure we + // use the same return storage variable in the declaration and definition. + new_function.return_storage_id = + context_.AddInstInNoBlock( + AddImportIRInst(import_function.return_storage_id), + {.type_id = + context_.GetTypeIdForTypeConstant(return_type_const_id), + .name_id = SemIR::NameId::ReturnSlot}); + } + + if (import_function.definition_id.is_valid()) { + new_function.definition_id = new_function.decl_id; + } + + return {.const_id = function_const_id}; } auto TryResolveTypedInst(SemIR::FunctionType inst) -> ResolveResult { diff --git a/toolchain/check/testdata/class/generic/import.carbon b/toolchain/check/testdata/class/generic/import.carbon index 30976b38b9bc..afd1eb3e4484 100644 --- a/toolchain/check/testdata/class/generic/import.carbon +++ b/toolchain/check/testdata/class/generic/import.carbon @@ -38,23 +38,13 @@ fn F() -> CompleteClass(i32) { library "use_foo"; import library "foo"; -fn Use() -> i32 { +fn UseMethod() -> i32 { var v: CompleteClass(i32) = F(); return v.F(); } -// --- fail_todo_use_foo.carbon - -library "fail_todo_use_foo"; -import library "foo"; - -fn Use() -> i32 { +fn UseField() -> i32 { var v: CompleteClass(i32) = F(); - // TODO: This should be accepted. - // CHECK:STDERR: fail_todo_use_foo.carbon:[[@LINE+4]]:10: ERROR: Cannot implicitly convert from `CompleteClass` to `CompleteClass`. - // CHECK:STDERR: return v.n; - // CHECK:STDERR: ^~~ - // CHECK:STDERR: return v.n; } @@ -387,8 +377,8 @@ class Class(U:! type) { // CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template] // CHECK:STDOUT: %.1: type = tuple_type () [template] // CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template] -// CHECK:STDOUT: %Use.type: type = fn_type @Use [template] -// CHECK:STDOUT: %Use: %Use.type = struct_value () [template] +// CHECK:STDOUT: %UseMethod.type: type = fn_type @UseMethod [template] +// CHECK:STDOUT: %UseMethod: %UseMethod.type = struct_value () [template] // CHECK:STDOUT: %CompleteClass.type: type = generic_class_type @CompleteClass [template] // CHECK:STDOUT: %CompleteClass.1: %CompleteClass.type = struct_value () [template] // CHECK:STDOUT: %.2: type = struct_type {.n: i32} [template] @@ -406,6 +396,8 @@ class Class(U:! type) { // CHECK:STDOUT: %.5: type = ptr_type %.2 [template] // CHECK:STDOUT: %F.type.4: type = fn_type @F.2 [template] // CHECK:STDOUT: %F.4: %F.type.4 = struct_value () [template] +// CHECK:STDOUT: %UseField.type: type = fn_type @UseField [template] +// CHECK:STDOUT: %UseField: %UseField.type = struct_value () [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -424,8 +416,8 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %import_ref.4: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32] // CHECK:STDOUT: %import_ref.5 = import_ref Main//foo, inst+18, unloaded -// CHECK:STDOUT: %import_ref.6 = import_ref Main//foo, inst+28, unloaded -// CHECK:STDOUT: %import_ref.7: %F.type.2 = import_ref Main//foo, inst+35, loaded [template = constants.%F.1] +// CHECK:STDOUT: %import_ref.6: @CompleteClass.%.1 (%.3) = import_ref Main//foo, inst+28, loaded [template = %.1] +// CHECK:STDOUT: %import_ref.7: @CompleteClass.%F.type (%F.type.2) = import_ref Main//foo, inst+35, loaded [symbolic = @CompleteClass.%F (constants.%F.1)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -434,15 +426,22 @@ class Class(U:! type) { // CHECK:STDOUT: .CompleteClass = imports.%import_ref.2 // CHECK:STDOUT: .F = imports.%import_ref.3 // CHECK:STDOUT: .Core = imports.%Core -// CHECK:STDOUT: .Use = %Use.decl +// CHECK:STDOUT: .UseMethod = %UseMethod.decl +// CHECK:STDOUT: .UseField = %UseField.decl // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %default.import = import -// CHECK:STDOUT: %Use.decl: %Use.type = fn_decl @Use [template = constants.%Use] { -// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32] -// CHECK:STDOUT: %.loc5_13.1: type = value_of_initializer %int.make_type_32 [template = i32] -// CHECK:STDOUT: %.loc5_13.2: type = converted %int.make_type_32, %.loc5_13.1 [template = i32] -// CHECK:STDOUT: @Use.%return: ref i32 = var +// CHECK:STDOUT: %UseMethod.decl: %UseMethod.type = fn_decl @UseMethod [template = constants.%UseMethod] { +// CHECK:STDOUT: %int.make_type_32.loc5: init type = call constants.%Int32() [template = i32] +// CHECK:STDOUT: %.loc5_19.1: type = value_of_initializer %int.make_type_32.loc5 [template = i32] +// CHECK:STDOUT: %.loc5_19.2: type = converted %int.make_type_32.loc5, %.loc5_19.1 [template = i32] +// CHECK:STDOUT: @UseMethod.%return: ref i32 = var +// CHECK:STDOUT: } +// CHECK:STDOUT: %UseField.decl: %UseField.type = fn_decl @UseField [template = constants.%UseField] { +// CHECK:STDOUT: %int.make_type_32.loc10: init type = call constants.%Int32() [template = i32] +// CHECK:STDOUT: %.loc10_18.1: type = value_of_initializer %int.make_type_32.loc10 [template = i32] +// CHECK:STDOUT: %.loc10_18.2: type = converted %int.make_type_32.loc10, %.loc10_18.1 [template = i32] +// CHECK:STDOUT: @UseField.%return: ref i32 = var // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -465,7 +464,7 @@ class Class(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32"; // CHECK:STDOUT: -// CHECK:STDOUT: fn @Use() -> i32 { +// CHECK:STDOUT: fn @UseMethod() -> i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %CompleteClass.ref: %CompleteClass.type = name_ref CompleteClass, imports.%import_ref.2 [template = constants.%CompleteClass.1] // CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32] @@ -481,7 +480,8 @@ class Class(U:! type) { // CHECK:STDOUT: %F.call.loc6: init %CompleteClass.3 = call %F.ref.loc6() to %.loc6_7 // CHECK:STDOUT: assign %v.var, %F.call.loc6 // CHECK:STDOUT: %v.ref: ref %CompleteClass.3 = name_ref v, %v -// CHECK:STDOUT: %F.ref.loc7: %F.type.2 = name_ref F, imports.%import_ref.7 [template = constants.%F.1] +// CHECK:STDOUT: %.loc7_11: %F.type.3 = specific_constant imports.%import_ref.7, @CompleteClass(i32) [template = constants.%F.3] +// CHECK:STDOUT: %F.ref.loc7: %F.type.3 = name_ref F, %.loc7_11 [template = constants.%F.3] // CHECK:STDOUT: %F.call.loc7: init i32 = call %F.ref.loc7() // CHECK:STDOUT: %.loc7_15.1: i32 = value_of_initializer %F.call.loc7 // CHECK:STDOUT: %.loc7_15.2: i32 = converted %F.call.loc7, %.loc7_15.1 @@ -496,145 +496,30 @@ class Class(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: fn @F.2() -> %CompleteClass.3; // CHECK:STDOUT: -// CHECK:STDOUT: specific @CompleteClass(constants.%T) { -// CHECK:STDOUT: %T => constants.%T -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @CompleteClass(@CompleteClass.%T) { -// CHECK:STDOUT: %T => constants.%T -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @CompleteClass(i32) { -// CHECK:STDOUT: %T => i32 -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %CompleteClass => constants.%CompleteClass.3 -// CHECK:STDOUT: %.1 => constants.%.4 -// CHECK:STDOUT: %F.type => constants.%F.type.3 -// CHECK:STDOUT: %F => constants.%F.3 -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_use_foo.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template] -// CHECK:STDOUT: %.1: type = tuple_type () [template] -// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template] -// CHECK:STDOUT: %Use.type: type = fn_type @Use [template] -// CHECK:STDOUT: %Use: %Use.type = struct_value () [template] -// CHECK:STDOUT: %CompleteClass.type: type = generic_class_type @CompleteClass [template] -// CHECK:STDOUT: %CompleteClass.1: %CompleteClass.type = struct_value () [template] -// CHECK:STDOUT: %.2: type = struct_type {.n: i32} [template] -// CHECK:STDOUT: %T: type = bind_symbolic_name T 0 [symbolic] -// CHECK:STDOUT: %CompleteClass.2: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic] -// CHECK:STDOUT: %F.type.1: type = fn_type @F.1 [template] -// CHECK:STDOUT: %F.1: %F.type.1 = struct_value () [template] -// CHECK:STDOUT: %F.type.2: type = fn_type @F.1, @CompleteClass(%T) [symbolic] -// CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [symbolic] -// CHECK:STDOUT: %.3: type = unbound_element_type %CompleteClass.2, i32 [symbolic] -// CHECK:STDOUT: %CompleteClass.3: type = class_type @CompleteClass, @CompleteClass(i32) [template] -// CHECK:STDOUT: %.4: type = unbound_element_type %CompleteClass.3, i32 [template] -// CHECK:STDOUT: %F.type.3: type = fn_type @F.1, @CompleteClass(i32) [template] -// CHECK:STDOUT: %F.3: %F.type.3 = struct_value () [template] -// CHECK:STDOUT: %.5: type = ptr_type %.2 [template] -// CHECK:STDOUT: %F.type.4: type = fn_type @F.2 [template] -// CHECK:STDOUT: %F.4: %F.type.4 = struct_value () [template] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %import_ref.1 = import_ref Main//foo, inst+6, unloaded -// CHECK:STDOUT: %import_ref.2: %CompleteClass.type = import_ref Main//foo, inst+14, loaded [template = constants.%CompleteClass.1] -// CHECK:STDOUT: %import_ref.3: %F.type.4 = import_ref Main//foo, inst+55, loaded [template = constants.%F.4] -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [template] { -// CHECK:STDOUT: .Int32 = %import_ref.4 -// CHECK:STDOUT: import Core//prelude -// CHECK:STDOUT: import Core//prelude/operators -// CHECK:STDOUT: import Core//prelude/types -// CHECK:STDOUT: import Core//prelude/operators/arithmetic -// CHECK:STDOUT: import Core//prelude/operators/bitwise -// CHECK:STDOUT: import Core//prelude/operators/comparison -// CHECK:STDOUT: import Core//prelude/types/bool -// CHECK:STDOUT: } -// CHECK:STDOUT: %import_ref.4: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32] -// CHECK:STDOUT: %import_ref.5 = import_ref Main//foo, inst+18, unloaded -// CHECK:STDOUT: %import_ref.6: %.3 = import_ref Main//foo, inst+28, loaded [template = %.1] -// CHECK:STDOUT: %import_ref.7 = import_ref Main//foo, inst+35, unloaded -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [template] { -// CHECK:STDOUT: .Class = imports.%import_ref.1 -// CHECK:STDOUT: .CompleteClass = imports.%import_ref.2 -// CHECK:STDOUT: .F = imports.%import_ref.3 -// CHECK:STDOUT: .Core = imports.%Core -// CHECK:STDOUT: .Use = %Use.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %default.import = import -// CHECK:STDOUT: %Use.decl: %Use.type = fn_decl @Use [template = constants.%Use] { -// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32] -// CHECK:STDOUT: %.loc5_13.1: type = value_of_initializer %int.make_type_32 [template = i32] -// CHECK:STDOUT: %.loc5_13.2: type = converted %int.make_type_32, %.loc5_13.1 [template = i32] -// CHECK:STDOUT: @Use.%return: ref i32 = var -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic class @CompleteClass(constants.%T: type) { -// CHECK:STDOUT: %T: type = bind_symbolic_name T 0 [symbolic = %T (constants.%T)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic = %CompleteClass (constants.%CompleteClass.2)] -// CHECK:STDOUT: %.1: type = unbound_element_type @CompleteClass.%CompleteClass (%CompleteClass.2), i32 [symbolic = %.1 (constants.%.3)] -// CHECK:STDOUT: %F.type: type = fn_type @F.1, @CompleteClass(%T) [symbolic = %F.type (constants.%F.type.2)] -// CHECK:STDOUT: %F: @CompleteClass.%F.type (%F.type.2) = struct_value () [symbolic = %F (constants.%F.2)] -// CHECK:STDOUT: -// CHECK:STDOUT: class { -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%import_ref.5 -// CHECK:STDOUT: .n = imports.%import_ref.6 -// CHECK:STDOUT: .F = imports.%import_ref.7 -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32"; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @Use() -> i32 { +// CHECK:STDOUT: fn @UseField() -> i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %CompleteClass.ref: %CompleteClass.type = name_ref CompleteClass, imports.%import_ref.2 [template = constants.%CompleteClass.1] // CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32] -// CHECK:STDOUT: %.loc6_23.1: type = value_of_initializer %int.make_type_32 [template = i32] -// CHECK:STDOUT: %.loc6_23.2: type = converted %int.make_type_32, %.loc6_23.1 [template = i32] -// CHECK:STDOUT: %.loc6_23.3: init type = call %CompleteClass.ref(%.loc6_23.2) [template = constants.%CompleteClass.3] -// CHECK:STDOUT: %.loc6_27.1: type = value_of_initializer %.loc6_23.3 [template = constants.%CompleteClass.3] -// CHECK:STDOUT: %.loc6_27.2: type = converted %.loc6_23.3, %.loc6_27.1 [template = constants.%CompleteClass.3] +// CHECK:STDOUT: %.loc11_23.1: type = value_of_initializer %int.make_type_32 [template = i32] +// CHECK:STDOUT: %.loc11_23.2: type = converted %int.make_type_32, %.loc11_23.1 [template = i32] +// CHECK:STDOUT: %.loc11_23.3: init type = call %CompleteClass.ref(%.loc11_23.2) [template = constants.%CompleteClass.3] +// CHECK:STDOUT: %.loc11_27.1: type = value_of_initializer %.loc11_23.3 [template = constants.%CompleteClass.3] +// CHECK:STDOUT: %.loc11_27.2: type = converted %.loc11_23.3, %.loc11_27.1 [template = constants.%CompleteClass.3] // CHECK:STDOUT: %v.var: ref %CompleteClass.3 = var v // CHECK:STDOUT: %v: ref %CompleteClass.3 = bind_name v, %v.var // CHECK:STDOUT: %F.ref: %F.type.4 = name_ref F, imports.%import_ref.3 [template = constants.%F.4] -// CHECK:STDOUT: %.loc6_7: ref %CompleteClass.3 = splice_block %v.var {} -// CHECK:STDOUT: %F.call: init %CompleteClass.3 = call %F.ref() to %.loc6_7 +// CHECK:STDOUT: %.loc11_7: ref %CompleteClass.3 = splice_block %v.var {} +// CHECK:STDOUT: %F.call: init %CompleteClass.3 = call %F.ref() to %.loc11_7 // CHECK:STDOUT: assign %v.var, %F.call // CHECK:STDOUT: %v.ref: ref %CompleteClass.3 = name_ref v, %v -// CHECK:STDOUT: %n.ref: %.3 = name_ref n, imports.%import_ref.6 [template = imports.%.1] -// CHECK:STDOUT: %.loc12: i32 = class_element_access , element0 [template = ] -// CHECK:STDOUT: return +// CHECK:STDOUT: %n.ref: %.4 = name_ref n, imports.%import_ref.6 [template = imports.%.1] +// CHECK:STDOUT: %.loc12_11.1: ref i32 = class_element_access %v.ref, element0 +// CHECK:STDOUT: %.loc12_11.2: i32 = bind_value %.loc12_11.1 +// CHECK:STDOUT: return %.loc12_11.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @F.1(constants.%T: type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn() -> i32; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F.2() -> %CompleteClass.3; -// CHECK:STDOUT: // CHECK:STDOUT: specific @CompleteClass(constants.%T) { // CHECK:STDOUT: %T => constants.%T -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %CompleteClass => constants.%CompleteClass.2 -// CHECK:STDOUT: %.1 => constants.%.3 -// CHECK:STDOUT: %F.type => constants.%F.type.2 -// CHECK:STDOUT: %F => constants.%F.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @CompleteClass(@CompleteClass.%T) { @@ -651,6 +536,8 @@ class Class(U:! type) { // CHECK:STDOUT: %F => constants.%F.3 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @F.1(i32) {} +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_generic_arg_mismatch.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -675,9 +562,9 @@ class Class(U:! type) { // CHECK:STDOUT: %F.type.3: type = fn_type @F.1, @CompleteClass(%.4) [template] // CHECK:STDOUT: %F.3: %F.type.3 = struct_value () [template] // CHECK:STDOUT: %.6: type = ptr_type %.2 [template] -// CHECK:STDOUT: %CompleteClass.4: type = class_type @CompleteClass, @CompleteClass(i32) [template] // CHECK:STDOUT: %F.type.4: type = fn_type @F.2 [template] // CHECK:STDOUT: %F.4: %F.type.4 = struct_value () [template] +// CHECK:STDOUT: %CompleteClass.4: type = class_type @CompleteClass, @CompleteClass(i32) [template] // CHECK:STDOUT: %.7: type = unbound_element_type %CompleteClass.4, i32 [template] // CHECK:STDOUT: %F.type.5: type = fn_type @F.1, @CompleteClass(i32) [template] // CHECK:STDOUT: %F.5: %F.type.5 = struct_value () [template] diff --git a/toolchain/check/testdata/class/import.carbon b/toolchain/check/testdata/class/import.carbon index 8896ee5dce75..4b4c2936e88b 100644 --- a/toolchain/check/testdata/class/import.carbon +++ b/toolchain/check/testdata/class/import.carbon @@ -162,12 +162,12 @@ fn Run() { // CHECK:STDOUT: %.8: i32 = int_literal 2 [template] // CHECK:STDOUT: %ForwardDeclared.1: type = class_type @ForwardDeclared.1 [template] // CHECK:STDOUT: %struct.3: %ForwardDeclared.1 = struct_value () [template] -// CHECK:STDOUT: %ForwardDeclared.2: type = class_type @ForwardDeclared.2 [template] // CHECK:STDOUT: %F.type: type = fn_type @F [template] // CHECK:STDOUT: %F: %F.type = struct_value () [template] -// CHECK:STDOUT: %.9: type = ptr_type %ForwardDeclared.1 [template] +// CHECK:STDOUT: %ForwardDeclared.2: type = class_type @ForwardDeclared.2 [template] // CHECK:STDOUT: %G.type: type = fn_type @G [template] // CHECK:STDOUT: %G: %G.type = struct_value () [template] +// CHECK:STDOUT: %.9: type = ptr_type %ForwardDeclared.1 [template] // CHECK:STDOUT: %Incomplete: type = class_type @Incomplete [template] // CHECK:STDOUT: %.10: type = ptr_type %Incomplete [template] // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/declaration/import.carbon b/toolchain/check/testdata/function/declaration/import.carbon index e604e431f4a5..a83174da6636 100644 --- a/toolchain/check/testdata/function/declaration/import.carbon +++ b/toolchain/check/testdata/function/declaration/import.carbon @@ -559,9 +559,9 @@ import library "extern_api"; // CHECK:STDOUT: %B: %B.type = struct_value () [template] // CHECK:STDOUT: %.2: i32 = int_literal 1 [template] // CHECK:STDOUT: %.3: type = struct_type {.c: i32} [template] -// CHECK:STDOUT: %.4: type = tuple_type (i32) [template] // CHECK:STDOUT: %C.type: type = fn_type @C [template] // CHECK:STDOUT: %C: %C.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = tuple_type (i32) [template] // CHECK:STDOUT: %tuple: %.4 = tuple_value (%.2) [template] // CHECK:STDOUT: %D.type: type = fn_type @D [template] // CHECK:STDOUT: %D: %D.type = struct_value () [template] @@ -989,9 +989,9 @@ import library "extern_api"; // CHECK:STDOUT: %B: %B.type = struct_value () [template] // CHECK:STDOUT: %.2: i32 = int_literal 1 [template] // CHECK:STDOUT: %.3: type = struct_type {.c: i32} [template] -// CHECK:STDOUT: %.4: type = tuple_type (i32) [template] // CHECK:STDOUT: %C.type: type = fn_type @C [template] // CHECK:STDOUT: %C: %C.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = tuple_type (i32) [template] // CHECK:STDOUT: %tuple: %.4 = tuple_value (%.2) [template] // CHECK:STDOUT: %D.type: type = fn_type @D [template] // CHECK:STDOUT: %D: %D.type = struct_value () [template] @@ -1118,9 +1118,9 @@ import library "extern_api"; // CHECK:STDOUT: %B: %B.type = struct_value () [template] // CHECK:STDOUT: %.2: i32 = int_literal 1 [template] // CHECK:STDOUT: %.3: type = struct_type {.c: i32} [template] -// CHECK:STDOUT: %.4: type = tuple_type (i32) [template] // CHECK:STDOUT: %C.type: type = fn_type @C [template] // CHECK:STDOUT: %C: %C.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = tuple_type (i32) [template] // CHECK:STDOUT: %tuple: %.4 = tuple_value (%.2) [template] // CHECK:STDOUT: %D.type: type = fn_type @D [template] // CHECK:STDOUT: %D: %D.type = struct_value () [template] diff --git a/toolchain/check/testdata/function/declaration/no_prelude/fail_import_incomplete_return.carbon b/toolchain/check/testdata/function/declaration/no_prelude/fail_import_incomplete_return.carbon index 0209183ce898..b55884ab7b38 100644 --- a/toolchain/check/testdata/function/declaration/no_prelude/fail_import_incomplete_return.carbon +++ b/toolchain/check/testdata/function/declaration/no_prelude/fail_import_incomplete_return.carbon @@ -172,15 +172,15 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: %CallFAndGIncomplete.type: type = fn_type @CallFAndGIncomplete [template] // CHECK:STDOUT: %.1: type = tuple_type () [template] // CHECK:STDOUT: %CallFAndGIncomplete: %CallFAndGIncomplete.type = struct_value () [template] -// CHECK:STDOUT: %C: type = class_type @C [template] // CHECK:STDOUT: %ReturnCUnused.type: type = fn_type @ReturnCUnused [template] // CHECK:STDOUT: %ReturnCUnused: %ReturnCUnused.type = struct_value () [template] +// CHECK:STDOUT: %C: type = class_type @C [template] // CHECK:STDOUT: %ReturnCUsed.type: type = fn_type @ReturnCUsed [template] // CHECK:STDOUT: %ReturnCUsed: %ReturnCUsed.type = struct_value () [template] -// CHECK:STDOUT: %D: type = class_type @D [template] -// CHECK:STDOUT: %.2: type = struct_type {} [template] // CHECK:STDOUT: %ReturnDUnused.type: type = fn_type @ReturnDUnused [template] // CHECK:STDOUT: %ReturnDUnused: %ReturnDUnused.type = struct_value () [template] +// CHECK:STDOUT: %D: type = class_type @D [template] +// CHECK:STDOUT: %.2: type = struct_type {} [template] // CHECK:STDOUT: %.3: type = ptr_type %.2 [template] // CHECK:STDOUT: %ReturnDUsed.type: type = fn_type @ReturnDUsed [template] // CHECK:STDOUT: %ReturnDUsed: %ReturnDUsed.type = struct_value () [template] diff --git a/toolchain/check/testdata/function/definition/import.carbon b/toolchain/check/testdata/function/definition/import.carbon index 7adaffb91a32..a3abeb7761aa 100644 --- a/toolchain/check/testdata/function/definition/import.carbon +++ b/toolchain/check/testdata/function/definition/import.carbon @@ -235,9 +235,9 @@ fn D() {} // CHECK:STDOUT: %B: %B.type = struct_value () [template] // CHECK:STDOUT: %.2: i32 = int_literal 1 [template] // CHECK:STDOUT: %.3: type = struct_type {.c: i32} [template] -// CHECK:STDOUT: %.4: type = tuple_type (i32) [template] // CHECK:STDOUT: %C.type: type = fn_type @C [template] // CHECK:STDOUT: %C: %C.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = tuple_type (i32) [template] // CHECK:STDOUT: %tuple: %.4 = tuple_value (%.2) [template] // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/no_prelude/generic_import.carbon b/toolchain/check/testdata/interface/no_prelude/generic_import.carbon index 9fd2cdd0f2ea..3eb3de03f87b 100644 --- a/toolchain/check/testdata/interface/no_prelude/generic_import.carbon +++ b/toolchain/check/testdata/interface/no_prelude/generic_import.carbon @@ -118,7 +118,7 @@ impl C as AddWith(C) { // CHECK:STDOUT: %import_ref.2 = import_ref Main//a, inst+12, unloaded // CHECK:STDOUT: %import_ref.3 = import_ref Main//a, inst+10, unloaded // CHECK:STDOUT: %import_ref.4 = import_ref Main//a, inst+16, unloaded -// CHECK:STDOUT: %import_ref.5: %F.type.2 = import_ref Main//a, inst+12, loaded [template = constants.%F.1] +// CHECK:STDOUT: %import_ref.5: @AddWith.%F.type (%F.type.2) = import_ref Main//a, inst+12, loaded [symbolic = @AddWith.%F (constants.%F.1)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/namespace/merging_with_indirections.carbon b/toolchain/check/testdata/namespace/merging_with_indirections.carbon index 543ac104f145..106e7a312e52 100644 --- a/toolchain/check/testdata/namespace/merging_with_indirections.carbon +++ b/toolchain/check/testdata/namespace/merging_with_indirections.carbon @@ -153,10 +153,10 @@ fn Run() { // CHECK:STDOUT: %Run.type: type = fn_type @Run [template] // CHECK:STDOUT: %.1: type = tuple_type () [template] // CHECK:STDOUT: %Run: %Run.type = struct_value () [template] -// CHECK:STDOUT: %A: type = class_type @A [template] -// CHECK:STDOUT: %.2: type = struct_type {} [template] // CHECK:STDOUT: %F.type: type = fn_type @F [template] // CHECK:STDOUT: %F: %F.type = struct_value () [template] +// CHECK:STDOUT: %A: type = class_type @A [template] +// CHECK:STDOUT: %.2: type = struct_type {} [template] // CHECK:STDOUT: %.3: type = ptr_type %.2 [template] // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/operators/overloaded/add.carbon b/toolchain/check/testdata/operators/overloaded/add.carbon index 4f672f53accd..071b184ab640 100644 --- a/toolchain/check/testdata/operators/overloaded/add.carbon +++ b/toolchain/check/testdata/operators/overloaded/add.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/bit_and.carbon b/toolchain/check/testdata/operators/overloaded/bit_and.carbon index f24cb300430b..22d3a743dc73 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_and.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_and.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/bit_or.carbon b/toolchain/check/testdata/operators/overloaded/bit_or.carbon index b0272dbe820f..df1721eaa301 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_or.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_or.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/bit_xor.carbon b/toolchain/check/testdata/operators/overloaded/bit_xor.carbon index 10a5918591ef..5dbd773d1133 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_xor.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_xor.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/dec.carbon b/toolchain/check/testdata/operators/overloaded/dec.carbon index ae6fbe9ccbe8..e76ae309987f 100644 --- a/toolchain/check/testdata/operators/overloaded/dec.carbon +++ b/toolchain/check/testdata/operators/overloaded/dec.carbon @@ -34,9 +34,9 @@ fn TestOp() { // CHECK:STDOUT: %Op.type.1: type = fn_type @Op.1 [template] // CHECK:STDOUT: %.4: type = tuple_type () [template] // CHECK:STDOUT: %Op.1: %Op.type.1 = struct_value () [template] -// CHECK:STDOUT: %.5: type = ptr_type %Self [symbolic] // CHECK:STDOUT: %Op.type.2: type = fn_type @Op.2 [template] // CHECK:STDOUT: %Op.2: %Op.type.2 = struct_value () [template] +// CHECK:STDOUT: %.5: type = ptr_type %Self [symbolic] // CHECK:STDOUT: %.6: = interface_witness (%Op.1) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/div.carbon b/toolchain/check/testdata/operators/overloaded/div.carbon index c121c27c4688..4a279f6a2274 100644 --- a/toolchain/check/testdata/operators/overloaded/div.carbon +++ b/toolchain/check/testdata/operators/overloaded/div.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon b/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon index a8634cc25aec..97c47cf84af5 100644 --- a/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon +++ b/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon @@ -51,17 +51,17 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: %Op.type.1: type = fn_type @Op.1 [template] // CHECK:STDOUT: %.4: type = tuple_type () [template] // CHECK:STDOUT: %Op.1: %Op.type.1 = struct_value () [template] -// CHECK:STDOUT: %.5: type = ptr_type %Self.1 [symbolic] // CHECK:STDOUT: %Op.type.2: type = fn_type @Op.2 [template] // CHECK:STDOUT: %Op.2: %Op.type.2 = struct_value () [template] +// CHECK:STDOUT: %.5: type = ptr_type %Self.1 [symbolic] // CHECK:STDOUT: %.6: = interface_witness (%Op.1) [template] // CHECK:STDOUT: %.7: type = interface_type @AddAssign [template] // CHECK:STDOUT: %Self.2: %.7 = bind_symbolic_name Self 0 [symbolic] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestIncNonRef.type: type = fn_type @TestIncNonRef [template] // CHECK:STDOUT: %TestIncNonRef: %TestIncNonRef.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon b/toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon index 57bb9d4eae84..a1db9fe4b42a 100644 --- a/toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon +++ b/toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon @@ -69,16 +69,16 @@ fn TestRef(b: C) { // CHECK:STDOUT: %struct: %C = struct_value () [template] // CHECK:STDOUT: %.10: type = interface_type @AddAssign [template] // CHECK:STDOUT: %Self.3: %.10 = bind_symbolic_name Self 0 [symbolic] -// CHECK:STDOUT: %.11: type = ptr_type %Self.3 [symbolic] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] +// CHECK:STDOUT: %.11: type = ptr_type %Self.3 [symbolic] // CHECK:STDOUT: %.12: type = assoc_entity_type @AddAssign, %Op.type.3 [template] // CHECK:STDOUT: %.13: %.12 = assoc_entity element0, imports.%import_ref.15 [template] // CHECK:STDOUT: %.14: type = interface_type @Inc [template] // CHECK:STDOUT: %Self.4: %.14 = bind_symbolic_name Self 0 [symbolic] -// CHECK:STDOUT: %.15: type = ptr_type %Self.4 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.15: type = ptr_type %Self.4 [symbolic] // CHECK:STDOUT: %.16: type = assoc_entity_type @Inc, %Op.type.4 [template] // CHECK:STDOUT: %.17: %.16 = assoc_entity element0, imports.%import_ref.20 [template] // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon b/toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon index a2298d865e9e..0c406ca515ef 100644 --- a/toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon +++ b/toolchain/check/testdata/operators/overloaded/fail_no_impl_for_arg.carbon @@ -61,9 +61,9 @@ fn TestAssign(b: D) { // CHECK:STDOUT: %.6: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.7: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.7: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.8: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %Test.type: type = fn_type @Test [template] // CHECK:STDOUT: %Test: %Test.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/inc.carbon b/toolchain/check/testdata/operators/overloaded/inc.carbon index 1caaf7119230..95ac2945ccb5 100644 --- a/toolchain/check/testdata/operators/overloaded/inc.carbon +++ b/toolchain/check/testdata/operators/overloaded/inc.carbon @@ -34,9 +34,9 @@ fn TestOp() { // CHECK:STDOUT: %Op.type.1: type = fn_type @Op.1 [template] // CHECK:STDOUT: %.4: type = tuple_type () [template] // CHECK:STDOUT: %Op.1: %Op.type.1 = struct_value () [template] -// CHECK:STDOUT: %.5: type = ptr_type %Self [symbolic] // CHECK:STDOUT: %Op.type.2: type = fn_type @Op.2 [template] // CHECK:STDOUT: %Op.2: %Op.type.2 = struct_value () [template] +// CHECK:STDOUT: %.5: type = ptr_type %Self [symbolic] // CHECK:STDOUT: %.6: = interface_witness (%Op.1) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/left_shift.carbon b/toolchain/check/testdata/operators/overloaded/left_shift.carbon index 7fcec7dff794..dcc1eabec122 100644 --- a/toolchain/check/testdata/operators/overloaded/left_shift.carbon +++ b/toolchain/check/testdata/operators/overloaded/left_shift.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/mod.carbon b/toolchain/check/testdata/operators/overloaded/mod.carbon index b399cbc84435..a61037c553a2 100644 --- a/toolchain/check/testdata/operators/overloaded/mod.carbon +++ b/toolchain/check/testdata/operators/overloaded/mod.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/mul.carbon b/toolchain/check/testdata/operators/overloaded/mul.carbon index 0cf4d35d18ab..2445bb3d8e55 100644 --- a/toolchain/check/testdata/operators/overloaded/mul.carbon +++ b/toolchain/check/testdata/operators/overloaded/mul.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/right_shift.carbon b/toolchain/check/testdata/operators/overloaded/right_shift.carbon index 5a9d0fab1af9..db0f61163f52 100644 --- a/toolchain/check/testdata/operators/overloaded/right_shift.carbon +++ b/toolchain/check/testdata/operators/overloaded/right_shift.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/operators/overloaded/sub.carbon b/toolchain/check/testdata/operators/overloaded/sub.carbon index 428224cd4a20..8559b85d65d9 100644 --- a/toolchain/check/testdata/operators/overloaded/sub.carbon +++ b/toolchain/check/testdata/operators/overloaded/sub.carbon @@ -51,9 +51,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %.7: type = ptr_type %C [template] // CHECK:STDOUT: %Op.type.3: type = fn_type @Op.3 [template] // CHECK:STDOUT: %Op.3: %Op.type.3 = struct_value () [template] -// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %Op.type.4: type = fn_type @Op.4 [template] // CHECK:STDOUT: %Op.4: %Op.type.4 = struct_value () [template] +// CHECK:STDOUT: %.8: type = ptr_type %Self.2 [symbolic] // CHECK:STDOUT: %.9: = interface_witness (%Op.3) [template] // CHECK:STDOUT: %TestOp.type: type = fn_type @TestOp [template] // CHECK:STDOUT: %TestOp: %TestOp.type = struct_value () [template] diff --git a/toolchain/check/testdata/struct/import.carbon b/toolchain/check/testdata/struct/import.carbon index 86ea05b7f85d..0f39e25334ee 100644 --- a/toolchain/check/testdata/struct/import.carbon +++ b/toolchain/check/testdata/struct/import.carbon @@ -380,10 +380,10 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %.5: i32 = int_literal 2 [template] // CHECK:STDOUT: %.6: type = struct_type {.c: i32, .d: i32} [template] // CHECK:STDOUT: %.7: type = ptr_type %.3 [template] -// CHECK:STDOUT: %struct: %.3 = struct_value (%.4, %.5) [template] -// CHECK:STDOUT: %C.3: type = class_type @C, @C(%struct) [template] // CHECK:STDOUT: %F.type: type = fn_type @F [template] // CHECK:STDOUT: %F: %F.type = struct_value () [template] +// CHECK:STDOUT: %struct: %.3 = struct_value (%.4, %.5) [template] +// CHECK:STDOUT: %C.3: type = class_type @C, @C(%struct) [template] // CHECK:STDOUT: %.8: type = ptr_type %.2 [template] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -475,12 +475,12 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %struct.1: %.3 = struct_value (%.4, %.5) [template] // CHECK:STDOUT: %C.3: type = class_type @C, @C(%struct.1) [template] // CHECK:STDOUT: %.7: type = ptr_type %.2 [template] +// CHECK:STDOUT: %F.type: type = fn_type @F [template] +// CHECK:STDOUT: %F: %F.type = struct_value () [template] // CHECK:STDOUT: %.8: i32 = int_literal 2 [template] // CHECK:STDOUT: %.9: i32 = int_literal 1 [template] // CHECK:STDOUT: %struct.2: %.3 = struct_value (%.9, %.8) [template] // CHECK:STDOUT: %C.4: type = class_type @C, @C(%struct.2) [template] -// CHECK:STDOUT: %F.type: type = fn_type @F [template] -// CHECK:STDOUT: %F: %F.type = struct_value () [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { diff --git a/toolchain/check/testdata/tuples/import.carbon b/toolchain/check/testdata/tuples/import.carbon index ce160f8c773b..db4aa3851701 100644 --- a/toolchain/check/testdata/tuples/import.carbon +++ b/toolchain/check/testdata/tuples/import.carbon @@ -420,10 +420,10 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %.6: i32 = int_literal 3 [template] // CHECK:STDOUT: %.7: type = tuple_type (i32, i32, i32) [template] // CHECK:STDOUT: %.8: type = ptr_type %.3 [template] -// CHECK:STDOUT: %tuple: %.3 = tuple_value (%.4, %.5) [template] -// CHECK:STDOUT: %C.3: type = class_type @C, @C(%tuple) [template] // CHECK:STDOUT: %F.type: type = fn_type @F [template] // CHECK:STDOUT: %F: %F.type = struct_value () [template] +// CHECK:STDOUT: %tuple: %.3 = tuple_value (%.4, %.5) [template] +// CHECK:STDOUT: %C.3: type = class_type @C, @C(%tuple) [template] // CHECK:STDOUT: %.9: type = ptr_type %.2 [template] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -516,12 +516,12 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %tuple.1: %.3 = tuple_value (%.4, %.5) [template] // CHECK:STDOUT: %C.3: type = class_type @C, @C(%tuple.1) [template] // CHECK:STDOUT: %.7: type = ptr_type %.2 [template] +// CHECK:STDOUT: %F.type: type = fn_type @F [template] +// CHECK:STDOUT: %F: %F.type = struct_value () [template] // CHECK:STDOUT: %.8: i32 = int_literal 2 [template] // CHECK:STDOUT: %.9: i32 = int_literal 1 [template] // CHECK:STDOUT: %tuple.2: %.3 = tuple_value (%.9, %.8) [template] // CHECK:STDOUT: %C.4: type = class_type @C, @C(%tuple.2) [template] -// CHECK:STDOUT: %F.type: type = fn_type @F [template] -// CHECK:STDOUT: %F: %F.type = struct_value () [template] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports {